LLVM 23.0.0git
AttributorAttributes.cpp
Go to the documentation of this file.
1//===- AttributorAttributes.cpp - Attributes for Attributor deduction -----===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// See the Attributor.h file comment and the class descriptions in that file for
10// more information.
11//
12//===----------------------------------------------------------------------===//
13
15
16#include "llvm/ADT/APInt.h"
17#include "llvm/ADT/ArrayRef.h"
19#include "llvm/ADT/MapVector.h"
21#include "llvm/ADT/STLExtras.h"
23#include "llvm/ADT/SetVector.h"
26#include "llvm/ADT/Statistic.h"
39#include "llvm/IR/Argument.h"
40#include "llvm/IR/Assumptions.h"
41#include "llvm/IR/Attributes.h"
42#include "llvm/IR/BasicBlock.h"
43#include "llvm/IR/Constant.h"
44#include "llvm/IR/Constants.h"
45#include "llvm/IR/DataLayout.h"
47#include "llvm/IR/GlobalValue.h"
48#include "llvm/IR/IRBuilder.h"
49#include "llvm/IR/InlineAsm.h"
50#include "llvm/IR/InstrTypes.h"
51#include "llvm/IR/Instruction.h"
54#include "llvm/IR/IntrinsicsAMDGPU.h"
55#include "llvm/IR/IntrinsicsNVPTX.h"
56#include "llvm/IR/LLVMContext.h"
57#include "llvm/IR/MDBuilder.h"
58#include "llvm/IR/NoFolder.h"
59#include "llvm/IR/Value.h"
60#include "llvm/IR/ValueHandle.h"
75#include <cassert>
76#include <numeric>
77#include <optional>
78#include <string>
79
80using namespace llvm;
81
82#define DEBUG_TYPE "attributor"
83
85 "attributor-manifest-internal", cl::Hidden,
86 cl::desc("Manifest Attributor internal string attributes."),
87 cl::init(false));
88
89static cl::opt<int> MaxHeapToStackSize("max-heap-to-stack-size", cl::init(128),
91
92template <>
94
96
98 "attributor-max-potential-values", cl::Hidden,
99 cl::desc("Maximum number of potential values to be "
100 "tracked for each position."),
102 cl::init(7));
103
105 "attributor-max-potential-values-iterations", cl::Hidden,
106 cl::desc(
107 "Maximum number of iterations we keep dismantling potential values."),
108 cl::init(64));
109
110STATISTIC(NumAAs, "Number of abstract attributes created");
111STATISTIC(NumIndirectCallsPromoted, "Number of indirect calls promoted");
112
113// Some helper macros to deal with statistics tracking.
114//
115// Usage:
116// For simple IR attribute tracking overload trackStatistics in the abstract
117// attribute and choose the right STATS_DECLTRACK_********* macro,
118// e.g.,:
119// void trackStatistics() const override {
120// STATS_DECLTRACK_ARG_ATTR(returned)
121// }
122// If there is a single "increment" side one can use the macro
123// STATS_DECLTRACK with a custom message. If there are multiple increment
124// sides, STATS_DECL and STATS_TRACK can also be used separately.
125//
126#define BUILD_STAT_MSG_IR_ATTR(TYPE, NAME) \
127 ("Number of " #TYPE " marked '" #NAME "'")
128#define BUILD_STAT_NAME(NAME, TYPE) NumIR##TYPE##_##NAME
129#define STATS_DECL_(NAME, MSG) STATISTIC(NAME, MSG);
130#define STATS_DECL(NAME, TYPE, MSG) \
131 STATS_DECL_(BUILD_STAT_NAME(NAME, TYPE), MSG);
132#define STATS_TRACK(NAME, TYPE) ++(BUILD_STAT_NAME(NAME, TYPE));
133#define STATS_DECLTRACK(NAME, TYPE, MSG) \
134 {STATS_DECL(NAME, TYPE, MSG) STATS_TRACK(NAME, TYPE)}
135#define STATS_DECLTRACK_ARG_ATTR(NAME) \
136 STATS_DECLTRACK(NAME, Arguments, BUILD_STAT_MSG_IR_ATTR(arguments, NAME))
137#define STATS_DECLTRACK_CSARG_ATTR(NAME) \
138 STATS_DECLTRACK(NAME, CSArguments, \
139 BUILD_STAT_MSG_IR_ATTR(call site arguments, NAME))
140#define STATS_DECLTRACK_FN_ATTR(NAME) \
141 STATS_DECLTRACK(NAME, Function, BUILD_STAT_MSG_IR_ATTR(functions, NAME))
142#define STATS_DECLTRACK_CS_ATTR(NAME) \
143 STATS_DECLTRACK(NAME, CS, BUILD_STAT_MSG_IR_ATTR(call site, NAME))
144#define STATS_DECLTRACK_FNRET_ATTR(NAME) \
145 STATS_DECLTRACK(NAME, FunctionReturn, \
146 BUILD_STAT_MSG_IR_ATTR(function returns, NAME))
147#define STATS_DECLTRACK_CSRET_ATTR(NAME) \
148 STATS_DECLTRACK(NAME, CSReturn, \
149 BUILD_STAT_MSG_IR_ATTR(call site returns, NAME))
150#define STATS_DECLTRACK_FLOATING_ATTR(NAME) \
151 STATS_DECLTRACK(NAME, Floating, \
152 ("Number of floating values known to be '" #NAME "'"))
153
154// Specialization of the operator<< for abstract attributes subclasses. This
155// disambiguates situations where multiple operators are applicable.
156namespace llvm {
157#define PIPE_OPERATOR(CLASS) \
158 raw_ostream &operator<<(raw_ostream &OS, const CLASS &AA) { \
159 return OS << static_cast<const AbstractAttribute &>(AA); \
160 }
161
201
202#undef PIPE_OPERATOR
203
204template <>
206 const DerefState &R) {
207 ChangeStatus CS0 =
208 clampStateAndIndicateChange(S.DerefBytesState, R.DerefBytesState);
209 ChangeStatus CS1 = clampStateAndIndicateChange(S.GlobalState, R.GlobalState);
210 return CS0 | CS1;
211}
212
213} // namespace llvm
214
215static bool mayBeInCycle(const CycleInfo *CI, const Instruction *I,
216 bool HeaderOnly, Cycle **CPtr = nullptr) {
217 if (!CI)
218 return true;
219 auto *BB = I->getParent();
220 auto *C = CI->getCycle(BB);
221 if (!C)
222 return false;
223 if (CPtr)
224 *CPtr = C;
225 return !HeaderOnly || BB == C->getHeader();
226}
227
228/// Checks if a type could have padding bytes.
229static bool isDenselyPacked(Type *Ty, const DataLayout &DL) {
230 // There is no size information, so be conservative.
231 if (!Ty->isSized())
232 return false;
233
234 // If the alloc size is not equal to the storage size, then there are padding
235 // bytes. For x86_fp80 on x86-64, size: 80 alloc size: 128.
236 if (DL.getTypeSizeInBits(Ty) != DL.getTypeAllocSizeInBits(Ty))
237 return false;
238
239 // FIXME: This isn't the right way to check for padding in vectors with
240 // non-byte-size elements.
241 if (VectorType *SeqTy = dyn_cast<VectorType>(Ty))
242 return isDenselyPacked(SeqTy->getElementType(), DL);
243
244 // For array types, check for padding within members.
245 if (ArrayType *SeqTy = dyn_cast<ArrayType>(Ty))
246 return isDenselyPacked(SeqTy->getElementType(), DL);
247
248 if (!isa<StructType>(Ty))
249 return true;
250
251 // Check for padding within and between elements of a struct.
252 StructType *StructTy = cast<StructType>(Ty);
253 const StructLayout *Layout = DL.getStructLayout(StructTy);
254 uint64_t StartPos = 0;
255 for (unsigned I = 0, E = StructTy->getNumElements(); I < E; ++I) {
256 Type *ElTy = StructTy->getElementType(I);
257 if (!isDenselyPacked(ElTy, DL))
258 return false;
259 if (StartPos != Layout->getElementOffsetInBits(I))
260 return false;
261 StartPos += DL.getTypeAllocSizeInBits(ElTy);
262 }
263
264 return true;
265}
266
267/// Get pointer operand of memory accessing instruction. If \p I is
268/// not a memory accessing instruction, return nullptr. If \p AllowVolatile,
269/// is set to false and the instruction is volatile, return nullptr.
271 bool AllowVolatile) {
272 if (!AllowVolatile && I->isVolatile())
273 return nullptr;
274
275 if (auto *LI = dyn_cast<LoadInst>(I)) {
276 return LI->getPointerOperand();
277 }
278
279 if (auto *SI = dyn_cast<StoreInst>(I)) {
280 return SI->getPointerOperand();
281 }
282
283 if (auto *CXI = dyn_cast<AtomicCmpXchgInst>(I)) {
284 return CXI->getPointerOperand();
285 }
286
287 if (auto *RMWI = dyn_cast<AtomicRMWInst>(I)) {
288 return RMWI->getPointerOperand();
289 }
290
291 return nullptr;
292}
293
294/// Helper function to create a pointer based on \p Ptr, and advanced by \p
295/// Offset bytes.
296static Value *constructPointer(Value *Ptr, int64_t Offset,
297 IRBuilder<NoFolder> &IRB) {
298 LLVM_DEBUG(dbgs() << "Construct pointer: " << *Ptr << " + " << Offset
299 << "-bytes\n");
300
301 if (Offset)
302 Ptr = IRB.CreatePtrAdd(Ptr, IRB.getInt64(Offset),
303 Ptr->getName() + ".b" + Twine(Offset));
304 return Ptr;
305}
306
307static const Value *
309 const Value *Val, const DataLayout &DL, APInt &Offset,
310 bool GetMinOffset, bool AllowNonInbounds,
311 bool UseAssumed = false) {
312
313 auto AttributorAnalysis = [&](Value &V, APInt &ROffset) -> bool {
314 const IRPosition &Pos = IRPosition::value(V);
315 // Only track dependence if we are going to use the assumed info.
316 const AAValueConstantRange *ValueConstantRangeAA =
317 A.getAAFor<AAValueConstantRange>(QueryingAA, Pos,
318 UseAssumed ? DepClassTy::OPTIONAL
320 if (!ValueConstantRangeAA)
321 return false;
322 ConstantRange Range = UseAssumed ? ValueConstantRangeAA->getAssumed()
323 : ValueConstantRangeAA->getKnown();
324 if (Range.isFullSet())
325 return false;
326
327 // We can only use the lower part of the range because the upper part can
328 // be higher than what the value can really be.
329 if (GetMinOffset)
330 ROffset = Range.getSignedMin();
331 else
332 ROffset = Range.getSignedMax();
333 return true;
334 };
335
336 return Val->stripAndAccumulateConstantOffsets(DL, Offset, AllowNonInbounds,
337 /* AllowInvariant */ true,
338 AttributorAnalysis);
339}
340
341static const Value *
343 const Value *Ptr, int64_t &BytesOffset,
344 const DataLayout &DL, bool AllowNonInbounds = false) {
345 APInt OffsetAPInt(DL.getIndexTypeSizeInBits(Ptr->getType()), 0);
346 const Value *Base =
347 stripAndAccumulateOffsets(A, QueryingAA, Ptr, DL, OffsetAPInt,
348 /* GetMinOffset */ true, AllowNonInbounds);
349
350 BytesOffset = OffsetAPInt.getSExtValue();
351 return Base;
352}
353
354/// Clamp the information known for all returned values of a function
355/// (identified by \p QueryingAA) into \p S.
356template <typename AAType, typename StateType = typename AAType::StateType,
357 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind,
358 bool RecurseForSelectAndPHI = true>
360 Attributor &A, const AAType &QueryingAA, StateType &S,
361 const IRPosition::CallBaseContext *CBContext = nullptr) {
362 LLVM_DEBUG(dbgs() << "[Attributor] Clamp return value states for "
363 << QueryingAA << " into " << S << "\n");
364
365 assert((QueryingAA.getIRPosition().getPositionKind() ==
367 QueryingAA.getIRPosition().getPositionKind() ==
369 "Can only clamp returned value states for a function returned or call "
370 "site returned position!");
371
372 // Use an optional state as there might not be any return values and we want
373 // to join (IntegerState::operator&) the state of all there are.
374 std::optional<StateType> T;
375
376 // Callback for each possibly returned value.
377 auto CheckReturnValue = [&](Value &RV) -> bool {
378 const IRPosition &RVPos = IRPosition::value(RV, CBContext);
379 // If possible, use the hasAssumedIRAttr interface.
380 if (Attribute::isEnumAttrKind(IRAttributeKind)) {
381 bool IsKnown;
383 A, &QueryingAA, RVPos, DepClassTy::REQUIRED, IsKnown);
384 }
385
386 const AAType *AA =
387 A.getAAFor<AAType>(QueryingAA, RVPos, DepClassTy::REQUIRED);
388 if (!AA)
389 return false;
390 LLVM_DEBUG(dbgs() << "[Attributor] RV: " << RV
391 << " AA: " << AA->getAsStr(&A) << " @ " << RVPos << "\n");
392 const StateType &AAS = AA->getState();
393 if (!T)
394 T = StateType::getBestState(AAS);
395 *T &= AAS;
396 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS << " RV State: " << T
397 << "\n");
398 return T->isValidState();
399 };
400
401 if (!A.checkForAllReturnedValues(CheckReturnValue, QueryingAA,
403 RecurseForSelectAndPHI))
404 S.indicatePessimisticFixpoint();
405 else if (T)
406 S ^= *T;
407}
408
409namespace {
410/// Helper class for generic deduction: return value -> returned position.
411template <typename AAType, typename BaseType,
412 typename StateType = typename BaseType::StateType,
413 bool PropagateCallBaseContext = false,
414 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind,
415 bool RecurseForSelectAndPHI = true>
416struct AAReturnedFromReturnedValues : public BaseType {
417 AAReturnedFromReturnedValues(const IRPosition &IRP, Attributor &A)
418 : BaseType(IRP, A) {}
419
420 /// See AbstractAttribute::updateImpl(...).
421 ChangeStatus updateImpl(Attributor &A) override {
422 StateType S(StateType::getBestState(this->getState()));
423 clampReturnedValueStates<AAType, StateType, IRAttributeKind,
424 RecurseForSelectAndPHI>(
425 A, *this, S,
426 PropagateCallBaseContext ? this->getCallBaseContext() : nullptr);
427 // TODO: If we know we visited all returned values, thus no are assumed
428 // dead, we can take the known information from the state T.
429 return clampStateAndIndicateChange<StateType>(this->getState(), S);
430 }
431};
432
433/// Clamp the information known at all call sites for a given argument
434/// (identified by \p QueryingAA) into \p S.
435template <typename AAType, typename StateType = typename AAType::StateType,
436 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind>
437static void clampCallSiteArgumentStates(Attributor &A, const AAType &QueryingAA,
438 StateType &S) {
439 LLVM_DEBUG(dbgs() << "[Attributor] Clamp call site argument states for "
440 << QueryingAA << " into " << S << "\n");
441
442 assert(QueryingAA.getIRPosition().getPositionKind() ==
444 "Can only clamp call site argument states for an argument position!");
445
446 // Use an optional state as there might not be any return values and we want
447 // to join (IntegerState::operator&) the state of all there are.
448 std::optional<StateType> T;
449
450 // The argument number which is also the call site argument number.
451 unsigned ArgNo = QueryingAA.getIRPosition().getCallSiteArgNo();
452
453 auto CallSiteCheck = [&](AbstractCallSite ACS) {
454 const IRPosition &ACSArgPos = IRPosition::callsite_argument(ACS, ArgNo);
455 // Check if a coresponding argument was found or if it is on not associated
456 // (which can happen for callback calls).
457 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
458 return false;
459
460 // If possible, use the hasAssumedIRAttr interface.
461 if (Attribute::isEnumAttrKind(IRAttributeKind)) {
462 bool IsKnown;
464 A, &QueryingAA, ACSArgPos, DepClassTy::REQUIRED, IsKnown);
465 }
466
467 const AAType *AA =
468 A.getAAFor<AAType>(QueryingAA, ACSArgPos, DepClassTy::REQUIRED);
469 if (!AA)
470 return false;
471 LLVM_DEBUG(dbgs() << "[Attributor] ACS: " << *ACS.getInstruction()
472 << " AA: " << AA->getAsStr(&A) << " @" << ACSArgPos
473 << "\n");
474 const StateType &AAS = AA->getState();
475 if (!T)
476 T = StateType::getBestState(AAS);
477 *T &= AAS;
478 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS << " CSA State: " << T
479 << "\n");
480 return T->isValidState();
481 };
482
483 bool UsedAssumedInformation = false;
484 if (!A.checkForAllCallSites(CallSiteCheck, QueryingAA, true,
485 UsedAssumedInformation))
486 S.indicatePessimisticFixpoint();
487 else if (T)
488 S ^= *T;
489}
490
491/// This function is the bridge between argument position and the call base
492/// context.
493template <typename AAType, typename BaseType,
494 typename StateType = typename AAType::StateType,
495 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind>
496bool getArgumentStateFromCallBaseContext(Attributor &A,
497 BaseType &QueryingAttribute,
498 IRPosition &Pos, StateType &State) {
500 "Expected an 'argument' position !");
501 const CallBase *CBContext = Pos.getCallBaseContext();
502 if (!CBContext)
503 return false;
504
505 int ArgNo = Pos.getCallSiteArgNo();
506 assert(ArgNo >= 0 && "Invalid Arg No!");
507 const IRPosition CBArgPos = IRPosition::callsite_argument(*CBContext, ArgNo);
508
509 // If possible, use the hasAssumedIRAttr interface.
510 if (Attribute::isEnumAttrKind(IRAttributeKind)) {
511 bool IsKnown;
513 A, &QueryingAttribute, CBArgPos, DepClassTy::REQUIRED, IsKnown);
514 }
515
516 const auto *AA =
517 A.getAAFor<AAType>(QueryingAttribute, CBArgPos, DepClassTy::REQUIRED);
518 if (!AA)
519 return false;
520 const StateType &CBArgumentState =
521 static_cast<const StateType &>(AA->getState());
522
523 LLVM_DEBUG(dbgs() << "[Attributor] Briding Call site context to argument"
524 << "Position:" << Pos << "CB Arg state:" << CBArgumentState
525 << "\n");
526
527 // NOTE: If we want to do call site grouping it should happen here.
528 State ^= CBArgumentState;
529 return true;
530}
531
532/// Helper class for generic deduction: call site argument -> argument position.
533template <typename AAType, typename BaseType,
534 typename StateType = typename AAType::StateType,
535 bool BridgeCallBaseContext = false,
536 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind>
537struct AAArgumentFromCallSiteArguments : public BaseType {
538 AAArgumentFromCallSiteArguments(const IRPosition &IRP, Attributor &A)
539 : BaseType(IRP, A) {}
540
541 /// See AbstractAttribute::updateImpl(...).
542 ChangeStatus updateImpl(Attributor &A) override {
543 StateType S = StateType::getBestState(this->getState());
544
545 if (BridgeCallBaseContext) {
546 bool Success =
547 getArgumentStateFromCallBaseContext<AAType, BaseType, StateType,
548 IRAttributeKind>(
549 A, *this, this->getIRPosition(), S);
550 if (Success)
551 return clampStateAndIndicateChange<StateType>(this->getState(), S);
552 }
553 clampCallSiteArgumentStates<AAType, StateType, IRAttributeKind>(A, *this,
554 S);
555
556 // TODO: If we know we visited all incoming values, thus no are assumed
557 // dead, we can take the known information from the state T.
558 return clampStateAndIndicateChange<StateType>(this->getState(), S);
559 }
560};
561
562/// Helper class for generic replication: function returned -> cs returned.
563template <typename AAType, typename BaseType,
564 typename StateType = typename BaseType::StateType,
565 bool IntroduceCallBaseContext = false,
566 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind>
567struct AACalleeToCallSite : public BaseType {
568 AACalleeToCallSite(const IRPosition &IRP, Attributor &A) : BaseType(IRP, A) {}
569
570 /// See AbstractAttribute::updateImpl(...).
571 ChangeStatus updateImpl(Attributor &A) override {
572 auto IRPKind = this->getIRPosition().getPositionKind();
574 IRPKind == IRPosition::IRP_CALL_SITE) &&
575 "Can only wrap function returned positions for call site "
576 "returned positions!");
577 auto &S = this->getState();
578
579 CallBase &CB = cast<CallBase>(this->getAnchorValue());
580 if (IntroduceCallBaseContext)
581 LLVM_DEBUG(dbgs() << "[Attributor] Introducing call base context:" << CB
582 << "\n");
583
584 ChangeStatus Changed = ChangeStatus::UNCHANGED;
585 auto CalleePred = [&](ArrayRef<const Function *> Callees) {
586 for (const Function *Callee : Callees) {
587 IRPosition FnPos =
589 ? IRPosition::returned(*Callee,
590 IntroduceCallBaseContext ? &CB : nullptr)
591 : IRPosition::function(
592 *Callee, IntroduceCallBaseContext ? &CB : nullptr);
593 // If possible, use the hasAssumedIRAttr interface.
594 if (Attribute::isEnumAttrKind(IRAttributeKind)) {
595 bool IsKnown;
597 A, this, FnPos, DepClassTy::REQUIRED, IsKnown))
598 return false;
599 continue;
600 }
601
602 const AAType *AA =
603 A.getAAFor<AAType>(*this, FnPos, DepClassTy::REQUIRED);
604 if (!AA)
605 return false;
606 Changed |= clampStateAndIndicateChange(S, AA->getState());
607 if (S.isAtFixpoint())
608 return S.isValidState();
609 }
610 return true;
611 };
612 if (!A.checkForAllCallees(CalleePred, *this, CB))
613 return S.indicatePessimisticFixpoint();
614 return Changed;
615 }
616};
617
618/// Helper function to accumulate uses.
619template <class AAType, typename StateType = typename AAType::StateType>
620static void followUsesInContext(AAType &AA, Attributor &A,
622 const Instruction *CtxI,
624 StateType &State) {
625 auto EIt = Explorer.begin(CtxI), EEnd = Explorer.end(CtxI);
626 for (unsigned u = 0; u < Uses.size(); ++u) {
627 const Use *U = Uses[u];
628 if (const Instruction *UserI = dyn_cast<Instruction>(U->getUser())) {
629 bool Found = Explorer.findInContextOf(UserI, EIt, EEnd);
630 if (Found && AA.followUseInMBEC(A, U, UserI, State))
631 Uses.insert_range(llvm::make_pointer_range(UserI->uses()));
632 }
633 }
634}
635
636/// Use the must-be-executed-context around \p I to add information into \p S.
637/// The AAType class is required to have `followUseInMBEC` method with the
638/// following signature and behaviour:
639///
640/// bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I)
641/// U - Underlying use.
642/// I - The user of the \p U.
643/// Returns true if the value should be tracked transitively.
644///
645template <class AAType, typename StateType = typename AAType::StateType>
646static void followUsesInMBEC(AAType &AA, Attributor &A, StateType &S,
647 Instruction &CtxI) {
648 const Value &Val = AA.getIRPosition().getAssociatedValue();
649 if (isa<ConstantData>(Val))
650 return;
651
653 A.getInfoCache().getMustBeExecutedContextExplorer();
654 if (!Explorer)
655 return;
656
657 // Container for (transitive) uses of the associated value.
659 for (const Use &U : Val.uses())
660 Uses.insert(&U);
661
662 followUsesInContext<AAType>(AA, A, *Explorer, &CtxI, Uses, S);
663
664 if (S.isAtFixpoint())
665 return;
666
668 auto Pred = [&](const Instruction *I) {
669 if (const CondBrInst *Br = dyn_cast<CondBrInst>(I))
670 BrInsts.push_back(Br);
671 return true;
672 };
673
674 // Here, accumulate conditional branch instructions in the context. We
675 // explore the child paths and collect the known states. The disjunction of
676 // those states can be merged to its own state. Let ParentState_i be a state
677 // to indicate the known information for an i-th branch instruction in the
678 // context. ChildStates are created for its successors respectively.
679 //
680 // ParentS_1 = ChildS_{1, 1} /\ ChildS_{1, 2} /\ ... /\ ChildS_{1, n_1}
681 // ParentS_2 = ChildS_{2, 1} /\ ChildS_{2, 2} /\ ... /\ ChildS_{2, n_2}
682 // ...
683 // ParentS_m = ChildS_{m, 1} /\ ChildS_{m, 2} /\ ... /\ ChildS_{m, n_m}
684 //
685 // Known State |= ParentS_1 \/ ParentS_2 \/... \/ ParentS_m
686 //
687 // FIXME: Currently, recursive branches are not handled. For example, we
688 // can't deduce that ptr must be dereferenced in below function.
689 //
690 // void f(int a, int c, int *ptr) {
691 // if(a)
692 // if (b) {
693 // *ptr = 0;
694 // } else {
695 // *ptr = 1;
696 // }
697 // else {
698 // if (b) {
699 // *ptr = 0;
700 // } else {
701 // *ptr = 1;
702 // }
703 // }
704 // }
705
706 Explorer->checkForAllContext(&CtxI, Pred);
707 for (const CondBrInst *Br : BrInsts) {
708 StateType ParentState;
709
710 // The known state of the parent state is a conjunction of children's
711 // known states so it is initialized with a best state.
712 ParentState.indicateOptimisticFixpoint();
713
714 for (const BasicBlock *BB : Br->successors()) {
715 StateType ChildState;
716
717 size_t BeforeSize = Uses.size();
718 followUsesInContext(AA, A, *Explorer, &BB->front(), Uses, ChildState);
719
720 // Erase uses which only appear in the child.
721 for (auto It = Uses.begin() + BeforeSize; It != Uses.end();)
722 It = Uses.erase(It);
723
724 ParentState &= ChildState;
725 }
726
727 // Use only known state.
728 S += ParentState;
729 }
730}
731} // namespace
732
733/// ------------------------ PointerInfo ---------------------------------------
734
735namespace llvm {
736namespace AA {
737namespace PointerInfo {
738
739struct State;
740
741} // namespace PointerInfo
742} // namespace AA
743
744/// Helper for AA::PointerInfo::Access DenseMap/Set usage.
745template <>
748 static unsigned getHashValue(const Access &A);
749 static bool isEqual(const Access &LHS, const Access &RHS);
750};
751
752/// Helper that allows RangeTy as a key in a DenseMap.
753template <> struct DenseMapInfo<AA::RangeTy> {
759
760 static bool isEqual(const AA::RangeTy &A, const AA::RangeTy B) {
761 return A == B;
762 }
763};
764
765/// Helper for AA::PointerInfo::Access DenseMap/Set usage ignoring everythign
766/// but the instruction
767struct AccessAsInstructionInfo : DenseMapInfo<Instruction *> {
770 static unsigned getHashValue(const Access &A);
771 static bool isEqual(const Access &LHS, const Access &RHS);
772};
773
774} // namespace llvm
775
776/// A type to track pointer/struct usage and accesses for AAPointerInfo.
778 /// Return the best possible representable state.
779 static State getBestState(const State &SIS) { return State(); }
780
781 /// Return the worst possible representable state.
782 static State getWorstState(const State &SIS) {
783 State R;
784 R.indicatePessimisticFixpoint();
785 return R;
786 }
787
788 State() = default;
789 State(State &&SIS) = default;
790
791 const State &getAssumed() const { return *this; }
792
793 /// See AbstractState::isValidState().
794 bool isValidState() const override { return BS.isValidState(); }
795
796 /// See AbstractState::isAtFixpoint().
797 bool isAtFixpoint() const override { return BS.isAtFixpoint(); }
798
799 /// See AbstractState::indicateOptimisticFixpoint().
801 BS.indicateOptimisticFixpoint();
803 }
804
805 /// See AbstractState::indicatePessimisticFixpoint().
807 BS.indicatePessimisticFixpoint();
809 }
810
811 State &operator=(const State &R) {
812 if (this == &R)
813 return *this;
814 BS = R.BS;
815 AccessList = R.AccessList;
816 OffsetBins = R.OffsetBins;
817 RemoteIMap = R.RemoteIMap;
818 ReturnedOffsets = R.ReturnedOffsets;
819 return *this;
820 }
821
823 if (this == &R)
824 return *this;
825 std::swap(BS, R.BS);
826 std::swap(AccessList, R.AccessList);
827 std::swap(OffsetBins, R.OffsetBins);
828 std::swap(RemoteIMap, R.RemoteIMap);
829 std::swap(ReturnedOffsets, R.ReturnedOffsets);
830 return *this;
831 }
832
833 /// Add a new Access to the state at offset \p Offset and with size \p Size.
834 /// The access is associated with \p I, writes \p Content (if anything), and
835 /// is of kind \p Kind. If an Access already exists for the same \p I and same
836 /// \p RemoteI, the two are combined, potentially losing information about
837 /// offset and size. The resulting access must now be moved from its original
838 /// OffsetBin to the bin for its new offset.
839 ///
840 /// \Returns CHANGED, if the state changed, UNCHANGED otherwise.
842 Instruction &I, std::optional<Value *> Content,
844 Instruction *RemoteI = nullptr);
845
848 int64_t numOffsetBins() const { return OffsetBins.size(); }
849
850 const AAPointerInfo::Access &getAccess(unsigned Index) const {
851 return AccessList[Index];
852 }
853
854protected:
855 // Every memory instruction results in an Access object. We maintain a list of
856 // all Access objects that we own, along with the following maps:
857 //
858 // - OffsetBins: RangeTy -> { Access }
859 // - RemoteIMap: RemoteI x LocalI -> Access
860 //
861 // A RemoteI is any instruction that accesses memory. RemoteI is different
862 // from LocalI if and only if LocalI is a call; then RemoteI is some
863 // instruction in the callgraph starting from LocalI. Multiple paths in the
864 // callgraph from LocalI to RemoteI may produce multiple accesses, but these
865 // are all combined into a single Access object. This may result in loss of
866 // information in RangeTy in the Access object.
870
871 /// Flag to determine if the underlying pointer is reaching a return statement
872 /// in the associated function or not. Returns in other functions cause
873 /// invalidation.
875
876 /// See AAPointerInfo::forallInterferingAccesses.
877 template <typename F>
879 if (!isValidState() || !ReturnedOffsets.isUnassigned())
880 return false;
881
882 for (const auto &It : OffsetBins) {
883 AA::RangeTy ItRange = It.getFirst();
884 if (!Range.mayOverlap(ItRange))
885 continue;
886 bool IsExact = Range == ItRange && !Range.offsetOrSizeAreUnknown();
887 for (auto Index : It.getSecond()) {
888 auto &Access = AccessList[Index];
889 if (!CB(Access, IsExact))
890 return false;
891 }
892 }
893 return true;
894 }
895
896 /// See AAPointerInfo::forallInterferingAccesses.
897 template <typename F>
899 AA::RangeTy &Range) const {
900 if (!isValidState() || !ReturnedOffsets.isUnassigned())
901 return false;
902
903 auto LocalList = RemoteIMap.find(&I);
904 if (LocalList == RemoteIMap.end()) {
905 return true;
906 }
907
908 for (unsigned Index : LocalList->getSecond()) {
909 for (auto &R : AccessList[Index]) {
910 Range &= R;
911 if (Range.offsetAndSizeAreUnknown())
912 break;
913 }
914 }
916 }
917
918private:
919 /// State to track fixpoint and validity.
920 BooleanState BS;
921};
922
925 std::optional<Value *> Content, AAPointerInfo::AccessKind Kind, Type *Ty,
926 Instruction *RemoteI) {
927 RemoteI = RemoteI ? RemoteI : &I;
928
929 // Check if we have an access for this instruction, if not, simply add it.
930 auto &LocalList = RemoteIMap[RemoteI];
931 bool AccExists = false;
932 unsigned AccIndex = AccessList.size();
933 for (auto Index : LocalList) {
934 auto &A = AccessList[Index];
935 if (A.getLocalInst() == &I) {
936 AccExists = true;
937 AccIndex = Index;
938 break;
939 }
940 }
941
942 auto AddToBins = [&](const AAPointerInfo::RangeList &ToAdd) {
943 LLVM_DEBUG(if (ToAdd.size()) dbgs()
944 << "[AAPointerInfo] Inserting access in new offset bins\n";);
945
946 for (auto Key : ToAdd) {
947 LLVM_DEBUG(dbgs() << " key " << Key << "\n");
948 OffsetBins[Key].insert(AccIndex);
949 }
950 };
951
952 if (!AccExists) {
953 AccessList.emplace_back(&I, RemoteI, Ranges, Content, Kind, Ty);
954 assert((AccessList.size() == AccIndex + 1) &&
955 "New Access should have been at AccIndex");
956 LocalList.push_back(AccIndex);
957 AddToBins(AccessList[AccIndex].getRanges());
959 }
960
961 // Combine the new Access with the existing Access, and then update the
962 // mapping in the offset bins.
963 AAPointerInfo::Access Acc(&I, RemoteI, Ranges, Content, Kind, Ty);
964 auto &Current = AccessList[AccIndex];
965 auto Before = Current;
966 Current &= Acc;
967 if (Current == Before)
969
970 auto &ExistingRanges = Before.getRanges();
971 auto &NewRanges = Current.getRanges();
972
973 // Ranges that are in the old access but not the new access need to be removed
974 // from the offset bins.
976 AAPointerInfo::RangeList::set_difference(ExistingRanges, NewRanges, ToRemove);
977 LLVM_DEBUG(if (ToRemove.size()) dbgs()
978 << "[AAPointerInfo] Removing access from old offset bins\n";);
979
980 for (auto Key : ToRemove) {
981 LLVM_DEBUG(dbgs() << " key " << Key << "\n");
982 assert(OffsetBins.count(Key) && "Existing Access must be in some bin.");
983 auto &Bin = OffsetBins[Key];
984 assert(Bin.count(AccIndex) &&
985 "Expected bin to actually contain the Access.");
986 Bin.erase(AccIndex);
987 }
988
989 // Ranges that are in the new access but not the old access need to be added
990 // to the offset bins.
992 AAPointerInfo::RangeList::set_difference(NewRanges, ExistingRanges, ToAdd);
993 AddToBins(ToAdd);
995}
996
997namespace {
998
999#ifndef NDEBUG
1001 const AAPointerInfo::OffsetInfo &OI) {
1002 OS << llvm::interleaved_array(OI);
1003 return OS;
1004}
1005#endif // NDEBUG
1006
1007struct AAPointerInfoImpl
1008 : public StateWrapper<AA::PointerInfo::State, AAPointerInfo> {
1010 AAPointerInfoImpl(const IRPosition &IRP, Attributor &A) : BaseTy(IRP) {}
1011
1012 /// See AbstractAttribute::getAsStr().
1013 const std::string getAsStr(Attributor *A) const override {
1014 return std::string("PointerInfo ") +
1015 (isValidState() ? (std::string("#") +
1016 std::to_string(OffsetBins.size()) + " bins")
1017 : "<invalid>") +
1018 (reachesReturn()
1019 ? (" (returned:" +
1020 join(map_range(ReturnedOffsets,
1021 [](int64_t O) { return std::to_string(O); }),
1022 ", ") +
1023 ")")
1024 : "");
1025 }
1026
1027 /// See AbstractAttribute::manifest(...).
1028 ChangeStatus manifest(Attributor &A) override {
1029 return AAPointerInfo::manifest(A);
1030 }
1031
1032 const_bin_iterator begin() const override { return State::begin(); }
1033 const_bin_iterator end() const override { return State::end(); }
1034 int64_t numOffsetBins() const override { return State::numOffsetBins(); }
1035 bool reachesReturn() const override {
1036 return !ReturnedOffsets.isUnassigned();
1037 }
1038 void addReturnedOffsetsTo(OffsetInfo &OI) const override {
1039 if (ReturnedOffsets.isUnknown()) {
1040 OI.setUnknown();
1041 return;
1042 }
1043
1044 OffsetInfo MergedOI;
1045 for (auto Offset : ReturnedOffsets) {
1046 OffsetInfo TmpOI = OI;
1047 TmpOI.addToAll(Offset);
1048 MergedOI.merge(TmpOI);
1049 }
1050 OI = std::move(MergedOI);
1051 }
1052
1053 ChangeStatus setReachesReturn(const OffsetInfo &ReachedReturnedOffsets) {
1054 if (ReturnedOffsets.isUnknown())
1055 return ChangeStatus::UNCHANGED;
1056 if (ReachedReturnedOffsets.isUnknown()) {
1057 ReturnedOffsets.setUnknown();
1058 return ChangeStatus::CHANGED;
1059 }
1060 if (ReturnedOffsets.merge(ReachedReturnedOffsets))
1061 return ChangeStatus::CHANGED;
1062 return ChangeStatus::UNCHANGED;
1063 }
1064
1065 bool forallInterferingAccesses(
1066 AA::RangeTy Range,
1067 function_ref<bool(const AAPointerInfo::Access &, bool)> CB)
1068 const override {
1069 return State::forallInterferingAccesses(Range, CB);
1070 }
1071
1072 bool forallInterferingAccesses(
1073 Attributor &A, const AbstractAttribute &QueryingAA, Instruction &I,
1074 bool FindInterferingWrites, bool FindInterferingReads,
1075 function_ref<bool(const Access &, bool)> UserCB, bool &HasBeenWrittenTo,
1076 AA::RangeTy &Range,
1077 function_ref<bool(const Access &)> SkipCB) const override {
1078 HasBeenWrittenTo = false;
1079
1080 SmallPtrSet<const Access *, 8> DominatingWrites;
1081 SmallVector<std::pair<const Access *, bool>, 8> InterferingAccesses;
1082
1083 Function &Scope = *I.getFunction();
1084 bool IsKnownNoSync;
1085 bool IsAssumedNoSync = AA::hasAssumedIRAttr<Attribute::NoSync>(
1086 A, &QueryingAA, IRPosition::function(Scope), DepClassTy::OPTIONAL,
1087 IsKnownNoSync);
1088 const auto *ExecDomainAA = A.lookupAAFor<AAExecutionDomain>(
1089 IRPosition::function(Scope), &QueryingAA, DepClassTy::NONE);
1090 bool AllInSameNoSyncFn = IsAssumedNoSync;
1091 bool InstIsExecutedByInitialThreadOnly =
1092 ExecDomainAA && ExecDomainAA->isExecutedByInitialThreadOnly(I);
1093
1094 // If the function is not ending in aligned barriers, we need the stores to
1095 // be in aligned barriers. The load being in one is not sufficient since the
1096 // store might be executed by a thread that disappears after, causing the
1097 // aligned barrier guarding the load to unblock and the load to read a value
1098 // that has no CFG path to the load.
1099 bool InstIsExecutedInAlignedRegion =
1100 FindInterferingReads && ExecDomainAA &&
1101 ExecDomainAA->isExecutedInAlignedRegion(A, I);
1102
1103 if (InstIsExecutedInAlignedRegion || InstIsExecutedByInitialThreadOnly)
1104 A.recordDependence(*ExecDomainAA, QueryingAA, DepClassTy::OPTIONAL);
1105
1106 InformationCache &InfoCache = A.getInfoCache();
1107 bool IsThreadLocalObj =
1108 AA::isAssumedThreadLocalObject(A, getAssociatedValue(), *this);
1109
1110 // Helper to determine if we need to consider threading, which we cannot
1111 // right now. However, if the function is (assumed) nosync or the thread
1112 // executing all instructions is the main thread only we can ignore
1113 // threading. Also, thread-local objects do not require threading reasoning.
1114 // Finally, we can ignore threading if either access is executed in an
1115 // aligned region.
1116 auto CanIgnoreThreadingForInst = [&](const Instruction &I) -> bool {
1117 if (IsThreadLocalObj || AllInSameNoSyncFn)
1118 return true;
1119 const auto *FnExecDomainAA =
1120 I.getFunction() == &Scope
1121 ? ExecDomainAA
1122 : A.lookupAAFor<AAExecutionDomain>(
1123 IRPosition::function(*I.getFunction()), &QueryingAA,
1124 DepClassTy::NONE);
1125 if (!FnExecDomainAA)
1126 return false;
1127 if (InstIsExecutedInAlignedRegion ||
1128 (FindInterferingWrites &&
1129 FnExecDomainAA->isExecutedInAlignedRegion(A, I))) {
1130 A.recordDependence(*FnExecDomainAA, QueryingAA, DepClassTy::OPTIONAL);
1131 return true;
1132 }
1133 if (InstIsExecutedByInitialThreadOnly &&
1134 FnExecDomainAA->isExecutedByInitialThreadOnly(I)) {
1135 A.recordDependence(*FnExecDomainAA, QueryingAA, DepClassTy::OPTIONAL);
1136 return true;
1137 }
1138 return false;
1139 };
1140
1141 // Helper to determine if the access is executed by the same thread as the
1142 // given instruction, for now it is sufficient to avoid any potential
1143 // threading effects as we cannot deal with them anyway.
1144 auto CanIgnoreThreading = [&](const Access &Acc) -> bool {
1145 return CanIgnoreThreadingForInst(*Acc.getRemoteInst()) ||
1146 (Acc.getRemoteInst() != Acc.getLocalInst() &&
1147 CanIgnoreThreadingForInst(*Acc.getLocalInst()));
1148 };
1149
1150 // TODO: Use inter-procedural reachability and dominance.
1151 bool IsKnownNoRecurse;
1153 A, this, IRPosition::function(Scope), DepClassTy::OPTIONAL,
1154 IsKnownNoRecurse);
1155
1156 // TODO: Use reaching kernels from AAKernelInfo (or move it to
1157 // AAExecutionDomain) such that we allow scopes other than kernels as long
1158 // as the reaching kernels are disjoint.
1159 bool InstInKernel = A.getInfoCache().isKernel(Scope);
1160 bool ObjHasKernelLifetime = false;
1161 const bool UseDominanceReasoning =
1162 FindInterferingWrites && IsKnownNoRecurse;
1163 const DominatorTree *DT =
1164 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(Scope);
1165
1166 // Helper to check if a value has "kernel lifetime", that is it will not
1167 // outlive a GPU kernel. This is true for shared, constant, and local
1168 // globals on AMD and NVIDIA GPUs.
1169 auto HasKernelLifetime = [&](Value *V, Module &M) {
1170 if (!AA::isGPU(M))
1171 return false;
1172 unsigned VAS = V->getType()->getPointerAddressSpace();
1173 return AA::isGPUSharedAddressSpace(M, VAS) ||
1176 };
1177
1178 // The IsLiveInCalleeCB will be used by the AA::isPotentiallyReachable query
1179 // to determine if we should look at reachability from the callee. For
1180 // certain pointers we know the lifetime and we do not have to step into the
1181 // callee to determine reachability as the pointer would be dead in the
1182 // callee. See the conditional initialization below.
1183 std::function<bool(const Function &)> IsLiveInCalleeCB;
1184
1185 if (auto *AI = dyn_cast<AllocaInst>(&getAssociatedValue())) {
1186 // If the alloca containing function is not recursive the alloca
1187 // must be dead in the callee.
1188 const Function *AIFn = AI->getFunction();
1189 ObjHasKernelLifetime = A.getInfoCache().isKernel(*AIFn);
1190 bool IsKnownNoRecurse;
1192 A, this, IRPosition::function(*AIFn), DepClassTy::OPTIONAL,
1193 IsKnownNoRecurse)) {
1194 IsLiveInCalleeCB = [AIFn](const Function &Fn) { return AIFn != &Fn; };
1195 }
1196 } else if (auto *GV = dyn_cast<GlobalValue>(&getAssociatedValue())) {
1197 // If the global has kernel lifetime we can stop if we reach a kernel
1198 // as it is "dead" in the (unknown) callees.
1199 ObjHasKernelLifetime = HasKernelLifetime(GV, *GV->getParent());
1200 if (ObjHasKernelLifetime)
1201 IsLiveInCalleeCB = [&A](const Function &Fn) {
1202 return !A.getInfoCache().isKernel(Fn);
1203 };
1204 }
1205
1206 // Set of accesses/instructions that will overwrite the result and are
1207 // therefore blockers in the reachability traversal.
1208 AA::InstExclusionSetTy ExclusionSet;
1209
1210 auto AccessCB = [&](const Access &Acc, bool Exact) {
1211 Function *AccScope = Acc.getRemoteInst()->getFunction();
1212 bool AccInSameScope = AccScope == &Scope;
1213
1214 // If the object has kernel lifetime we can ignore accesses only reachable
1215 // by other kernels. For now we only skip accesses *in* other kernels.
1216 if (InstInKernel && ObjHasKernelLifetime && !AccInSameScope &&
1217 A.getInfoCache().isKernel(*AccScope))
1218 return true;
1219
1220 if (Exact && Acc.isMustAccess() && Acc.getRemoteInst() != &I) {
1221 if (Acc.isWrite() || (isa<LoadInst>(I) && Acc.isWriteOrAssumption()))
1222 ExclusionSet.insert(Acc.getRemoteInst());
1223 }
1224
1225 if ((!FindInterferingWrites || !Acc.isWriteOrAssumption()) &&
1226 (!FindInterferingReads || !Acc.isRead()))
1227 return true;
1228
1229 bool Dominates = FindInterferingWrites && DT && Exact &&
1230 Acc.isMustAccess() && AccInSameScope &&
1231 DT->dominates(Acc.getRemoteInst(), &I);
1232 if (Dominates)
1233 DominatingWrites.insert(&Acc);
1234
1235 // Track if all interesting accesses are in the same `nosync` function as
1236 // the given instruction.
1237 AllInSameNoSyncFn &= Acc.getRemoteInst()->getFunction() == &Scope;
1238
1239 InterferingAccesses.push_back({&Acc, Exact});
1240 return true;
1241 };
1242 if (!State::forallInterferingAccesses(I, AccessCB, Range))
1243 return false;
1244
1245 HasBeenWrittenTo = !DominatingWrites.empty();
1246
1247 // Dominating writes form a chain, find the least/lowest member.
1248 Instruction *LeastDominatingWriteInst = nullptr;
1249 for (const Access *Acc : DominatingWrites) {
1250 if (!LeastDominatingWriteInst) {
1251 LeastDominatingWriteInst = Acc->getRemoteInst();
1252 } else if (DT->dominates(LeastDominatingWriteInst,
1253 Acc->getRemoteInst())) {
1254 LeastDominatingWriteInst = Acc->getRemoteInst();
1255 }
1256 }
1257
1258 // Helper to determine if we can skip a specific write access.
1259 auto CanSkipAccess = [&](const Access &Acc, bool Exact) {
1260 if (SkipCB && SkipCB(Acc))
1261 return true;
1262 if (!CanIgnoreThreading(Acc))
1263 return false;
1264
1265 // Check read (RAW) dependences and write (WAR) dependences as necessary.
1266 // If we successfully excluded all effects we are interested in, the
1267 // access can be skipped.
1268 bool ReadChecked = !FindInterferingReads;
1269 bool WriteChecked = !FindInterferingWrites;
1270
1271 // If the instruction cannot reach the access, the former does not
1272 // interfere with what the access reads.
1273 if (!ReadChecked) {
1274 if (!AA::isPotentiallyReachable(A, I, *Acc.getRemoteInst(), QueryingAA,
1275 &ExclusionSet, IsLiveInCalleeCB))
1276 ReadChecked = true;
1277 }
1278 // If the instruction cannot be reach from the access, the latter does not
1279 // interfere with what the instruction reads.
1280 if (!WriteChecked) {
1281 if (!AA::isPotentiallyReachable(A, *Acc.getRemoteInst(), I, QueryingAA,
1282 &ExclusionSet, IsLiveInCalleeCB))
1283 WriteChecked = true;
1284 }
1285
1286 // If we still might be affected by the write of the access but there are
1287 // dominating writes in the function of the instruction
1288 // (HasBeenWrittenTo), we can try to reason that the access is overwritten
1289 // by them. This would have happend above if they are all in the same
1290 // function, so we only check the inter-procedural case. Effectively, we
1291 // want to show that there is no call after the dominting write that might
1292 // reach the access, and when it returns reach the instruction with the
1293 // updated value. To this end, we iterate all call sites, check if they
1294 // might reach the instruction without going through another access
1295 // (ExclusionSet) and at the same time might reach the access. However,
1296 // that is all part of AAInterFnReachability.
1297 if (!WriteChecked && HasBeenWrittenTo &&
1298 Acc.getRemoteInst()->getFunction() != &Scope) {
1299
1300 const auto *FnReachabilityAA = A.getAAFor<AAInterFnReachability>(
1301 QueryingAA, IRPosition::function(Scope), DepClassTy::OPTIONAL);
1302 if (FnReachabilityAA) {
1303 // Without going backwards in the call tree, can we reach the access
1304 // from the least dominating write. Do not allow to pass the
1305 // instruction itself either.
1306 bool Inserted = ExclusionSet.insert(&I).second;
1307
1308 if (!FnReachabilityAA->instructionCanReach(
1309 A, *LeastDominatingWriteInst,
1310 *Acc.getRemoteInst()->getFunction(), &ExclusionSet))
1311 WriteChecked = true;
1312
1313 if (Inserted)
1314 ExclusionSet.erase(&I);
1315 }
1316 }
1317
1318 if (ReadChecked && WriteChecked)
1319 return true;
1320
1321 if (!DT || !UseDominanceReasoning)
1322 return false;
1323 if (!DominatingWrites.count(&Acc))
1324 return false;
1325 return LeastDominatingWriteInst != Acc.getRemoteInst();
1326 };
1327
1328 // Run the user callback on all accesses we cannot skip and return if
1329 // that succeeded for all or not.
1330 for (auto &It : InterferingAccesses) {
1331 if ((!AllInSameNoSyncFn && !IsThreadLocalObj && !ExecDomainAA) ||
1332 !CanSkipAccess(*It.first, It.second)) {
1333 if (!UserCB(*It.first, It.second))
1334 return false;
1335 }
1336 }
1337 return true;
1338 }
1339
1340 ChangeStatus translateAndAddStateFromCallee(Attributor &A,
1341 const AAPointerInfo &OtherAA,
1342 CallBase &CB) {
1343 using namespace AA::PointerInfo;
1344 if (!OtherAA.getState().isValidState() || !isValidState())
1345 return indicatePessimisticFixpoint();
1346
1347 ChangeStatus Changed = ChangeStatus::UNCHANGED;
1348 const auto &OtherAAImpl = static_cast<const AAPointerInfoImpl &>(OtherAA);
1349 bool IsByval = OtherAAImpl.getAssociatedArgument()->hasByValAttr();
1350 Changed |= setReachesReturn(OtherAAImpl.ReturnedOffsets);
1351
1352 // Combine the accesses bin by bin.
1353 const auto &State = OtherAAImpl.getState();
1354 for (const auto &It : State) {
1355 for (auto Index : It.getSecond()) {
1356 const auto &RAcc = State.getAccess(Index);
1357 if (IsByval && !RAcc.isRead())
1358 continue;
1359 bool UsedAssumedInformation = false;
1360 AccessKind AK = RAcc.getKind();
1361 auto Content = A.translateArgumentToCallSiteContent(
1362 RAcc.getContent(), CB, *this, UsedAssumedInformation);
1363 AK = AccessKind(AK & (IsByval ? AccessKind::AK_R : AccessKind::AK_RW));
1364 AK = AccessKind(AK | (RAcc.isMayAccess() ? AK_MAY : AK_MUST));
1365
1366 Changed |= addAccess(A, RAcc.getRanges(), CB, Content, AK,
1367 RAcc.getType(), RAcc.getRemoteInst());
1368 }
1369 }
1370 return Changed;
1371 }
1372
1373 ChangeStatus translateAndAddState(Attributor &A, const AAPointerInfo &OtherAA,
1374 const OffsetInfo &Offsets, CallBase &CB,
1375 bool IsMustAcc) {
1376 using namespace AA::PointerInfo;
1377 if (!OtherAA.getState().isValidState() || !isValidState())
1378 return indicatePessimisticFixpoint();
1379
1380 const auto &OtherAAImpl = static_cast<const AAPointerInfoImpl &>(OtherAA);
1381
1382 // Combine the accesses bin by bin.
1383 ChangeStatus Changed = ChangeStatus::UNCHANGED;
1384 const auto &State = OtherAAImpl.getState();
1385 for (const auto &It : State) {
1386 for (auto Index : It.getSecond()) {
1387 const auto &RAcc = State.getAccess(Index);
1388 if (!IsMustAcc && RAcc.isAssumption())
1389 continue;
1390 for (auto Offset : Offsets) {
1391 auto NewRanges = Offset == AA::RangeTy::Unknown
1393 : RAcc.getRanges();
1394 if (!NewRanges.isUnknown()) {
1395 NewRanges.addToAllOffsets(Offset);
1396 }
1397 AccessKind AK = RAcc.getKind();
1398 if (!IsMustAcc)
1399 AK = AccessKind((AK & ~AK_MUST) | AK_MAY);
1400 Changed |= addAccess(A, NewRanges, CB, RAcc.getContent(), AK,
1401 RAcc.getType(), RAcc.getRemoteInst());
1402 }
1403 }
1404 }
1405 return Changed;
1406 }
1407
1408 /// Statistic tracking for all AAPointerInfo implementations.
1409 /// See AbstractAttribute::trackStatistics().
1410 void trackPointerInfoStatistics(const IRPosition &IRP) const {}
1411
1412 /// Dump the state into \p O.
1413 void dumpState(raw_ostream &O) {
1414 for (auto &It : OffsetBins) {
1415 O << "[" << It.first.Offset << "-" << It.first.Offset + It.first.Size
1416 << "] : " << It.getSecond().size() << "\n";
1417 for (auto AccIndex : It.getSecond()) {
1418 auto &Acc = AccessList[AccIndex];
1419 O << " - " << Acc.getKind() << " - " << *Acc.getLocalInst() << "\n";
1420 if (Acc.getLocalInst() != Acc.getRemoteInst())
1421 O << " --> " << *Acc.getRemoteInst()
1422 << "\n";
1423 if (!Acc.isWrittenValueYetUndetermined()) {
1424 if (isa_and_nonnull<Function>(Acc.getWrittenValue()))
1425 O << " - c: func " << Acc.getWrittenValue()->getName()
1426 << "\n";
1427 else if (Acc.getWrittenValue())
1428 O << " - c: " << *Acc.getWrittenValue() << "\n";
1429 else
1430 O << " - c: <unknown>\n";
1431 }
1432 }
1433 }
1434 }
1435};
1436
1437struct AAPointerInfoFloating : public AAPointerInfoImpl {
1439 AAPointerInfoFloating(const IRPosition &IRP, Attributor &A)
1440 : AAPointerInfoImpl(IRP, A) {}
1441
1442 /// Deal with an access and signal if it was handled successfully.
1443 bool handleAccess(Attributor &A, Instruction &I,
1444 std::optional<Value *> Content, AccessKind Kind,
1445 OffsetInfo::VecTy &Offsets, ChangeStatus &Changed,
1446 Type &Ty) {
1447 using namespace AA::PointerInfo;
1449 const DataLayout &DL = A.getDataLayout();
1450 TypeSize AccessSize = DL.getTypeStoreSize(&Ty);
1451 if (!AccessSize.isScalable())
1452 Size = AccessSize.getFixedValue();
1453
1454 // Make a strictly ascending list of offsets as required by addAccess()
1455 SmallVector<int64_t> OffsetsSorted(Offsets.begin(), Offsets.end());
1456 llvm::sort(OffsetsSorted);
1457
1459 if (!VT || VT->getElementCount().isScalable() ||
1460 !Content.value_or(nullptr) || !isa<Constant>(*Content) ||
1461 (*Content)->getType() != VT ||
1462 DL.getTypeStoreSize(VT->getElementType()).isScalable()) {
1463 Changed =
1464 Changed | addAccess(A, {OffsetsSorted, Size}, I, Content, Kind, &Ty);
1465 } else {
1466 // Handle vector stores with constant content element-wise.
1467 // TODO: We could look for the elements or create instructions
1468 // representing them.
1469 // TODO: We need to push the Content into the range abstraction
1470 // (AA::RangeTy) to allow different content values for different
1471 // ranges. ranges. Hence, support vectors storing different values.
1472 Type *ElementType = VT->getElementType();
1473 int64_t ElementSize = DL.getTypeStoreSize(ElementType).getFixedValue();
1474 auto *ConstContent = cast<Constant>(*Content);
1475 Type *Int32Ty = Type::getInt32Ty(ElementType->getContext());
1476 SmallVector<int64_t> ElementOffsets(Offsets.begin(), Offsets.end());
1477
1478 for (int i = 0, e = VT->getElementCount().getFixedValue(); i != e; ++i) {
1479 Value *ElementContent = ConstantExpr::getExtractElement(
1480 ConstContent, ConstantInt::get(Int32Ty, i));
1481
1482 // Add the element access.
1483 Changed = Changed | addAccess(A, {ElementOffsets, ElementSize}, I,
1484 ElementContent, Kind, ElementType);
1485
1486 // Advance the offsets for the next element.
1487 for (auto &ElementOffset : ElementOffsets)
1488 ElementOffset += ElementSize;
1489 }
1490 }
1491 return true;
1492 };
1493
1494 /// See AbstractAttribute::updateImpl(...).
1495 ChangeStatus updateImpl(Attributor &A) override;
1496
1497 /// If the indices to \p GEP can be traced to constants, incorporate all
1498 /// of these into \p UsrOI.
1499 ///
1500 /// \return true iff \p UsrOI is updated.
1501 bool collectConstantsForGEP(Attributor &A, const DataLayout &DL,
1502 OffsetInfo &UsrOI, const OffsetInfo &PtrOI,
1503 const GEPOperator *GEP);
1504
1505 /// See AbstractAttribute::trackStatistics()
1506 void trackStatistics() const override {
1507 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
1508 }
1509};
1510
1511bool AAPointerInfoFloating::collectConstantsForGEP(Attributor &A,
1512 const DataLayout &DL,
1513 OffsetInfo &UsrOI,
1514 const OffsetInfo &PtrOI,
1515 const GEPOperator *GEP) {
1516 unsigned BitWidth = DL.getIndexTypeSizeInBits(GEP->getType());
1517 SmallMapVector<Value *, APInt, 4> VariableOffsets;
1518 APInt ConstantOffset(BitWidth, 0);
1519
1520 assert(!UsrOI.isUnknown() && !PtrOI.isUnknown() &&
1521 "Don't look for constant values if the offset has already been "
1522 "determined to be unknown.");
1523
1524 if (!GEP->collectOffset(DL, BitWidth, VariableOffsets, ConstantOffset)) {
1525 UsrOI.setUnknown();
1526 return true;
1527 }
1528
1529 LLVM_DEBUG(dbgs() << "[AAPointerInfo] GEP offset is "
1530 << (VariableOffsets.empty() ? "" : "not") << " constant "
1531 << *GEP << "\n");
1532
1533 auto Union = PtrOI;
1534 Union.addToAll(ConstantOffset.getSExtValue());
1535
1536 // Each VI in VariableOffsets has a set of potential constant values. Every
1537 // combination of elements, picked one each from these sets, is separately
1538 // added to the original set of offsets, thus resulting in more offsets.
1539 for (const auto &VI : VariableOffsets) {
1540 auto *PotentialConstantsAA = A.getAAFor<AAPotentialConstantValues>(
1541 *this, IRPosition::value(*VI.first), DepClassTy::OPTIONAL);
1542 if (!PotentialConstantsAA || !PotentialConstantsAA->isValidState()) {
1543 UsrOI.setUnknown();
1544 return true;
1545 }
1546
1547 // UndefValue is treated as a zero, which leaves Union as is.
1548 if (PotentialConstantsAA->undefIsContained())
1549 continue;
1550
1551 // We need at least one constant in every set to compute an actual offset.
1552 // Otherwise, we end up pessimizing AAPointerInfo by respecting offsets that
1553 // don't actually exist. In other words, the absence of constant values
1554 // implies that the operation can be assumed dead for now.
1555 auto &AssumedSet = PotentialConstantsAA->getAssumedSet();
1556 if (AssumedSet.empty())
1557 return false;
1558
1559 OffsetInfo Product;
1560 for (const auto &ConstOffset : AssumedSet) {
1561 auto CopyPerOffset = Union;
1562 CopyPerOffset.addToAll(ConstOffset.getSExtValue() *
1563 VI.second.getZExtValue());
1564 Product.merge(CopyPerOffset);
1565 }
1566 Union = Product;
1567 }
1568
1569 UsrOI = std::move(Union);
1570 return true;
1571}
1572
1573ChangeStatus AAPointerInfoFloating::updateImpl(Attributor &A) {
1574 using namespace AA::PointerInfo;
1576 const DataLayout &DL = A.getDataLayout();
1577 Value &AssociatedValue = getAssociatedValue();
1578
1579 DenseMap<Value *, OffsetInfo> OffsetInfoMap;
1580 OffsetInfoMap[&AssociatedValue].insert(0);
1581
1582 auto HandlePassthroughUser = [&](Value *Usr, Value *CurPtr, bool &Follow) {
1583 // One does not simply walk into a map and assign a reference to a possibly
1584 // new location. That can cause an invalidation before the assignment
1585 // happens, like so:
1586 //
1587 // OffsetInfoMap[Usr] = OffsetInfoMap[CurPtr]; /* bad idea! */
1588 //
1589 // The RHS is a reference that may be invalidated by an insertion caused by
1590 // the LHS. So we ensure that the side-effect of the LHS happens first.
1591
1592 assert(OffsetInfoMap.contains(CurPtr) &&
1593 "CurPtr does not exist in the map!");
1594
1595 auto &UsrOI = OffsetInfoMap[Usr];
1596 auto &PtrOI = OffsetInfoMap[CurPtr];
1597 assert(!PtrOI.isUnassigned() &&
1598 "Cannot pass through if the input Ptr was not visited!");
1599 UsrOI.merge(PtrOI);
1600 Follow = true;
1601 return true;
1602 };
1603
1604 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
1605 Value *CurPtr = U.get();
1606 User *Usr = U.getUser();
1607 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Analyze " << *CurPtr << " in " << *Usr
1608 << "\n");
1609 assert(OffsetInfoMap.count(CurPtr) &&
1610 "The current pointer offset should have been seeded!");
1611 assert(!OffsetInfoMap[CurPtr].isUnassigned() &&
1612 "Current pointer should be assigned");
1613
1614 if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Usr)) {
1615 if (CE->isCast())
1616 return HandlePassthroughUser(Usr, CurPtr, Follow);
1617 if (!isa<GEPOperator>(CE)) {
1618 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Unhandled constant user " << *CE
1619 << "\n");
1620 return false;
1621 }
1622 }
1623 if (auto *GEP = dyn_cast<GEPOperator>(Usr)) {
1624 // Note the order here, the Usr access might change the map, CurPtr is
1625 // already in it though.
1626 auto &UsrOI = OffsetInfoMap[Usr];
1627 auto &PtrOI = OffsetInfoMap[CurPtr];
1628
1629 if (UsrOI.isUnknown())
1630 return true;
1631
1632 if (PtrOI.isUnknown()) {
1633 Follow = true;
1634 UsrOI.setUnknown();
1635 return true;
1636 }
1637
1638 Follow = collectConstantsForGEP(A, DL, UsrOI, PtrOI, GEP);
1639 return true;
1640 }
1641 if (isa<PtrToIntInst>(Usr))
1642 return false;
1643 if (isa<CastInst>(Usr) || isa<SelectInst>(Usr))
1644 return HandlePassthroughUser(Usr, CurPtr, Follow);
1645 // Returns are allowed if they are in the associated functions. Users can
1646 // then check the call site return. Returns from other functions can't be
1647 // tracked and are cause for invalidation.
1648 if (auto *RI = dyn_cast<ReturnInst>(Usr)) {
1649 if (RI->getFunction() == getAssociatedFunction()) {
1650 auto &PtrOI = OffsetInfoMap[CurPtr];
1651 Changed |= setReachesReturn(PtrOI);
1652 return true;
1653 }
1654 return false;
1655 }
1656
1657 // For PHIs we need to take care of the recurrence explicitly as the value
1658 // might change while we iterate through a loop. For now, we give up if
1659 // the PHI is not invariant.
1660 if (auto *PHI = dyn_cast<PHINode>(Usr)) {
1661 // Note the order here, the Usr access might change the map, CurPtr is
1662 // already in it though.
1663 auto [PhiIt, IsFirstPHIUser] = OffsetInfoMap.try_emplace(PHI);
1664 auto &UsrOI = PhiIt->second;
1665 auto &PtrOI = OffsetInfoMap[CurPtr];
1666
1667 // Check if the PHI operand has already an unknown offset as we can't
1668 // improve on that anymore.
1669 if (PtrOI.isUnknown()) {
1670 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI operand offset unknown "
1671 << *CurPtr << " in " << *PHI << "\n");
1672 Follow = !UsrOI.isUnknown();
1673 UsrOI.setUnknown();
1674 return true;
1675 }
1676
1677 // Check if the PHI is invariant (so far).
1678 if (UsrOI == PtrOI) {
1679 assert(!PtrOI.isUnassigned() &&
1680 "Cannot assign if the current Ptr was not visited!");
1681 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI is invariant (so far)");
1682 return true;
1683 }
1684
1685 // Check if the PHI operand can be traced back to AssociatedValue.
1686 APInt Offset(
1687 DL.getIndexSizeInBits(CurPtr->getType()->getPointerAddressSpace()),
1688 0);
1689 Value *CurPtrBase = CurPtr->stripAndAccumulateConstantOffsets(
1690 DL, Offset, /* AllowNonInbounds */ true);
1691 auto It = OffsetInfoMap.find(CurPtrBase);
1692 if (It == OffsetInfoMap.end()) {
1693 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI operand is too complex "
1694 << *CurPtr << " in " << *PHI
1695 << " (base: " << *CurPtrBase << ")\n");
1696 UsrOI.setUnknown();
1697 Follow = true;
1698 return true;
1699 }
1700
1701 // Check if the PHI operand is not dependent on the PHI itself. Every
1702 // recurrence is a cyclic net of PHIs in the data flow, and has an
1703 // equivalent Cycle in the control flow. One of those PHIs must be in the
1704 // header of that control flow Cycle. This is independent of the choice of
1705 // Cycles reported by CycleInfo. It is sufficient to check the PHIs in
1706 // every Cycle header; if such a node is marked unknown, this will
1707 // eventually propagate through the whole net of PHIs in the recurrence.
1708 const auto *CI =
1709 A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>(
1710 *PHI->getFunction());
1711 if (mayBeInCycle(CI, cast<Instruction>(Usr), /* HeaderOnly */ true)) {
1712 auto BaseOI = It->getSecond();
1713 BaseOI.addToAll(Offset.getZExtValue());
1714 if (IsFirstPHIUser || BaseOI == UsrOI) {
1715 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI is invariant " << *CurPtr
1716 << " in " << *Usr << "\n");
1717 return HandlePassthroughUser(Usr, CurPtr, Follow);
1718 }
1719
1720 LLVM_DEBUG(
1721 dbgs() << "[AAPointerInfo] PHI operand pointer offset mismatch "
1722 << *CurPtr << " in " << *PHI << "\n");
1723 UsrOI.setUnknown();
1724 Follow = true;
1725 return true;
1726 }
1727
1728 UsrOI.merge(PtrOI);
1729 Follow = true;
1730 return true;
1731 }
1732
1733 if (auto *LoadI = dyn_cast<LoadInst>(Usr)) {
1734 // If the access is to a pointer that may or may not be the associated
1735 // value, e.g. due to a PHI, we cannot assume it will be read.
1736 AccessKind AK = AccessKind::AK_R;
1737 if (getUnderlyingObject(CurPtr) == &AssociatedValue)
1738 AK = AccessKind(AK | AccessKind::AK_MUST);
1739 else
1740 AK = AccessKind(AK | AccessKind::AK_MAY);
1741 if (!handleAccess(A, *LoadI, /* Content */ nullptr, AK,
1742 OffsetInfoMap[CurPtr].Offsets, Changed,
1743 *LoadI->getType()))
1744 return false;
1745
1746 auto IsAssumption = [](Instruction &I) {
1747 if (auto *II = dyn_cast<IntrinsicInst>(&I))
1748 return II->isAssumeLikeIntrinsic();
1749 return false;
1750 };
1751
1752 auto IsImpactedInRange = [&](Instruction *FromI, Instruction *ToI) {
1753 // Check if the assumption and the load are executed together without
1754 // memory modification.
1755 do {
1756 if (FromI->mayWriteToMemory() && !IsAssumption(*FromI))
1757 return true;
1758 FromI = FromI->getNextNode();
1759 } while (FromI && FromI != ToI);
1760 return false;
1761 };
1762
1763 BasicBlock *BB = LoadI->getParent();
1764 auto IsValidAssume = [&](IntrinsicInst &IntrI) {
1765 if (IntrI.getIntrinsicID() != Intrinsic::assume)
1766 return false;
1767 BasicBlock *IntrBB = IntrI.getParent();
1768 if (IntrI.getParent() == BB) {
1769 if (IsImpactedInRange(LoadI->getNextNode(), &IntrI))
1770 return false;
1771 } else {
1772 auto PredIt = pred_begin(IntrBB);
1773 if (PredIt == pred_end(IntrBB))
1774 return false;
1775 if ((*PredIt) != BB)
1776 return false;
1777 if (++PredIt != pred_end(IntrBB))
1778 return false;
1779 for (auto *SuccBB : successors(BB)) {
1780 if (SuccBB == IntrBB)
1781 continue;
1782 if (isa<UnreachableInst>(SuccBB->getTerminator()))
1783 continue;
1784 return false;
1785 }
1786 if (IsImpactedInRange(LoadI->getNextNode(), BB->getTerminator()))
1787 return false;
1788 if (IsImpactedInRange(&IntrBB->front(), &IntrI))
1789 return false;
1790 }
1791 return true;
1792 };
1793
1794 std::pair<Value *, IntrinsicInst *> Assumption;
1795 for (const Use &LoadU : LoadI->uses()) {
1796 if (auto *CmpI = dyn_cast<CmpInst>(LoadU.getUser())) {
1797 if (!CmpI->isEquality() || !CmpI->isTrueWhenEqual())
1798 continue;
1799 for (const Use &CmpU : CmpI->uses()) {
1800 if (auto *IntrI = dyn_cast<IntrinsicInst>(CmpU.getUser())) {
1801 if (!IsValidAssume(*IntrI))
1802 continue;
1803 int Idx = CmpI->getOperandUse(0) == LoadU;
1804 Assumption = {CmpI->getOperand(Idx), IntrI};
1805 break;
1806 }
1807 }
1808 }
1809 if (Assumption.first)
1810 break;
1811 }
1812
1813 // Check if we found an assumption associated with this load.
1814 if (!Assumption.first || !Assumption.second)
1815 return true;
1816
1817 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Assumption found "
1818 << *Assumption.second << ": " << *LoadI
1819 << " == " << *Assumption.first << "\n");
1820 bool UsedAssumedInformation = false;
1821 std::optional<Value *> Content = nullptr;
1822 if (Assumption.first)
1823 Content =
1824 A.getAssumedSimplified(*Assumption.first, *this,
1825 UsedAssumedInformation, AA::Interprocedural);
1826 return handleAccess(
1827 A, *Assumption.second, Content, AccessKind::AK_ASSUMPTION,
1828 OffsetInfoMap[CurPtr].Offsets, Changed, *LoadI->getType());
1829 }
1830
1831 auto HandleStoreLike = [&](Instruction &I, Value *ValueOp, Type &ValueTy,
1832 ArrayRef<Value *> OtherOps, AccessKind AK) {
1833 for (auto *OtherOp : OtherOps) {
1834 if (OtherOp == CurPtr) {
1835 LLVM_DEBUG(
1836 dbgs()
1837 << "[AAPointerInfo] Escaping use in store like instruction " << I
1838 << "\n");
1839 return false;
1840 }
1841 }
1842
1843 // If the access is to a pointer that may or may not be the associated
1844 // value, e.g. due to a PHI, we cannot assume it will be written.
1845 if (getUnderlyingObject(CurPtr) == &AssociatedValue)
1846 AK = AccessKind(AK | AccessKind::AK_MUST);
1847 else
1848 AK = AccessKind(AK | AccessKind::AK_MAY);
1849 bool UsedAssumedInformation = false;
1850 std::optional<Value *> Content = nullptr;
1851 if (ValueOp)
1852 Content = A.getAssumedSimplified(
1853 *ValueOp, *this, UsedAssumedInformation, AA::Interprocedural);
1854 return handleAccess(A, I, Content, AK, OffsetInfoMap[CurPtr].Offsets,
1855 Changed, ValueTy);
1856 };
1857
1858 if (auto *StoreI = dyn_cast<StoreInst>(Usr))
1859 return HandleStoreLike(*StoreI, StoreI->getValueOperand(),
1860 *StoreI->getValueOperand()->getType(),
1861 {StoreI->getValueOperand()}, AccessKind::AK_W);
1862 if (auto *RMWI = dyn_cast<AtomicRMWInst>(Usr))
1863 return HandleStoreLike(*RMWI, nullptr, *RMWI->getValOperand()->getType(),
1864 {RMWI->getValOperand()}, AccessKind::AK_RW);
1865 if (auto *CXI = dyn_cast<AtomicCmpXchgInst>(Usr))
1866 return HandleStoreLike(
1867 *CXI, nullptr, *CXI->getNewValOperand()->getType(),
1868 {CXI->getCompareOperand(), CXI->getNewValOperand()},
1869 AccessKind::AK_RW);
1870
1871 if (auto *CB = dyn_cast<CallBase>(Usr)) {
1872 if (CB->isLifetimeStartOrEnd())
1873 return true;
1874 const auto *TLI =
1875 A.getInfoCache().getTargetLibraryInfoForFunction(*CB->getFunction());
1876 if (getFreedOperand(CB, TLI) == U)
1877 return true;
1878 if (CB->isArgOperand(&U)) {
1879 unsigned ArgNo = CB->getArgOperandNo(&U);
1880 const auto *CSArgPI = A.getAAFor<AAPointerInfo>(
1881 *this, IRPosition::callsite_argument(*CB, ArgNo),
1883 if (!CSArgPI)
1884 return false;
1885 bool IsArgMustAcc = (getUnderlyingObject(CurPtr) == &AssociatedValue);
1886 Changed = translateAndAddState(A, *CSArgPI, OffsetInfoMap[CurPtr], *CB,
1887 IsArgMustAcc) |
1888 Changed;
1889 if (!CSArgPI->reachesReturn())
1890 return isValidState();
1891
1893 if (!Callee || Callee->arg_size() <= ArgNo)
1894 return false;
1895 bool UsedAssumedInformation = false;
1896 auto ReturnedValue = A.getAssumedSimplified(
1897 IRPosition::returned(*Callee), *this, UsedAssumedInformation,
1899 auto *ReturnedArg =
1900 dyn_cast_or_null<Argument>(ReturnedValue.value_or(nullptr));
1901 auto *Arg = Callee->getArg(ArgNo);
1902 if (ReturnedArg && Arg != ReturnedArg)
1903 return true;
1904 bool IsRetMustAcc = IsArgMustAcc && (ReturnedArg == Arg);
1905 const auto *CSRetPI = A.getAAFor<AAPointerInfo>(
1907 if (!CSRetPI)
1908 return false;
1909 OffsetInfo OI = OffsetInfoMap[CurPtr];
1910 CSArgPI->addReturnedOffsetsTo(OI);
1911 Changed =
1912 translateAndAddState(A, *CSRetPI, OI, *CB, IsRetMustAcc) | Changed;
1913 return isValidState();
1914 }
1915 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Call user not handled " << *CB
1916 << "\n");
1917 return false;
1918 }
1919
1920 LLVM_DEBUG(dbgs() << "[AAPointerInfo] User not handled " << *Usr << "\n");
1921 return false;
1922 };
1923 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) {
1924 assert(OffsetInfoMap.count(OldU) && "Old use should be known already!");
1925 assert(!OffsetInfoMap[OldU].isUnassigned() && "Old use should be assinged");
1926 if (OffsetInfoMap.count(NewU)) {
1927 LLVM_DEBUG({
1928 if (!(OffsetInfoMap[NewU] == OffsetInfoMap[OldU])) {
1929 dbgs() << "[AAPointerInfo] Equivalent use callback failed: "
1930 << OffsetInfoMap[NewU] << " vs " << OffsetInfoMap[OldU]
1931 << "\n";
1932 }
1933 });
1934 return OffsetInfoMap[NewU] == OffsetInfoMap[OldU];
1935 }
1936 bool Unused;
1937 return HandlePassthroughUser(NewU.get(), OldU.get(), Unused);
1938 };
1939 if (!A.checkForAllUses(UsePred, *this, AssociatedValue,
1940 /* CheckBBLivenessOnly */ true, DepClassTy::OPTIONAL,
1941 /* IgnoreDroppableUses */ true, EquivalentUseCB)) {
1942 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Check for all uses failed, abort!\n");
1943 return indicatePessimisticFixpoint();
1944 }
1945
1946 LLVM_DEBUG({
1947 dbgs() << "Accesses by bin after update:\n";
1948 dumpState(dbgs());
1949 });
1950
1951 return Changed;
1952}
1953
1954struct AAPointerInfoReturned final : AAPointerInfoImpl {
1955 AAPointerInfoReturned(const IRPosition &IRP, Attributor &A)
1956 : AAPointerInfoImpl(IRP, A) {}
1957
1958 /// See AbstractAttribute::updateImpl(...).
1959 ChangeStatus updateImpl(Attributor &A) override {
1960 return indicatePessimisticFixpoint();
1961 }
1962
1963 /// See AbstractAttribute::trackStatistics()
1964 void trackStatistics() const override {
1965 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
1966 }
1967};
1968
1969struct AAPointerInfoArgument final : AAPointerInfoFloating {
1970 AAPointerInfoArgument(const IRPosition &IRP, Attributor &A)
1971 : AAPointerInfoFloating(IRP, A) {}
1972
1973 /// See AbstractAttribute::trackStatistics()
1974 void trackStatistics() const override {
1975 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
1976 }
1977};
1978
1979struct AAPointerInfoCallSiteArgument final : AAPointerInfoFloating {
1980 AAPointerInfoCallSiteArgument(const IRPosition &IRP, Attributor &A)
1981 : AAPointerInfoFloating(IRP, A) {}
1982
1983 /// See AbstractAttribute::updateImpl(...).
1984 ChangeStatus updateImpl(Attributor &A) override {
1985 using namespace AA::PointerInfo;
1986 // We handle memory intrinsics explicitly, at least the first (=
1987 // destination) and second (=source) arguments as we know how they are
1988 // accessed.
1989 if (auto *MI = dyn_cast_or_null<MemIntrinsic>(getCtxI())) {
1990 int64_t LengthVal = AA::RangeTy::Unknown;
1991 if (auto Length = MI->getLengthInBytes())
1992 LengthVal = Length->getSExtValue();
1993 unsigned ArgNo = getIRPosition().getCallSiteArgNo();
1994 ChangeStatus Changed = ChangeStatus::UNCHANGED;
1995 if (ArgNo > 1) {
1996 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Unhandled memory intrinsic "
1997 << *MI << "\n");
1998 return indicatePessimisticFixpoint();
1999 } else {
2000 auto Kind =
2001 ArgNo == 0 ? AccessKind::AK_MUST_WRITE : AccessKind::AK_MUST_READ;
2002 Changed =
2003 Changed | addAccess(A, {0, LengthVal}, *MI, nullptr, Kind, nullptr);
2004 }
2005 LLVM_DEBUG({
2006 dbgs() << "Accesses by bin after update:\n";
2007 dumpState(dbgs());
2008 });
2009
2010 return Changed;
2011 }
2012
2013 // TODO: Once we have call site specific value information we can provide
2014 // call site specific liveness information and then it makes
2015 // sense to specialize attributes for call sites arguments instead of
2016 // redirecting requests to the callee argument.
2017 Argument *Arg = getAssociatedArgument();
2018 if (Arg) {
2019 const IRPosition &ArgPos = IRPosition::argument(*Arg);
2020 auto *ArgAA =
2021 A.getAAFor<AAPointerInfo>(*this, ArgPos, DepClassTy::REQUIRED);
2022 if (ArgAA && ArgAA->getState().isValidState())
2023 return translateAndAddStateFromCallee(A, *ArgAA,
2024 *cast<CallBase>(getCtxI()));
2025 if (!Arg->getParent()->isDeclaration())
2026 return indicatePessimisticFixpoint();
2027 }
2028
2029 bool IsKnownNoCapture;
2031 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNoCapture))
2032 return indicatePessimisticFixpoint();
2033
2034 bool IsKnown = false;
2035 if (AA::isAssumedReadNone(A, getIRPosition(), *this, IsKnown))
2036 return ChangeStatus::UNCHANGED;
2037 bool ReadOnly = AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown);
2038 auto Kind =
2039 ReadOnly ? AccessKind::AK_MAY_READ : AccessKind::AK_MAY_READ_WRITE;
2040 return addAccess(A, AA::RangeTy::getUnknown(), *getCtxI(), nullptr, Kind,
2041 nullptr);
2042 }
2043
2044 /// See AbstractAttribute::trackStatistics()
2045 void trackStatistics() const override {
2046 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
2047 }
2048};
2049
2050struct AAPointerInfoCallSiteReturned final : AAPointerInfoFloating {
2051 AAPointerInfoCallSiteReturned(const IRPosition &IRP, Attributor &A)
2052 : AAPointerInfoFloating(IRP, A) {}
2053
2054 /// See AbstractAttribute::trackStatistics()
2055 void trackStatistics() const override {
2056 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
2057 }
2058};
2059} // namespace
2060
2061/// -----------------------NoUnwind Function Attribute--------------------------
2062
2063namespace {
2064struct AANoUnwindImpl : AANoUnwind {
2065 AANoUnwindImpl(const IRPosition &IRP, Attributor &A) : AANoUnwind(IRP, A) {}
2066
2067 /// See AbstractAttribute::initialize(...).
2068 void initialize(Attributor &A) override {
2069 bool IsKnown;
2071 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
2072 (void)IsKnown;
2073 }
2074
2075 const std::string getAsStr(Attributor *A) const override {
2076 return getAssumed() ? "nounwind" : "may-unwind";
2077 }
2078
2079 /// See AbstractAttribute::updateImpl(...).
2080 ChangeStatus updateImpl(Attributor &A) override {
2081 auto Opcodes = {
2082 (unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,
2083 (unsigned)Instruction::Call, (unsigned)Instruction::CleanupRet,
2084 (unsigned)Instruction::CatchSwitch, (unsigned)Instruction::Resume};
2085
2086 auto CheckForNoUnwind = [&](Instruction &I) {
2087 if (!I.mayThrow(/* IncludePhaseOneUnwind */ true))
2088 return true;
2089
2090 if (const auto *CB = dyn_cast<CallBase>(&I)) {
2091 bool IsKnownNoUnwind;
2093 A, this, IRPosition::callsite_function(*CB), DepClassTy::REQUIRED,
2094 IsKnownNoUnwind);
2095 }
2096 return false;
2097 };
2098
2099 bool UsedAssumedInformation = false;
2100 if (!A.checkForAllInstructions(CheckForNoUnwind, *this, Opcodes,
2101 UsedAssumedInformation))
2102 return indicatePessimisticFixpoint();
2103
2104 return ChangeStatus::UNCHANGED;
2105 }
2106};
2107
2108struct AANoUnwindFunction final : public AANoUnwindImpl {
2109 AANoUnwindFunction(const IRPosition &IRP, Attributor &A)
2110 : AANoUnwindImpl(IRP, A) {}
2111
2112 /// See AbstractAttribute::trackStatistics()
2113 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nounwind) }
2114};
2115
2116/// NoUnwind attribute deduction for a call sites.
2117struct AANoUnwindCallSite final
2118 : AACalleeToCallSite<AANoUnwind, AANoUnwindImpl> {
2119 AANoUnwindCallSite(const IRPosition &IRP, Attributor &A)
2120 : AACalleeToCallSite<AANoUnwind, AANoUnwindImpl>(IRP, A) {}
2121
2122 /// See AbstractAttribute::trackStatistics()
2123 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nounwind); }
2124};
2125} // namespace
2126
2127/// ------------------------ NoSync Function Attribute -------------------------
2128
2129bool AANoSync::isAlignedBarrier(const CallBase &CB, bool ExecutedAligned) {
2130 switch (CB.getIntrinsicID()) {
2131 case Intrinsic::nvvm_barrier_cta_sync_aligned_all:
2132 case Intrinsic::nvvm_barrier_cta_sync_aligned_count:
2133 case Intrinsic::nvvm_barrier_cta_red_and_aligned_all:
2134 case Intrinsic::nvvm_barrier_cta_red_and_aligned_count:
2135 case Intrinsic::nvvm_barrier_cta_red_or_aligned_all:
2136 case Intrinsic::nvvm_barrier_cta_red_or_aligned_count:
2137 case Intrinsic::nvvm_barrier_cta_red_popc_aligned_all:
2138 case Intrinsic::nvvm_barrier_cta_red_popc_aligned_count:
2139 return true;
2140 case Intrinsic::amdgcn_s_barrier:
2141 if (ExecutedAligned)
2142 return true;
2143 break;
2144 default:
2145 break;
2146 }
2147 return hasAssumption(CB, KnownAssumptionString("ompx_aligned_barrier"));
2148}
2149
2151 if (!I->isAtomic())
2152 return false;
2153
2154 if (auto *FI = dyn_cast<FenceInst>(I))
2155 // All legal orderings for fence are stronger than monotonic.
2156 return FI->getSyncScopeID() != SyncScope::SingleThread;
2157 if (auto *AI = dyn_cast<AtomicCmpXchgInst>(I)) {
2158 // Unordered is not a legal ordering for cmpxchg.
2159 return (AI->getSuccessOrdering() != AtomicOrdering::Monotonic ||
2160 AI->getFailureOrdering() != AtomicOrdering::Monotonic);
2161 }
2162
2163 AtomicOrdering Ordering;
2164 switch (I->getOpcode()) {
2165 case Instruction::AtomicRMW:
2166 Ordering = cast<AtomicRMWInst>(I)->getOrdering();
2167 break;
2168 case Instruction::Store:
2169 Ordering = cast<StoreInst>(I)->getOrdering();
2170 break;
2171 case Instruction::Load:
2172 Ordering = cast<LoadInst>(I)->getOrdering();
2173 break;
2174 default:
2176 "New atomic operations need to be known in the attributor.");
2177 }
2178
2179 return (Ordering != AtomicOrdering::Unordered &&
2180 Ordering != AtomicOrdering::Monotonic);
2181}
2182
2183namespace {
2184struct AANoSyncImpl : AANoSync {
2185 AANoSyncImpl(const IRPosition &IRP, Attributor &A) : AANoSync(IRP, A) {}
2186
2187 /// See AbstractAttribute::initialize(...).
2188 void initialize(Attributor &A) override {
2189 bool IsKnown;
2190 assert(!AA::hasAssumedIRAttr<Attribute::NoSync>(A, nullptr, getIRPosition(),
2191 DepClassTy::NONE, IsKnown));
2192 (void)IsKnown;
2193 }
2194
2195 const std::string getAsStr(Attributor *A) const override {
2196 return getAssumed() ? "nosync" : "may-sync";
2197 }
2198
2199 /// See AbstractAttribute::updateImpl(...).
2200 ChangeStatus updateImpl(Attributor &A) override;
2201};
2202
2203ChangeStatus AANoSyncImpl::updateImpl(Attributor &A) {
2204
2205 auto CheckRWInstForNoSync = [&](Instruction &I) {
2206 return AA::isNoSyncInst(A, I, *this);
2207 };
2208
2209 auto CheckForNoSync = [&](Instruction &I) {
2210 // At this point we handled all read/write effects and they are all
2211 // nosync, so they can be skipped.
2212 if (I.mayReadOrWriteMemory())
2213 return true;
2214
2215 bool IsKnown;
2216 CallBase &CB = cast<CallBase>(I);
2219 IsKnown))
2220 return true;
2221
2222 // non-convergent and readnone imply nosync.
2223 return !CB.isConvergent();
2224 };
2225
2226 bool UsedAssumedInformation = false;
2227 if (!A.checkForAllReadWriteInstructions(CheckRWInstForNoSync, *this,
2228 UsedAssumedInformation) ||
2229 !A.checkForAllCallLikeInstructions(CheckForNoSync, *this,
2230 UsedAssumedInformation))
2231 return indicatePessimisticFixpoint();
2232
2234}
2235
2236struct AANoSyncFunction final : public AANoSyncImpl {
2237 AANoSyncFunction(const IRPosition &IRP, Attributor &A)
2238 : AANoSyncImpl(IRP, A) {}
2239
2240 /// See AbstractAttribute::trackStatistics()
2241 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nosync) }
2242};
2243
2244/// NoSync attribute deduction for a call sites.
2245struct AANoSyncCallSite final : AACalleeToCallSite<AANoSync, AANoSyncImpl> {
2246 AANoSyncCallSite(const IRPosition &IRP, Attributor &A)
2247 : AACalleeToCallSite<AANoSync, AANoSyncImpl>(IRP, A) {}
2248
2249 /// See AbstractAttribute::trackStatistics()
2250 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nosync); }
2251};
2252} // namespace
2253
2254/// ------------------------ No-Free Attributes ----------------------------
2255
2256namespace {
2257struct AANoFreeImpl : public AANoFree {
2258 AANoFreeImpl(const IRPosition &IRP, Attributor &A) : AANoFree(IRP, A) {}
2259
2260 /// See AbstractAttribute::initialize(...).
2261 void initialize(Attributor &A) override {
2262 bool IsKnown;
2263 assert(!AA::hasAssumedIRAttr<Attribute::NoFree>(A, nullptr, getIRPosition(),
2264 DepClassTy::NONE, IsKnown));
2265 (void)IsKnown;
2266 }
2267
2268 /// See AbstractAttribute::updateImpl(...).
2269 ChangeStatus updateImpl(Attributor &A) override {
2270 auto CheckForNoFree = [&](Instruction &I) {
2271 if (auto *CB = dyn_cast<CallBase>(&I)) {
2272 bool IsKnown;
2274 A, this, IRPosition::callsite_function(*CB), DepClassTy::REQUIRED,
2275 IsKnown);
2276 }
2277 // Make sure that synchronization cannot establish happens-before with a
2278 // free on another thread.
2279 return AA::isNoSyncInst(A, I, *this);
2280 };
2281
2282 bool UsedAssumedInformation = false;
2283 if (!A.checkForAllReadWriteInstructions(CheckForNoFree, *this,
2284 UsedAssumedInformation) ||
2285 !A.checkForAllCallLikeInstructions(CheckForNoFree, *this,
2286 UsedAssumedInformation))
2287 return indicatePessimisticFixpoint();
2288
2289 return ChangeStatus::UNCHANGED;
2290 }
2291
2292 /// See AbstractAttribute::getAsStr().
2293 const std::string getAsStr(Attributor *A) const override {
2294 return getAssumed() ? "nofree" : "may-free";
2295 }
2296};
2297
2298struct AANoFreeFunction final : public AANoFreeImpl {
2299 AANoFreeFunction(const IRPosition &IRP, Attributor &A)
2300 : AANoFreeImpl(IRP, A) {}
2301
2302 /// See AbstractAttribute::trackStatistics()
2303 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nofree) }
2304};
2305
2306/// NoFree attribute deduction for a call sites.
2307struct AANoFreeCallSite final : AACalleeToCallSite<AANoFree, AANoFreeImpl> {
2308 AANoFreeCallSite(const IRPosition &IRP, Attributor &A)
2309 : AACalleeToCallSite<AANoFree, AANoFreeImpl>(IRP, A) {}
2310
2311 /// See AbstractAttribute::trackStatistics()
2312 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nofree); }
2313};
2314
2315/// NoFree attribute for floating values.
2316struct AANoFreeFloating : AANoFreeImpl {
2317 AANoFreeFloating(const IRPosition &IRP, Attributor &A)
2318 : AANoFreeImpl(IRP, A) {}
2319
2320 /// See AbstractAttribute::trackStatistics()
2321 void trackStatistics() const override{STATS_DECLTRACK_FLOATING_ATTR(nofree)}
2322
2323 /// See Abstract Attribute::updateImpl(...).
2324 ChangeStatus updateImpl(Attributor &A) override {
2325 const IRPosition &IRP = getIRPosition();
2326
2327 bool IsKnown;
2330 DepClassTy::OPTIONAL, IsKnown))
2331 return ChangeStatus::UNCHANGED;
2332
2333 Value &AssociatedValue = getIRPosition().getAssociatedValue();
2334 auto Pred = [&](const Use &U, bool &Follow) -> bool {
2335 Instruction *UserI = cast<Instruction>(U.getUser());
2336 if (auto *CB = dyn_cast<CallBase>(UserI)) {
2337 if (CB->isBundleOperand(&U))
2338 return false;
2339 if (!CB->isArgOperand(&U))
2340 return true;
2341 unsigned ArgNo = CB->getArgOperandNo(&U);
2342
2343 // Even if the argument is nofree, we still need to check for nocapture,
2344 // as the call may capture the argument without freeing it, and the
2345 // captured argument is freed later.
2346 bool IsKnown;
2348 A, this, IRPosition::callsite_argument(*CB, ArgNo),
2349 DepClassTy::REQUIRED, IsKnown))
2350 return false;
2351
2352 const AANoCapture *NoCaptureAA = nullptr;
2354 A, this, IRPosition::callsite_argument(*CB, ArgNo),
2355 DepClassTy::REQUIRED, IsKnown,
2356 /*IgnoreSubsumingPositions=*/false, &NoCaptureAA)) {
2357 if (NoCaptureAA && NoCaptureAA->isAssumedNoCaptureMaybeReturned()) {
2358 Follow = true;
2359 return true;
2360 }
2361 return false;
2362 }
2363
2364 return true;
2365 }
2366
2367 UseCaptureInfo CI = DetermineUseCaptureKind(U, /*Base=*/nullptr);
2368 if (!capturesAnyProvenance(CI))
2369 return true;
2371 Follow = true;
2372 return true;
2373 }
2374
2375 if (isa<ReturnInst>(UserI) && getIRPosition().isArgumentPosition())
2376 return true;
2377
2378 // Capturing user.
2379 return false;
2380 };
2381 if (!A.checkForAllUses(Pred, *this, AssociatedValue))
2382 return indicatePessimisticFixpoint();
2383
2384 return ChangeStatus::UNCHANGED;
2385 }
2386};
2387
2388/// NoFree attribute for a call site argument.
2389struct AANoFreeArgument final : AANoFreeFloating {
2390 AANoFreeArgument(const IRPosition &IRP, Attributor &A)
2391 : AANoFreeFloating(IRP, A) {}
2392
2393 /// See AbstractAttribute::trackStatistics()
2394 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nofree) }
2395};
2396
2397/// NoFree attribute for call site arguments.
2398struct AANoFreeCallSiteArgument final : AANoFreeFloating {
2399 AANoFreeCallSiteArgument(const IRPosition &IRP, Attributor &A)
2400 : AANoFreeFloating(IRP, A) {}
2401
2402 /// See AbstractAttribute::updateImpl(...).
2403 ChangeStatus updateImpl(Attributor &A) override {
2404 // TODO: Once we have call site specific value information we can provide
2405 // call site specific liveness information and then it makes
2406 // sense to specialize attributes for call sites arguments instead of
2407 // redirecting requests to the callee argument.
2408 Argument *Arg = getAssociatedArgument();
2409 if (!Arg)
2410 return indicatePessimisticFixpoint();
2411 const IRPosition &ArgPos = IRPosition::argument(*Arg);
2412 bool IsKnown;
2414 DepClassTy::REQUIRED, IsKnown))
2415 return ChangeStatus::UNCHANGED;
2416 return indicatePessimisticFixpoint();
2417 }
2418
2419 /// See AbstractAttribute::trackStatistics()
2420 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(nofree) };
2421};
2422
2423/// NoFree attribute for function return value.
2424struct AANoFreeReturned final : AANoFreeFloating {
2425 AANoFreeReturned(const IRPosition &IRP, Attributor &A)
2426 : AANoFreeFloating(IRP, A) {
2427 llvm_unreachable("NoFree is not applicable to function returns!");
2428 }
2429
2430 /// See AbstractAttribute::initialize(...).
2431 void initialize(Attributor &A) override {
2432 llvm_unreachable("NoFree is not applicable to function returns!");
2433 }
2434
2435 /// See AbstractAttribute::updateImpl(...).
2436 ChangeStatus updateImpl(Attributor &A) override {
2437 llvm_unreachable("NoFree is not applicable to function returns!");
2438 }
2439
2440 /// See AbstractAttribute::trackStatistics()
2441 void trackStatistics() const override {}
2442};
2443
2444/// NoFree attribute deduction for a call site return value.
2445struct AANoFreeCallSiteReturned final : AANoFreeFloating {
2446 AANoFreeCallSiteReturned(const IRPosition &IRP, Attributor &A)
2447 : AANoFreeFloating(IRP, A) {}
2448
2449 ChangeStatus manifest(Attributor &A) override {
2450 return ChangeStatus::UNCHANGED;
2451 }
2452 /// See AbstractAttribute::trackStatistics()
2453 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(nofree) }
2454};
2455} // namespace
2456
2457/// ------------------------ NonNull Argument Attribute ------------------------
2458
2460 Attribute::AttrKind ImpliedAttributeKind,
2461 bool IgnoreSubsumingPositions) {
2463 AttrKinds.push_back(Attribute::NonNull);
2466 AttrKinds.push_back(Attribute::Dereferenceable);
2467 if (A.hasAttr(IRP, AttrKinds, IgnoreSubsumingPositions, Attribute::NonNull))
2468 return true;
2469
2470 DominatorTree *DT = nullptr;
2471 AssumptionCache *AC = nullptr;
2472 InformationCache &InfoCache = A.getInfoCache();
2473 if (const Function *Fn = IRP.getAnchorScope()) {
2474 if (!Fn->isDeclaration()) {
2477 }
2478 }
2479
2481 if (IRP.getPositionKind() != IRP_RETURNED) {
2482 Worklist.push_back({IRP.getAssociatedValue(), IRP.getCtxI()});
2483 } else {
2484 bool UsedAssumedInformation = false;
2485 if (!A.checkForAllInstructions(
2486 [&](Instruction &I) {
2487 Worklist.push_back({*cast<ReturnInst>(I).getReturnValue(), &I});
2488 return true;
2489 },
2490 IRP.getAssociatedFunction(), nullptr, {Instruction::Ret},
2491 UsedAssumedInformation, false, /*CheckPotentiallyDead=*/true))
2492 return false;
2493 }
2494
2495 if (llvm::any_of(Worklist, [&](AA::ValueAndContext VAC) {
2496 return !isKnownNonZero(
2497 VAC.getValue(),
2498 SimplifyQuery(A.getDataLayout(), DT, AC, VAC.getCtxI()));
2499 }))
2500 return false;
2501
2502 A.manifestAttrs(IRP, {Attribute::get(IRP.getAnchorValue().getContext(),
2503 Attribute::NonNull)});
2504 return true;
2505}
2506
2507namespace {
2508static int64_t getKnownNonNullAndDerefBytesForUse(
2509 Attributor &A, const AbstractAttribute &QueryingAA, Value &AssociatedValue,
2510 const Use *U, const Instruction *I, bool &IsNonNull, bool &TrackUse) {
2511 TrackUse = false;
2512
2513 const Value *UseV = U->get();
2514 if (!UseV->getType()->isPointerTy())
2515 return 0;
2516
2517 // We need to follow common pointer manipulation uses to the accesses they
2518 // feed into. We can try to be smart to avoid looking through things we do not
2519 // like for now, e.g., non-inbounds GEPs.
2520 if (isa<CastInst>(I)) {
2521 TrackUse = true;
2522 return 0;
2523 }
2524
2526 TrackUse = true;
2527 return 0;
2528 }
2529
2530 Type *PtrTy = UseV->getType();
2531 const Function *F = I->getFunction();
2534 const DataLayout &DL = A.getInfoCache().getDL();
2535 if (const auto *CB = dyn_cast<CallBase>(I)) {
2536 if (CB->isBundleOperand(U)) {
2537 if (RetainedKnowledge RK = getKnowledgeFromUse(
2538 U, {Attribute::NonNull, Attribute::Dereferenceable})) {
2539 IsNonNull |=
2540 (RK.AttrKind == Attribute::NonNull || !NullPointerIsDefined);
2541 return RK.ArgValue;
2542 }
2543 return 0;
2544 }
2545
2546 if (CB->isCallee(U)) {
2547 IsNonNull |= !NullPointerIsDefined;
2548 return 0;
2549 }
2550
2551 unsigned ArgNo = CB->getArgOperandNo(U);
2552 IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo);
2553 // As long as we only use known information there is no need to track
2554 // dependences here.
2555 bool IsKnownNonNull;
2557 DepClassTy::NONE, IsKnownNonNull);
2558 IsNonNull |= IsKnownNonNull;
2559 auto *DerefAA =
2560 A.getAAFor<AADereferenceable>(QueryingAA, IRP, DepClassTy::NONE);
2561 return DerefAA ? DerefAA->getKnownDereferenceableBytes() : 0;
2562 }
2563
2564 std::optional<MemoryLocation> Loc = MemoryLocation::getOrNone(I);
2565 if (!Loc || Loc->Ptr != UseV || !Loc->Size.isPrecise() ||
2566 Loc->Size.isScalable() || I->isVolatile())
2567 return 0;
2568
2569 int64_t Offset;
2570 const Value *Base =
2571 getMinimalBaseOfPointer(A, QueryingAA, Loc->Ptr, Offset, DL);
2572 if (Base && Base == &AssociatedValue) {
2573 int64_t DerefBytes = Loc->Size.getValue() + Offset;
2574 IsNonNull |= !NullPointerIsDefined;
2575 return std::max(int64_t(0), DerefBytes);
2576 }
2577
2578 /// Corner case when an offset is 0.
2580 /*AllowNonInbounds*/ true);
2581 if (Base && Base == &AssociatedValue && Offset == 0) {
2582 int64_t DerefBytes = Loc->Size.getValue();
2583 IsNonNull |= !NullPointerIsDefined;
2584 return std::max(int64_t(0), DerefBytes);
2585 }
2586
2587 return 0;
2588}
2589
2590struct AANonNullImpl : AANonNull {
2591 AANonNullImpl(const IRPosition &IRP, Attributor &A) : AANonNull(IRP, A) {}
2592
2593 /// See AbstractAttribute::initialize(...).
2594 void initialize(Attributor &A) override {
2595 Value &V = *getAssociatedValue().stripPointerCasts();
2596 if (isa<ConstantPointerNull>(V)) {
2597 indicatePessimisticFixpoint();
2598 return;
2599 }
2600
2601 if (Instruction *CtxI = getCtxI())
2602 followUsesInMBEC(*this, A, getState(), *CtxI);
2603 }
2604
2605 /// See followUsesInMBEC
2606 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
2607 AANonNull::StateType &State) {
2608 bool IsNonNull = false;
2609 bool TrackUse = false;
2610 getKnownNonNullAndDerefBytesForUse(A, *this, getAssociatedValue(), U, I,
2611 IsNonNull, TrackUse);
2612 State.setKnown(IsNonNull);
2613 return TrackUse;
2614 }
2615
2616 /// See AbstractAttribute::getAsStr().
2617 const std::string getAsStr(Attributor *A) const override {
2618 return getAssumed() ? "nonnull" : "may-null";
2619 }
2620};
2621
2622/// NonNull attribute for a floating value.
2623struct AANonNullFloating : public AANonNullImpl {
2624 AANonNullFloating(const IRPosition &IRP, Attributor &A)
2625 : AANonNullImpl(IRP, A) {}
2626
2627 /// See AbstractAttribute::updateImpl(...).
2628 ChangeStatus updateImpl(Attributor &A) override {
2629 auto CheckIRP = [&](const IRPosition &IRP) {
2630 bool IsKnownNonNull;
2632 A, *this, IRP, DepClassTy::OPTIONAL, IsKnownNonNull);
2633 };
2634
2635 bool Stripped;
2636 bool UsedAssumedInformation = false;
2637 Value *AssociatedValue = &getAssociatedValue();
2639 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
2640 AA::AnyScope, UsedAssumedInformation))
2641 Stripped = false;
2642 else
2643 Stripped =
2644 Values.size() != 1 || Values.front().getValue() != AssociatedValue;
2645
2646 if (!Stripped) {
2647 bool IsKnown;
2648 if (auto *PHI = dyn_cast<PHINode>(AssociatedValue))
2649 if (llvm::all_of(PHI->incoming_values(), [&](Value *Op) {
2650 return AA::hasAssumedIRAttr<Attribute::NonNull>(
2651 A, this, IRPosition::value(*Op), DepClassTy::OPTIONAL,
2652 IsKnown);
2653 }))
2654 return ChangeStatus::UNCHANGED;
2655 if (auto *Select = dyn_cast<SelectInst>(AssociatedValue))
2657 A, this, IRPosition::value(*Select->getFalseValue()),
2658 DepClassTy::OPTIONAL, IsKnown) &&
2660 A, this, IRPosition::value(*Select->getTrueValue()),
2661 DepClassTy::OPTIONAL, IsKnown))
2662 return ChangeStatus::UNCHANGED;
2663
2664 // If we haven't stripped anything we might still be able to use a
2665 // different AA, but only if the IRP changes. Effectively when we
2666 // interpret this not as a call site value but as a floating/argument
2667 // value.
2668 const IRPosition AVIRP = IRPosition::value(*AssociatedValue);
2669 if (AVIRP == getIRPosition() || !CheckIRP(AVIRP))
2670 return indicatePessimisticFixpoint();
2671 return ChangeStatus::UNCHANGED;
2672 }
2673
2674 for (const auto &VAC : Values)
2675 if (!CheckIRP(IRPosition::value(*VAC.getValue())))
2676 return indicatePessimisticFixpoint();
2677
2678 return ChangeStatus::UNCHANGED;
2679 }
2680
2681 /// See AbstractAttribute::trackStatistics()
2682 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
2683};
2684
2685/// NonNull attribute for function return value.
2686struct AANonNullReturned final
2687 : AAReturnedFromReturnedValues<AANonNull, AANonNull, AANonNull::StateType,
2688 false, AANonNull::IRAttributeKind, false> {
2689 AANonNullReturned(const IRPosition &IRP, Attributor &A)
2690 : AAReturnedFromReturnedValues<AANonNull, AANonNull, AANonNull::StateType,
2691 false, Attribute::NonNull, false>(IRP, A) {
2692 }
2693
2694 /// See AbstractAttribute::getAsStr().
2695 const std::string getAsStr(Attributor *A) const override {
2696 return getAssumed() ? "nonnull" : "may-null";
2697 }
2698
2699 /// See AbstractAttribute::trackStatistics()
2700 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
2701};
2702
2703/// NonNull attribute for function argument.
2704struct AANonNullArgument final
2705 : AAArgumentFromCallSiteArguments<AANonNull, AANonNullImpl> {
2706 AANonNullArgument(const IRPosition &IRP, Attributor &A)
2707 : AAArgumentFromCallSiteArguments<AANonNull, AANonNullImpl>(IRP, A) {}
2708
2709 /// See AbstractAttribute::trackStatistics()
2710 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nonnull) }
2711};
2712
2713struct AANonNullCallSiteArgument final : AANonNullFloating {
2714 AANonNullCallSiteArgument(const IRPosition &IRP, Attributor &A)
2715 : AANonNullFloating(IRP, A) {}
2716
2717 /// See AbstractAttribute::trackStatistics()
2718 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(nonnull) }
2719};
2720
2721/// NonNull attribute for a call site return position.
2722struct AANonNullCallSiteReturned final
2723 : AACalleeToCallSite<AANonNull, AANonNullImpl> {
2724 AANonNullCallSiteReturned(const IRPosition &IRP, Attributor &A)
2725 : AACalleeToCallSite<AANonNull, AANonNullImpl>(IRP, A) {}
2726
2727 /// See AbstractAttribute::trackStatistics()
2728 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(nonnull) }
2729};
2730} // namespace
2731
2732/// ------------------------ Must-Progress Attributes --------------------------
2733namespace {
2734struct AAMustProgressImpl : public AAMustProgress {
2735 AAMustProgressImpl(const IRPosition &IRP, Attributor &A)
2736 : AAMustProgress(IRP, A) {}
2737
2738 /// See AbstractAttribute::initialize(...).
2739 void initialize(Attributor &A) override {
2740 bool IsKnown;
2742 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
2743 (void)IsKnown;
2744 }
2745
2746 /// See AbstractAttribute::getAsStr()
2747 const std::string getAsStr(Attributor *A) const override {
2748 return getAssumed() ? "mustprogress" : "may-not-progress";
2749 }
2750};
2751
2752struct AAMustProgressFunction final : AAMustProgressImpl {
2753 AAMustProgressFunction(const IRPosition &IRP, Attributor &A)
2754 : AAMustProgressImpl(IRP, A) {}
2755
2756 /// See AbstractAttribute::updateImpl(...).
2757 ChangeStatus updateImpl(Attributor &A) override {
2758 bool IsKnown;
2760 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnown)) {
2761 if (IsKnown)
2762 return indicateOptimisticFixpoint();
2763 return ChangeStatus::UNCHANGED;
2764 }
2765
2766 auto CheckForMustProgress = [&](AbstractCallSite ACS) {
2767 IRPosition IPos = IRPosition::callsite_function(*ACS.getInstruction());
2768 bool IsKnownMustProgress;
2770 A, this, IPos, DepClassTy::REQUIRED, IsKnownMustProgress,
2771 /* IgnoreSubsumingPositions */ true);
2772 };
2773
2774 bool AllCallSitesKnown = true;
2775 if (!A.checkForAllCallSites(CheckForMustProgress, *this,
2776 /* RequireAllCallSites */ true,
2777 AllCallSitesKnown))
2778 return indicatePessimisticFixpoint();
2779
2780 return ChangeStatus::UNCHANGED;
2781 }
2782
2783 /// See AbstractAttribute::trackStatistics()
2784 void trackStatistics() const override {
2785 STATS_DECLTRACK_FN_ATTR(mustprogress)
2786 }
2787};
2788
2789/// MustProgress attribute deduction for a call sites.
2790struct AAMustProgressCallSite final : AAMustProgressImpl {
2791 AAMustProgressCallSite(const IRPosition &IRP, Attributor &A)
2792 : AAMustProgressImpl(IRP, A) {}
2793
2794 /// See AbstractAttribute::updateImpl(...).
2795 ChangeStatus updateImpl(Attributor &A) override {
2796 // TODO: Once we have call site specific value information we can provide
2797 // call site specific liveness information and then it makes
2798 // sense to specialize attributes for call sites arguments instead of
2799 // redirecting requests to the callee argument.
2800 const IRPosition &FnPos = IRPosition::function(*getAnchorScope());
2801 bool IsKnownMustProgress;
2803 A, this, FnPos, DepClassTy::REQUIRED, IsKnownMustProgress))
2804 return indicatePessimisticFixpoint();
2805 return ChangeStatus::UNCHANGED;
2806 }
2807
2808 /// See AbstractAttribute::trackStatistics()
2809 void trackStatistics() const override {
2810 STATS_DECLTRACK_CS_ATTR(mustprogress);
2811 }
2812};
2813} // namespace
2814
2815/// ------------------------ No-Recurse Attributes ----------------------------
2816
2817namespace {
2818struct AANoRecurseImpl : public AANoRecurse {
2819 AANoRecurseImpl(const IRPosition &IRP, Attributor &A) : AANoRecurse(IRP, A) {}
2820
2821 /// See AbstractAttribute::initialize(...).
2822 void initialize(Attributor &A) override {
2823 bool IsKnown;
2825 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
2826 (void)IsKnown;
2827 }
2828
2829 /// See AbstractAttribute::getAsStr()
2830 const std::string getAsStr(Attributor *A) const override {
2831 return getAssumed() ? "norecurse" : "may-recurse";
2832 }
2833};
2834
2835struct AANoRecurseFunction final : AANoRecurseImpl {
2836 AANoRecurseFunction(const IRPosition &IRP, Attributor &A)
2837 : AANoRecurseImpl(IRP, A) {}
2838
2839 /// See AbstractAttribute::updateImpl(...).
2840 ChangeStatus updateImpl(Attributor &A) override {
2841
2842 // If all live call sites are known to be no-recurse, we are as well.
2843 auto CallSitePred = [&](AbstractCallSite ACS) {
2844 bool IsKnownNoRecurse;
2846 A, this,
2847 IRPosition::function(*ACS.getInstruction()->getFunction()),
2848 DepClassTy::NONE, IsKnownNoRecurse))
2849 return false;
2850 return IsKnownNoRecurse;
2851 };
2852 bool UsedAssumedInformation = false;
2853 if (A.checkForAllCallSites(CallSitePred, *this, true,
2854 UsedAssumedInformation)) {
2855 // If we know all call sites and all are known no-recurse, we are done.
2856 // If all known call sites, which might not be all that exist, are known
2857 // to be no-recurse, we are not done but we can continue to assume
2858 // no-recurse. If one of the call sites we have not visited will become
2859 // live, another update is triggered.
2860 if (!UsedAssumedInformation)
2861 indicateOptimisticFixpoint();
2862 return ChangeStatus::UNCHANGED;
2863 }
2864
2865 const AAInterFnReachability *EdgeReachability =
2866 A.getAAFor<AAInterFnReachability>(*this, getIRPosition(),
2867 DepClassTy::REQUIRED);
2868 if (EdgeReachability && EdgeReachability->canReach(A, *getAnchorScope()))
2869 return indicatePessimisticFixpoint();
2870 return ChangeStatus::UNCHANGED;
2871 }
2872
2873 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(norecurse) }
2874};
2875
2876/// NoRecurse attribute deduction for a call sites.
2877struct AANoRecurseCallSite final
2878 : AACalleeToCallSite<AANoRecurse, AANoRecurseImpl> {
2879 AANoRecurseCallSite(const IRPosition &IRP, Attributor &A)
2880 : AACalleeToCallSite<AANoRecurse, AANoRecurseImpl>(IRP, A) {}
2881
2882 /// See AbstractAttribute::trackStatistics()
2883 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(norecurse); }
2884};
2885} // namespace
2886
2887/// ------------------------ No-Convergent Attribute --------------------------
2888
2889namespace {
2890struct AANonConvergentImpl : public AANonConvergent {
2891 AANonConvergentImpl(const IRPosition &IRP, Attributor &A)
2892 : AANonConvergent(IRP, A) {}
2893
2894 /// See AbstractAttribute::getAsStr()
2895 const std::string getAsStr(Attributor *A) const override {
2896 return getAssumed() ? "non-convergent" : "may-be-convergent";
2897 }
2898};
2899
2900struct AANonConvergentFunction final : AANonConvergentImpl {
2901 AANonConvergentFunction(const IRPosition &IRP, Attributor &A)
2902 : AANonConvergentImpl(IRP, A) {}
2903
2904 /// See AbstractAttribute::updateImpl(...).
2905 ChangeStatus updateImpl(Attributor &A) override {
2906 // If all function calls are known to not be convergent, we are not
2907 // convergent.
2908 auto CalleeIsNotConvergent = [&](Instruction &Inst) {
2909 CallBase &CB = cast<CallBase>(Inst);
2911 if (!Callee || Callee->isIntrinsic()) {
2912 return false;
2913 }
2914 if (Callee->isDeclaration()) {
2915 return !Callee->hasFnAttribute(Attribute::Convergent);
2916 }
2917 const auto *ConvergentAA = A.getAAFor<AANonConvergent>(
2918 *this, IRPosition::function(*Callee), DepClassTy::REQUIRED);
2919 return ConvergentAA && ConvergentAA->isAssumedNotConvergent();
2920 };
2921
2922 bool UsedAssumedInformation = false;
2923 if (!A.checkForAllCallLikeInstructions(CalleeIsNotConvergent, *this,
2924 UsedAssumedInformation)) {
2925 return indicatePessimisticFixpoint();
2926 }
2927 return ChangeStatus::UNCHANGED;
2928 }
2929
2930 ChangeStatus manifest(Attributor &A) override {
2931 if (isKnownNotConvergent() &&
2932 A.hasAttr(getIRPosition(), Attribute::Convergent)) {
2933 A.removeAttrs(getIRPosition(), {Attribute::Convergent});
2934 return ChangeStatus::CHANGED;
2935 }
2936 return ChangeStatus::UNCHANGED;
2937 }
2938
2939 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(convergent) }
2940};
2941} // namespace
2942
2943/// -------------------- Undefined-Behavior Attributes ------------------------
2944
2945namespace {
2946struct AAUndefinedBehaviorImpl : public AAUndefinedBehavior {
2947 AAUndefinedBehaviorImpl(const IRPosition &IRP, Attributor &A)
2948 : AAUndefinedBehavior(IRP, A) {}
2949
2950 /// See AbstractAttribute::updateImpl(...).
2951 // through a pointer (i.e. also branches etc.)
2952 ChangeStatus updateImpl(Attributor &A) override {
2953 const size_t UBPrevSize = KnownUBInsts.size();
2954 const size_t NoUBPrevSize = AssumedNoUBInsts.size();
2955
2956 auto InspectMemAccessInstForUB = [&](Instruction &I) {
2957 // Volatile accesses on null are not necessarily UB.
2958 if (I.isVolatile())
2959 return true;
2960
2961 // Skip instructions that are already saved.
2962 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
2963 return true;
2964
2965 // If we reach here, we know we have an instruction
2966 // that accesses memory through a pointer operand,
2967 // for which getPointerOperand() should give it to us.
2968 Value *PtrOp =
2969 const_cast<Value *>(getPointerOperand(&I, /* AllowVolatile */ true));
2970 assert(PtrOp &&
2971 "Expected pointer operand of memory accessing instruction");
2972
2973 // Either we stopped and the appropriate action was taken,
2974 // or we got back a simplified value to continue.
2975 std::optional<Value *> SimplifiedPtrOp =
2976 stopOnUndefOrAssumed(A, PtrOp, &I);
2977 if (!SimplifiedPtrOp || !*SimplifiedPtrOp)
2978 return true;
2979 const Value *PtrOpVal = *SimplifiedPtrOp;
2980
2981 // A memory access through a pointer is considered UB
2982 // only if the pointer has constant null value.
2983 // TODO: Expand it to not only check constant values.
2984 if (!isa<ConstantPointerNull>(PtrOpVal)) {
2985 AssumedNoUBInsts.insert(&I);
2986 return true;
2987 }
2988 const Type *PtrTy = PtrOpVal->getType();
2989
2990 // Because we only consider instructions inside functions,
2991 // assume that a parent function exists.
2992 const Function *F = I.getFunction();
2993
2994 // A memory access using constant null pointer is only considered UB
2995 // if null pointer is _not_ defined for the target platform.
2997 AssumedNoUBInsts.insert(&I);
2998 else
2999 KnownUBInsts.insert(&I);
3000 return true;
3001 };
3002
3003 auto InspectBrInstForUB = [&](Instruction &I) {
3004 // A conditional branch instruction is considered UB if it has `undef`
3005 // condition.
3006
3007 // Skip instructions that are already saved.
3008 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
3009 return true;
3010
3011 // We know we have a branch instruction.
3012 auto *BrInst = cast<CondBrInst>(&I);
3013
3014 // Either we stopped and the appropriate action was taken,
3015 // or we got back a simplified value to continue.
3016 std::optional<Value *> SimplifiedCond =
3017 stopOnUndefOrAssumed(A, BrInst->getCondition(), BrInst);
3018 if (!SimplifiedCond || !*SimplifiedCond)
3019 return true;
3020 AssumedNoUBInsts.insert(&I);
3021 return true;
3022 };
3023
3024 auto InspectCallSiteForUB = [&](Instruction &I) {
3025 // Check whether a callsite always cause UB or not
3026
3027 // Skip instructions that are already saved.
3028 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
3029 return true;
3030
3031 // Check nonnull and noundef argument attribute violation for each
3032 // callsite.
3033 CallBase &CB = cast<CallBase>(I);
3035 if (!Callee)
3036 return true;
3037 for (unsigned idx = 0; idx < CB.arg_size(); idx++) {
3038 // If current argument is known to be simplified to null pointer and the
3039 // corresponding argument position is known to have nonnull attribute,
3040 // the argument is poison. Furthermore, if the argument is poison and
3041 // the position is known to have noundef attriubte, this callsite is
3042 // considered UB.
3043 if (idx >= Callee->arg_size())
3044 break;
3045 Value *ArgVal = CB.getArgOperand(idx);
3046 if (!ArgVal)
3047 continue;
3048 // Here, we handle three cases.
3049 // (1) Not having a value means it is dead. (we can replace the value
3050 // with undef)
3051 // (2) Simplified to undef. The argument violate noundef attriubte.
3052 // (3) Simplified to null pointer where known to be nonnull.
3053 // The argument is a poison value and violate noundef attribute.
3054 IRPosition CalleeArgumentIRP = IRPosition::callsite_argument(CB, idx);
3055 bool IsKnownNoUndef;
3057 A, this, CalleeArgumentIRP, DepClassTy::NONE, IsKnownNoUndef);
3058 if (!IsKnownNoUndef)
3059 continue;
3060 bool UsedAssumedInformation = false;
3061 std::optional<Value *> SimplifiedVal =
3062 A.getAssumedSimplified(IRPosition::value(*ArgVal), *this,
3063 UsedAssumedInformation, AA::Interprocedural);
3064 if (UsedAssumedInformation)
3065 continue;
3066 if (SimplifiedVal && !*SimplifiedVal)
3067 return true;
3068 if (!SimplifiedVal || isa<UndefValue>(**SimplifiedVal)) {
3069 KnownUBInsts.insert(&I);
3070 continue;
3071 }
3072 if (!ArgVal->getType()->isPointerTy() ||
3073 !isa<ConstantPointerNull>(**SimplifiedVal))
3074 continue;
3075 bool IsKnownNonNull;
3077 A, this, CalleeArgumentIRP, DepClassTy::NONE, IsKnownNonNull);
3078 if (IsKnownNonNull)
3079 KnownUBInsts.insert(&I);
3080 }
3081 return true;
3082 };
3083
3084 auto InspectReturnInstForUB = [&](Instruction &I) {
3085 auto &RI = cast<ReturnInst>(I);
3086 // Either we stopped and the appropriate action was taken,
3087 // or we got back a simplified return value to continue.
3088 std::optional<Value *> SimplifiedRetValue =
3089 stopOnUndefOrAssumed(A, RI.getReturnValue(), &I);
3090 if (!SimplifiedRetValue || !*SimplifiedRetValue)
3091 return true;
3092
3093 // Check if a return instruction always cause UB or not
3094 // Note: It is guaranteed that the returned position of the anchor
3095 // scope has noundef attribute when this is called.
3096 // We also ensure the return position is not "assumed dead"
3097 // because the returned value was then potentially simplified to
3098 // `undef` in AAReturnedValues without removing the `noundef`
3099 // attribute yet.
3100
3101 // When the returned position has noundef attriubte, UB occurs in the
3102 // following cases.
3103 // (1) Returned value is known to be undef.
3104 // (2) The value is known to be a null pointer and the returned
3105 // position has nonnull attribute (because the returned value is
3106 // poison).
3107 if (isa<ConstantPointerNull>(*SimplifiedRetValue)) {
3108 bool IsKnownNonNull;
3110 A, this, IRPosition::returned(*getAnchorScope()), DepClassTy::NONE,
3111 IsKnownNonNull);
3112 if (IsKnownNonNull)
3113 KnownUBInsts.insert(&I);
3114 }
3115
3116 return true;
3117 };
3118
3119 bool UsedAssumedInformation = false;
3120 A.checkForAllInstructions(InspectMemAccessInstForUB, *this,
3121 {Instruction::Load, Instruction::Store,
3122 Instruction::AtomicCmpXchg,
3123 Instruction::AtomicRMW},
3124 UsedAssumedInformation,
3125 /* CheckBBLivenessOnly */ true);
3126 A.checkForAllInstructions(InspectBrInstForUB, *this, {Instruction::CondBr},
3127 UsedAssumedInformation,
3128 /* CheckBBLivenessOnly */ true);
3129 A.checkForAllCallLikeInstructions(InspectCallSiteForUB, *this,
3130 UsedAssumedInformation);
3131
3132 // If the returned position of the anchor scope has noundef attriubte, check
3133 // all returned instructions.
3134 if (!getAnchorScope()->getReturnType()->isVoidTy()) {
3135 const IRPosition &ReturnIRP = IRPosition::returned(*getAnchorScope());
3136 if (!A.isAssumedDead(ReturnIRP, this, nullptr, UsedAssumedInformation)) {
3137 bool IsKnownNoUndef;
3139 A, this, ReturnIRP, DepClassTy::NONE, IsKnownNoUndef);
3140 if (IsKnownNoUndef)
3141 A.checkForAllInstructions(InspectReturnInstForUB, *this,
3142 {Instruction::Ret}, UsedAssumedInformation,
3143 /* CheckBBLivenessOnly */ true);
3144 }
3145 }
3146
3147 if (NoUBPrevSize != AssumedNoUBInsts.size() ||
3148 UBPrevSize != KnownUBInsts.size())
3149 return ChangeStatus::CHANGED;
3150 return ChangeStatus::UNCHANGED;
3151 }
3152
3153 bool isKnownToCauseUB(Instruction *I) const override {
3154 return KnownUBInsts.count(I);
3155 }
3156
3157 bool isAssumedToCauseUB(Instruction *I) const override {
3158 // In simple words, if an instruction is not in the assumed to _not_
3159 // cause UB, then it is assumed UB (that includes those
3160 // in the KnownUBInsts set). The rest is boilerplate
3161 // is to ensure that it is one of the instructions we test
3162 // for UB.
3163
3164 switch (I->getOpcode()) {
3165 case Instruction::Load:
3166 case Instruction::Store:
3167 case Instruction::AtomicCmpXchg:
3168 case Instruction::AtomicRMW:
3169 case Instruction::CondBr:
3170 return !AssumedNoUBInsts.count(I);
3171 default:
3172 return false;
3173 }
3174 return false;
3175 }
3176
3177 ChangeStatus manifest(Attributor &A) override {
3178 if (KnownUBInsts.empty())
3179 return ChangeStatus::UNCHANGED;
3180 for (Instruction *I : KnownUBInsts)
3181 A.changeToUnreachableAfterManifest(I);
3182 return ChangeStatus::CHANGED;
3183 }
3184
3185 /// See AbstractAttribute::getAsStr()
3186 const std::string getAsStr(Attributor *A) const override {
3187 return getAssumed() ? "undefined-behavior" : "no-ub";
3188 }
3189
3190 /// Note: The correctness of this analysis depends on the fact that the
3191 /// following 2 sets will stop changing after some point.
3192 /// "Change" here means that their size changes.
3193 /// The size of each set is monotonically increasing
3194 /// (we only add items to them) and it is upper bounded by the number of
3195 /// instructions in the processed function (we can never save more
3196 /// elements in either set than this number). Hence, at some point,
3197 /// they will stop increasing.
3198 /// Consequently, at some point, both sets will have stopped
3199 /// changing, effectively making the analysis reach a fixpoint.
3200
3201 /// Note: These 2 sets are disjoint and an instruction can be considered
3202 /// one of 3 things:
3203 /// 1) Known to cause UB (AAUndefinedBehavior could prove it) and put it in
3204 /// the KnownUBInsts set.
3205 /// 2) Assumed to cause UB (in every updateImpl, AAUndefinedBehavior
3206 /// has a reason to assume it).
3207 /// 3) Assumed to not cause UB. very other instruction - AAUndefinedBehavior
3208 /// could not find a reason to assume or prove that it can cause UB,
3209 /// hence it assumes it doesn't. We have a set for these instructions
3210 /// so that we don't reprocess them in every update.
3211 /// Note however that instructions in this set may cause UB.
3212
3213protected:
3214 /// A set of all live instructions _known_ to cause UB.
3215 SmallPtrSet<Instruction *, 8> KnownUBInsts;
3216
3217private:
3218 /// A set of all the (live) instructions that are assumed to _not_ cause UB.
3219 SmallPtrSet<Instruction *, 8> AssumedNoUBInsts;
3220
3221 // Should be called on updates in which if we're processing an instruction
3222 // \p I that depends on a value \p V, one of the following has to happen:
3223 // - If the value is assumed, then stop.
3224 // - If the value is known but undef, then consider it UB.
3225 // - Otherwise, do specific processing with the simplified value.
3226 // We return std::nullopt in the first 2 cases to signify that an appropriate
3227 // action was taken and the caller should stop.
3228 // Otherwise, we return the simplified value that the caller should
3229 // use for specific processing.
3230 std::optional<Value *> stopOnUndefOrAssumed(Attributor &A, Value *V,
3231 Instruction *I) {
3232 bool UsedAssumedInformation = false;
3233 std::optional<Value *> SimplifiedV =
3234 A.getAssumedSimplified(IRPosition::value(*V), *this,
3235 UsedAssumedInformation, AA::Interprocedural);
3236 if (!UsedAssumedInformation) {
3237 // Don't depend on assumed values.
3238 if (!SimplifiedV) {
3239 // If it is known (which we tested above) but it doesn't have a value,
3240 // then we can assume `undef` and hence the instruction is UB.
3241 KnownUBInsts.insert(I);
3242 return std::nullopt;
3243 }
3244 if (!*SimplifiedV)
3245 return nullptr;
3246 V = *SimplifiedV;
3247 }
3248 if (isa<UndefValue>(V)) {
3249 KnownUBInsts.insert(I);
3250 return std::nullopt;
3251 }
3252 return V;
3253 }
3254};
3255
3256struct AAUndefinedBehaviorFunction final : AAUndefinedBehaviorImpl {
3257 AAUndefinedBehaviorFunction(const IRPosition &IRP, Attributor &A)
3258 : AAUndefinedBehaviorImpl(IRP, A) {}
3259
3260 /// See AbstractAttribute::trackStatistics()
3261 void trackStatistics() const override {
3262 STATS_DECL(UndefinedBehaviorInstruction, Instruction,
3263 "Number of instructions known to have UB");
3264 BUILD_STAT_NAME(UndefinedBehaviorInstruction, Instruction) +=
3265 KnownUBInsts.size();
3266 }
3267};
3268} // namespace
3269
3270/// ------------------------ Will-Return Attributes ----------------------------
3271
3272namespace {
3273// Helper function that checks whether a function has any cycle which we don't
3274// know if it is bounded or not.
3275// Loops with maximum trip count are considered bounded, any other cycle not.
3276static bool mayContainUnboundedCycle(Function &F, Attributor &A) {
3277 ScalarEvolution *SE =
3278 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(F);
3279 LoopInfo *LI = A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(F);
3280 // If either SCEV or LoopInfo is not available for the function then we assume
3281 // any cycle to be unbounded cycle.
3282 // We use scc_iterator which uses Tarjan algorithm to find all the maximal
3283 // SCCs.To detect if there's a cycle, we only need to find the maximal ones.
3284 if (!SE || !LI) {
3285 for (scc_iterator<Function *> SCCI = scc_begin(&F); !SCCI.isAtEnd(); ++SCCI)
3286 if (SCCI.hasCycle())
3287 return true;
3288 return false;
3289 }
3290
3291 // If there's irreducible control, the function may contain non-loop cycles.
3293 return true;
3294
3295 // Any loop that does not have a max trip count is considered unbounded cycle.
3296 for (auto *L : LI->getLoopsInPreorder()) {
3297 if (!SE->getSmallConstantMaxTripCount(L))
3298 return true;
3299 }
3300 return false;
3301}
3302
3303struct AAWillReturnImpl : public AAWillReturn {
3304 AAWillReturnImpl(const IRPosition &IRP, Attributor &A)
3305 : AAWillReturn(IRP, A) {}
3306
3307 /// See AbstractAttribute::initialize(...).
3308 void initialize(Attributor &A) override {
3309 bool IsKnown;
3311 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
3312 (void)IsKnown;
3313 }
3314
3315 /// Check for `mustprogress` and `readonly` as they imply `willreturn`.
3316 bool isImpliedByMustprogressAndReadonly(Attributor &A, bool KnownOnly) {
3317 if (!A.hasAttr(getIRPosition(), {Attribute::MustProgress}))
3318 return false;
3319
3320 bool IsKnown;
3321 if (AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown))
3322 return IsKnown || !KnownOnly;
3323 return false;
3324 }
3325
3326 /// See AbstractAttribute::updateImpl(...).
3327 ChangeStatus updateImpl(Attributor &A) override {
3328 if (isImpliedByMustprogressAndReadonly(A, /* KnownOnly */ false))
3329 return ChangeStatus::UNCHANGED;
3330
3331 auto CheckForWillReturn = [&](Instruction &I) {
3333 bool IsKnown;
3335 A, this, IPos, DepClassTy::REQUIRED, IsKnown)) {
3336 if (IsKnown)
3337 return true;
3338 } else {
3339 return false;
3340 }
3341 bool IsKnownNoRecurse;
3343 A, this, IPos, DepClassTy::REQUIRED, IsKnownNoRecurse);
3344 };
3345
3346 bool UsedAssumedInformation = false;
3347 if (!A.checkForAllCallLikeInstructions(CheckForWillReturn, *this,
3348 UsedAssumedInformation))
3349 return indicatePessimisticFixpoint();
3350
3351 auto CheckForVolatile = [&](Instruction &I) {
3352 // Volatile operations are not willreturn.
3353 return !I.isVolatile();
3354 };
3355 if (!A.checkForAllInstructions(CheckForVolatile, *this,
3356 {Instruction::Load, Instruction::Store,
3357 Instruction::AtomicCmpXchg,
3358 Instruction::AtomicRMW},
3359 UsedAssumedInformation))
3360 return indicatePessimisticFixpoint();
3361
3362 return ChangeStatus::UNCHANGED;
3363 }
3364
3365 /// See AbstractAttribute::getAsStr()
3366 const std::string getAsStr(Attributor *A) const override {
3367 return getAssumed() ? "willreturn" : "may-noreturn";
3368 }
3369};
3370
3371struct AAWillReturnFunction final : AAWillReturnImpl {
3372 AAWillReturnFunction(const IRPosition &IRP, Attributor &A)
3373 : AAWillReturnImpl(IRP, A) {}
3374
3375 /// See AbstractAttribute::initialize(...).
3376 void initialize(Attributor &A) override {
3377 AAWillReturnImpl::initialize(A);
3378
3379 Function *F = getAnchorScope();
3380 assert(F && "Did expect an anchor function");
3381 if (F->isDeclaration() || mayContainUnboundedCycle(*F, A))
3382 indicatePessimisticFixpoint();
3383 }
3384
3385 /// See AbstractAttribute::trackStatistics()
3386 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(willreturn) }
3387};
3388
3389/// WillReturn attribute deduction for a call sites.
3390struct AAWillReturnCallSite final
3391 : AACalleeToCallSite<AAWillReturn, AAWillReturnImpl> {
3392 AAWillReturnCallSite(const IRPosition &IRP, Attributor &A)
3393 : AACalleeToCallSite<AAWillReturn, AAWillReturnImpl>(IRP, A) {}
3394
3395 /// See AbstractAttribute::updateImpl(...).
3396 ChangeStatus updateImpl(Attributor &A) override {
3397 if (isImpliedByMustprogressAndReadonly(A, /* KnownOnly */ false))
3398 return ChangeStatus::UNCHANGED;
3399
3400 return AACalleeToCallSite::updateImpl(A);
3401 }
3402
3403 /// See AbstractAttribute::trackStatistics()
3404 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(willreturn); }
3405};
3406} // namespace
3407
3408/// -------------------AAIntraFnReachability Attribute--------------------------
3409
3410/// All information associated with a reachability query. This boilerplate code
3411/// is used by both AAIntraFnReachability and AAInterFnReachability, with
3412/// different \p ToTy values.
3413template <typename ToTy> struct ReachabilityQueryInfo {
3414 enum class Reachable {
3417 };
3418
3419 /// Start here,
3420 const Instruction *From = nullptr;
3421 /// reach this place,
3422 const ToTy *To = nullptr;
3423 /// without going through any of these instructions,
3425 /// and remember if it worked:
3427
3428 /// Precomputed hash for this RQI.
3429 unsigned Hash = 0;
3430
3431 unsigned computeHashValue() const {
3432 assert(Hash == 0 && "Computed hash twice!");
3435 return const_cast<ReachabilityQueryInfo<ToTy> *>(this)->Hash =
3436 detail::combineHashValue(PairDMI ::getHashValue({From, To}),
3437 InstSetDMI::getHashValue(ExclusionSet));
3438 }
3439
3441 : From(From), To(To) {}
3442
3443 /// Constructor replacement to ensure unique and stable sets are used for the
3444 /// cache.
3446 const AA::InstExclusionSetTy *ES, bool MakeUnique)
3447 : From(&From), To(&To), ExclusionSet(ES) {
3448
3449 if (!ES || ES->empty()) {
3450 ExclusionSet = nullptr;
3451 } else if (MakeUnique) {
3452 ExclusionSet = A.getInfoCache().getOrCreateUniqueBlockExecutionSet(ES);
3453 }
3454 }
3455
3458};
3459
3460namespace llvm {
3461template <typename ToTy> struct DenseMapInfo<ReachabilityQueryInfo<ToTy> *> {
3464
3465 static unsigned getHashValue(const ReachabilityQueryInfo<ToTy> *RQI) {
3466 return RQI->Hash ? RQI->Hash : RQI->computeHashValue();
3467 }
3468 static bool isEqual(const ReachabilityQueryInfo<ToTy> *LHS,
3469 const ReachabilityQueryInfo<ToTy> *RHS) {
3470 if (!PairDMI::isEqual({LHS->From, LHS->To}, {RHS->From, RHS->To}))
3471 return false;
3472 return InstSetDMI::isEqual(LHS->ExclusionSet, RHS->ExclusionSet);
3473 }
3474};
3475
3476} // namespace llvm
3477
3478namespace {
3479
3480template <typename BaseTy, typename ToTy>
3481struct CachedReachabilityAA : public BaseTy {
3482 using RQITy = ReachabilityQueryInfo<ToTy>;
3483
3484 CachedReachabilityAA(const IRPosition &IRP, Attributor &A) : BaseTy(IRP, A) {}
3485
3486 /// See AbstractAttribute::isQueryAA.
3487 bool isQueryAA() const override { return true; }
3488
3489 /// See AbstractAttribute::updateImpl(...).
3490 ChangeStatus updateImpl(Attributor &A) override {
3491 ChangeStatus Changed = ChangeStatus::UNCHANGED;
3492 for (unsigned u = 0, e = QueryVector.size(); u < e; ++u) {
3493 RQITy *RQI = QueryVector[u];
3494 if (RQI->Result == RQITy::Reachable::No &&
3495 isReachableImpl(A, *RQI, /*IsTemporaryRQI=*/false))
3496 Changed = ChangeStatus::CHANGED;
3497 }
3498 return Changed;
3499 }
3500
3501 virtual bool isReachableImpl(Attributor &A, RQITy &RQI,
3502 bool IsTemporaryRQI) = 0;
3503
3504 bool rememberResult(Attributor &A, typename RQITy::Reachable Result,
3505 RQITy &RQI, bool UsedExclusionSet, bool IsTemporaryRQI) {
3506 RQI.Result = Result;
3507
3508 // Remove the temporary RQI from the cache.
3509 if (IsTemporaryRQI)
3510 QueryCache.erase(&RQI);
3511
3512 // Insert a plain RQI (w/o exclusion set) if that makes sense. Two options:
3513 // 1) If it is reachable, it doesn't matter if we have an exclusion set for
3514 // this query. 2) We did not use the exclusion set, potentially because
3515 // there is none.
3516 if (Result == RQITy::Reachable::Yes || !UsedExclusionSet) {
3517 RQITy PlainRQI(RQI.From, RQI.To);
3518 if (!QueryCache.count(&PlainRQI)) {
3519 RQITy *RQIPtr = new (A.Allocator) RQITy(RQI.From, RQI.To);
3520 RQIPtr->Result = Result;
3521 QueryVector.push_back(RQIPtr);
3522 QueryCache.insert(RQIPtr);
3523 }
3524 }
3525
3526 // Check if we need to insert a new permanent RQI with the exclusion set.
3527 if (IsTemporaryRQI && Result != RQITy::Reachable::Yes && UsedExclusionSet) {
3528 assert((!RQI.ExclusionSet || !RQI.ExclusionSet->empty()) &&
3529 "Did not expect empty set!");
3530 RQITy *RQIPtr = new (A.Allocator)
3531 RQITy(A, *RQI.From, *RQI.To, RQI.ExclusionSet, true);
3532 assert(RQIPtr->Result == RQITy::Reachable::No && "Already reachable?");
3533 RQIPtr->Result = Result;
3534 assert(!QueryCache.count(RQIPtr));
3535 QueryVector.push_back(RQIPtr);
3536 QueryCache.insert(RQIPtr);
3537 }
3538
3539 if (Result == RQITy::Reachable::No && IsTemporaryRQI)
3540 A.registerForUpdate(*this);
3541 return Result == RQITy::Reachable::Yes;
3542 }
3543
3544 const std::string getAsStr(Attributor *A) const override {
3545 // TODO: Return the number of reachable queries.
3546 return "#queries(" + std::to_string(QueryVector.size()) + ")";
3547 }
3548
3549 bool checkQueryCache(Attributor &A, RQITy &StackRQI,
3550 typename RQITy::Reachable &Result) {
3551 if (!this->getState().isValidState()) {
3552 Result = RQITy::Reachable::Yes;
3553 return true;
3554 }
3555
3556 // If we have an exclusion set we might be able to find our answer by
3557 // ignoring it first.
3558 if (StackRQI.ExclusionSet) {
3559 RQITy PlainRQI(StackRQI.From, StackRQI.To);
3560 auto It = QueryCache.find(&PlainRQI);
3561 if (It != QueryCache.end() && (*It)->Result == RQITy::Reachable::No) {
3562 Result = RQITy::Reachable::No;
3563 return true;
3564 }
3565 }
3566
3567 auto It = QueryCache.find(&StackRQI);
3568 if (It != QueryCache.end()) {
3569 Result = (*It)->Result;
3570 return true;
3571 }
3572
3573 // Insert a temporary for recursive queries. We will replace it with a
3574 // permanent entry later.
3575 QueryCache.insert(&StackRQI);
3576 return false;
3577 }
3578
3579private:
3580 SmallVector<RQITy *> QueryVector;
3581 DenseSet<RQITy *> QueryCache;
3582};
3583
3584struct AAIntraFnReachabilityFunction final
3585 : public CachedReachabilityAA<AAIntraFnReachability, Instruction> {
3586 using Base = CachedReachabilityAA<AAIntraFnReachability, Instruction>;
3587 AAIntraFnReachabilityFunction(const IRPosition &IRP, Attributor &A)
3588 : Base(IRP, A) {
3589 DT = A.getInfoCache().getAnalysisResultForFunction<DominatorTreeAnalysis>(
3590 *IRP.getAssociatedFunction());
3591 }
3592
3593 bool isAssumedReachable(
3594 Attributor &A, const Instruction &From, const Instruction &To,
3595 const AA::InstExclusionSetTy *ExclusionSet) const override {
3596 auto *NonConstThis = const_cast<AAIntraFnReachabilityFunction *>(this);
3597 if (&From == &To)
3598 return true;
3599
3600 RQITy StackRQI(A, From, To, ExclusionSet, false);
3601 RQITy::Reachable Result;
3602 if (!NonConstThis->checkQueryCache(A, StackRQI, Result))
3603 return NonConstThis->isReachableImpl(A, StackRQI,
3604 /*IsTemporaryRQI=*/true);
3605 return Result == RQITy::Reachable::Yes;
3606 }
3607
3608 ChangeStatus updateImpl(Attributor &A) override {
3609 // We only depend on liveness. DeadEdges is all we care about, check if any
3610 // of them changed.
3611 auto *LivenessAA =
3612 A.getAAFor<AAIsDead>(*this, getIRPosition(), DepClassTy::OPTIONAL);
3613 if (LivenessAA &&
3614 llvm::all_of(DeadEdges,
3615 [&](const auto &DeadEdge) {
3616 return LivenessAA->isEdgeDead(DeadEdge.first,
3617 DeadEdge.second);
3618 }) &&
3619 llvm::all_of(DeadBlocks, [&](const BasicBlock *BB) {
3620 return LivenessAA->isAssumedDead(BB);
3621 })) {
3622 return ChangeStatus::UNCHANGED;
3623 }
3624 DeadEdges.clear();
3625 DeadBlocks.clear();
3626 return Base::updateImpl(A);
3627 }
3628
3629 bool isReachableImpl(Attributor &A, RQITy &RQI,
3630 bool IsTemporaryRQI) override {
3631 const Instruction *Origin = RQI.From;
3632 bool UsedExclusionSet = false;
3633
3634 auto WillReachInBlock = [&](const Instruction &From, const Instruction &To,
3635 const AA::InstExclusionSetTy *ExclusionSet) {
3636 const Instruction *IP = &From;
3637 while (IP && IP != &To) {
3638 if (ExclusionSet && IP != Origin && ExclusionSet->count(IP)) {
3639 UsedExclusionSet = true;
3640 break;
3641 }
3642 IP = IP->getNextNode();
3643 }
3644 return IP == &To;
3645 };
3646
3647 const BasicBlock *FromBB = RQI.From->getParent();
3648 const BasicBlock *ToBB = RQI.To->getParent();
3649 assert(FromBB->getParent() == ToBB->getParent() &&
3650 "Not an intra-procedural query!");
3651
3652 // Check intra-block reachability, however, other reaching paths are still
3653 // possible.
3654 if (FromBB == ToBB &&
3655 WillReachInBlock(*RQI.From, *RQI.To, RQI.ExclusionSet))
3656 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
3657 IsTemporaryRQI);
3658
3659 // Check if reaching the ToBB block is sufficient or if even that would not
3660 // ensure reaching the target. In the latter case we are done.
3661 if (!WillReachInBlock(ToBB->front(), *RQI.To, RQI.ExclusionSet))
3662 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
3663 IsTemporaryRQI);
3664
3665 const Function *Fn = FromBB->getParent();
3666 SmallPtrSet<const BasicBlock *, 16> ExclusionBlocks;
3667 if (RQI.ExclusionSet)
3668 for (auto *I : *RQI.ExclusionSet)
3669 if (I->getFunction() == Fn)
3670 ExclusionBlocks.insert(I->getParent());
3671
3672 // Check if we make it out of the FromBB block at all.
3673 if (ExclusionBlocks.count(FromBB) &&
3674 !WillReachInBlock(*RQI.From, *FromBB->getTerminator(),
3675 RQI.ExclusionSet))
3676 return rememberResult(A, RQITy::Reachable::No, RQI, true, IsTemporaryRQI);
3677
3678 auto *LivenessAA =
3679 A.getAAFor<AAIsDead>(*this, getIRPosition(), DepClassTy::OPTIONAL);
3680 if (LivenessAA && LivenessAA->isAssumedDead(ToBB)) {
3681 DeadBlocks.insert(ToBB);
3682 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
3683 IsTemporaryRQI);
3684 }
3685
3686 SmallPtrSet<const BasicBlock *, 16> Visited;
3688 Worklist.push_back(FromBB);
3689
3690 DenseSet<std::pair<const BasicBlock *, const BasicBlock *>> LocalDeadEdges;
3691 while (!Worklist.empty()) {
3692 const BasicBlock *BB = Worklist.pop_back_val();
3693 if (!Visited.insert(BB).second)
3694 continue;
3695 for (const BasicBlock *SuccBB : successors(BB)) {
3696 if (LivenessAA && LivenessAA->isEdgeDead(BB, SuccBB)) {
3697 LocalDeadEdges.insert({BB, SuccBB});
3698 continue;
3699 }
3700 // We checked before if we just need to reach the ToBB block.
3701 if (SuccBB == ToBB)
3702 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
3703 IsTemporaryRQI);
3704 if (DT && ExclusionBlocks.empty() && DT->dominates(BB, ToBB))
3705 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
3706 IsTemporaryRQI);
3707
3708 if (ExclusionBlocks.count(SuccBB)) {
3709 UsedExclusionSet = true;
3710 continue;
3711 }
3712 Worklist.push_back(SuccBB);
3713 }
3714 }
3715
3716 DeadEdges.insert_range(LocalDeadEdges);
3717 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
3718 IsTemporaryRQI);
3719 }
3720
3721 /// See AbstractAttribute::trackStatistics()
3722 void trackStatistics() const override {}
3723
3724private:
3725 // Set of assumed dead blocks we used in the last query. If any changes we
3726 // update the state.
3727 DenseSet<const BasicBlock *> DeadBlocks;
3728
3729 // Set of assumed dead edges we used in the last query. If any changes we
3730 // update the state.
3731 DenseSet<std::pair<const BasicBlock *, const BasicBlock *>> DeadEdges;
3732
3733 /// The dominator tree of the function to short-circuit reasoning.
3734 const DominatorTree *DT = nullptr;
3735};
3736} // namespace
3737
3738/// ------------------------ NoAlias Argument Attribute ------------------------
3739
3741 Attribute::AttrKind ImpliedAttributeKind,
3742 bool IgnoreSubsumingPositions) {
3743 assert(ImpliedAttributeKind == Attribute::NoAlias &&
3744 "Unexpected attribute kind");
3745 Value *Val = &IRP.getAssociatedValue();
3747 if (isa<AllocaInst>(Val))
3748 return true;
3749 } else {
3750 IgnoreSubsumingPositions = true;
3751 }
3752
3753 if (isa<UndefValue>(Val))
3754 return true;
3755
3756 if (isa<ConstantPointerNull>(Val) &&
3759 return true;
3760
3761 if (A.hasAttr(IRP, {Attribute::ByVal, Attribute::NoAlias},
3762 IgnoreSubsumingPositions, Attribute::NoAlias))
3763 return true;
3764
3765 return false;
3766}
3767
3768namespace {
3769struct AANoAliasImpl : AANoAlias {
3770 AANoAliasImpl(const IRPosition &IRP, Attributor &A) : AANoAlias(IRP, A) {
3771 assert(getAssociatedType()->isPointerTy() &&
3772 "Noalias is a pointer attribute");
3773 }
3774
3775 const std::string getAsStr(Attributor *A) const override {
3776 return getAssumed() ? "noalias" : "may-alias";
3777 }
3778};
3779
3780/// NoAlias attribute for a floating value.
3781struct AANoAliasFloating final : AANoAliasImpl {
3782 AANoAliasFloating(const IRPosition &IRP, Attributor &A)
3783 : AANoAliasImpl(IRP, A) {}
3784
3785 /// See AbstractAttribute::updateImpl(...).
3786 ChangeStatus updateImpl(Attributor &A) override {
3787 // TODO: Implement this.
3788 return indicatePessimisticFixpoint();
3789 }
3790
3791 /// See AbstractAttribute::trackStatistics()
3792 void trackStatistics() const override {
3794 }
3795};
3796
3797/// NoAlias attribute for an argument.
3798struct AANoAliasArgument final
3799 : AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl> {
3800 using Base = AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl>;
3801 AANoAliasArgument(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {}
3802
3803 /// See AbstractAttribute::update(...).
3804 ChangeStatus updateImpl(Attributor &A) override {
3805 // We have to make sure no-alias on the argument does not break
3806 // synchronization when this is a callback argument, see also [1] below.
3807 // If synchronization cannot be affected, we delegate to the base updateImpl
3808 // function, otherwise we give up for now.
3809
3810 // If the function is no-sync, no-alias cannot break synchronization.
3811 bool IsKnownNoSycn;
3813 A, this, IRPosition::function_scope(getIRPosition()),
3814 DepClassTy::OPTIONAL, IsKnownNoSycn))
3815 return Base::updateImpl(A);
3816
3817 // If the argument is read-only, no-alias cannot break synchronization.
3818 bool IsKnown;
3819 if (AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown))
3820 return Base::updateImpl(A);
3821
3822 // If the argument is never passed through callbacks, no-alias cannot break
3823 // synchronization.
3824 bool UsedAssumedInformation = false;
3825 if (A.checkForAllCallSites(
3826 [](AbstractCallSite ACS) { return !ACS.isCallbackCall(); }, *this,
3827 true, UsedAssumedInformation))
3828 return Base::updateImpl(A);
3829
3830 // TODO: add no-alias but make sure it doesn't break synchronization by
3831 // introducing fake uses. See:
3832 // [1] Compiler Optimizations for OpenMP, J. Doerfert and H. Finkel,
3833 // International Workshop on OpenMP 2018,
3834 // http://compilers.cs.uni-saarland.de/people/doerfert/par_opt18.pdf
3835
3836 return indicatePessimisticFixpoint();
3837 }
3838
3839 /// See AbstractAttribute::trackStatistics()
3840 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noalias) }
3841};
3842
3843struct AANoAliasCallSiteArgument final : AANoAliasImpl {
3844 AANoAliasCallSiteArgument(const IRPosition &IRP, Attributor &A)
3845 : AANoAliasImpl(IRP, A) {}
3846
3847 /// Determine if the underlying value may alias with the call site argument
3848 /// \p OtherArgNo of \p ICS (= the underlying call site).
3849 bool mayAliasWithArgument(Attributor &A, AAResults *&AAR,
3850 const AAMemoryBehavior &MemBehaviorAA,
3851 const CallBase &CB, unsigned OtherArgNo) {
3852 // We do not need to worry about aliasing with the underlying IRP.
3853 if (this->getCalleeArgNo() == (int)OtherArgNo)
3854 return false;
3855
3856 // If it is not a pointer or pointer vector we do not alias.
3857 const Value *ArgOp = CB.getArgOperand(OtherArgNo);
3858 if (!ArgOp->getType()->isPtrOrPtrVectorTy())
3859 return false;
3860
3861 auto *CBArgMemBehaviorAA = A.getAAFor<AAMemoryBehavior>(
3862 *this, IRPosition::callsite_argument(CB, OtherArgNo), DepClassTy::NONE);
3863
3864 // If the argument is readnone, there is no read-write aliasing.
3865 if (CBArgMemBehaviorAA && CBArgMemBehaviorAA->isAssumedReadNone()) {
3866 A.recordDependence(*CBArgMemBehaviorAA, *this, DepClassTy::OPTIONAL);
3867 return false;
3868 }
3869
3870 // If the argument is readonly and the underlying value is readonly, there
3871 // is no read-write aliasing.
3872 bool IsReadOnly = MemBehaviorAA.isAssumedReadOnly();
3873 if (CBArgMemBehaviorAA && CBArgMemBehaviorAA->isAssumedReadOnly() &&
3874 IsReadOnly) {
3875 A.recordDependence(MemBehaviorAA, *this, DepClassTy::OPTIONAL);
3876 A.recordDependence(*CBArgMemBehaviorAA, *this, DepClassTy::OPTIONAL);
3877 return false;
3878 }
3879
3880 // We have to utilize actual alias analysis queries so we need the object.
3881 if (!AAR)
3882 AAR = A.getInfoCache().getAnalysisResultForFunction<AAManager>(
3883 *getAnchorScope());
3884
3885 // Try to rule it out at the call site.
3886 bool IsAliasing = !AAR || !AAR->isNoAlias(&getAssociatedValue(), ArgOp);
3887 LLVM_DEBUG(dbgs() << "[NoAliasCSArg] Check alias between "
3888 "callsite arguments: "
3889 << getAssociatedValue() << " " << *ArgOp << " => "
3890 << (IsAliasing ? "" : "no-") << "alias \n");
3891
3892 return IsAliasing;
3893 }
3894
3895 bool isKnownNoAliasDueToNoAliasPreservation(
3896 Attributor &A, AAResults *&AAR, const AAMemoryBehavior &MemBehaviorAA) {
3897 // We can deduce "noalias" if the following conditions hold.
3898 // (i) Associated value is assumed to be noalias in the definition.
3899 // (ii) Associated value is assumed to be no-capture in all the uses
3900 // possibly executed before this callsite.
3901 // (iii) There is no other pointer argument which could alias with the
3902 // value.
3903
3904 const IRPosition &VIRP = IRPosition::value(getAssociatedValue());
3905 const Function *ScopeFn = VIRP.getAnchorScope();
3906 // Check whether the value is captured in the scope using AANoCapture.
3907 // Look at CFG and check only uses possibly executed before this
3908 // callsite.
3909 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
3910 Instruction *UserI = cast<Instruction>(U.getUser());
3911
3912 // If UserI is the curr instruction and there is a single potential use of
3913 // the value in UserI we allow the use.
3914 // TODO: We should inspect the operands and allow those that cannot alias
3915 // with the value.
3916 if (UserI == getCtxI() && UserI->getNumOperands() == 1)
3917 return true;
3918
3919 if (ScopeFn) {
3920 if (auto *CB = dyn_cast<CallBase>(UserI)) {
3921 if (CB->isArgOperand(&U)) {
3922
3923 unsigned ArgNo = CB->getArgOperandNo(&U);
3924
3925 bool IsKnownNoCapture;
3927 A, this, IRPosition::callsite_argument(*CB, ArgNo),
3928 DepClassTy::OPTIONAL, IsKnownNoCapture))
3929 return true;
3930 }
3931 }
3932
3934 A, *UserI, *getCtxI(), *this, /* ExclusionSet */ nullptr,
3935 [ScopeFn](const Function &Fn) { return &Fn != ScopeFn; }))
3936 return true;
3937 }
3938
3939 // TODO: We should track the capturing uses in AANoCapture but the problem
3940 // is CGSCC runs. For those we would need to "allow" AANoCapture for
3941 // a value in the module slice.
3942 // TODO(captures): Make this more precise.
3943 UseCaptureInfo CI = DetermineUseCaptureKind(U, /*Base=*/nullptr);
3944 if (capturesNothing(CI))
3945 return true;
3946 if (CI.isPassthrough()) {
3947 Follow = true;
3948 return true;
3949 }
3950 LLVM_DEBUG(dbgs() << "[AANoAliasCSArg] Unknown user: " << *UserI << "\n");
3951 return false;
3952 };
3953
3954 bool IsKnownNoCapture;
3955 const AANoCapture *NoCaptureAA = nullptr;
3956 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
3957 A, this, VIRP, DepClassTy::NONE, IsKnownNoCapture, false, &NoCaptureAA);
3958 if (!IsAssumedNoCapture &&
3959 (!NoCaptureAA || !NoCaptureAA->isAssumedNoCaptureMaybeReturned())) {
3960 if (!A.checkForAllUses(UsePred, *this, getAssociatedValue())) {
3961 LLVM_DEBUG(
3962 dbgs() << "[AANoAliasCSArg] " << getAssociatedValue()
3963 << " cannot be noalias as it is potentially captured\n");
3964 return false;
3965 }
3966 }
3967 if (NoCaptureAA)
3968 A.recordDependence(*NoCaptureAA, *this, DepClassTy::OPTIONAL);
3969
3970 // Check there is no other pointer argument which could alias with the
3971 // value passed at this call site.
3972 // TODO: AbstractCallSite
3973 const auto &CB = cast<CallBase>(getAnchorValue());
3974 for (unsigned OtherArgNo = 0; OtherArgNo < CB.arg_size(); OtherArgNo++)
3975 if (mayAliasWithArgument(A, AAR, MemBehaviorAA, CB, OtherArgNo))
3976 return false;
3977
3978 return true;
3979 }
3980
3981 /// See AbstractAttribute::updateImpl(...).
3982 ChangeStatus updateImpl(Attributor &A) override {
3983 // If the argument is readnone we are done as there are no accesses via the
3984 // argument.
3985 auto *MemBehaviorAA =
3986 A.getAAFor<AAMemoryBehavior>(*this, getIRPosition(), DepClassTy::NONE);
3987 if (MemBehaviorAA && MemBehaviorAA->isAssumedReadNone()) {
3988 A.recordDependence(*MemBehaviorAA, *this, DepClassTy::OPTIONAL);
3989 return ChangeStatus::UNCHANGED;
3990 }
3991
3992 bool IsKnownNoAlias;
3993 const IRPosition &VIRP = IRPosition::value(getAssociatedValue());
3995 A, this, VIRP, DepClassTy::REQUIRED, IsKnownNoAlias)) {
3996 LLVM_DEBUG(dbgs() << "[AANoAlias] " << getAssociatedValue()
3997 << " is not no-alias at the definition\n");
3998 return indicatePessimisticFixpoint();
3999 }
4000
4001 AAResults *AAR = nullptr;
4002 if (MemBehaviorAA &&
4003 isKnownNoAliasDueToNoAliasPreservation(A, AAR, *MemBehaviorAA)) {
4004 LLVM_DEBUG(
4005 dbgs() << "[AANoAlias] No-Alias deduced via no-alias preservation\n");
4006 return ChangeStatus::UNCHANGED;
4007 }
4008
4009 return indicatePessimisticFixpoint();
4010 }
4011
4012 /// See AbstractAttribute::trackStatistics()
4013 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(noalias) }
4014};
4015
4016/// NoAlias attribute for function return value.
4017struct AANoAliasReturned final : AANoAliasImpl {
4018 AANoAliasReturned(const IRPosition &IRP, Attributor &A)
4019 : AANoAliasImpl(IRP, A) {}
4020
4021 /// See AbstractAttribute::updateImpl(...).
4022 ChangeStatus updateImpl(Attributor &A) override {
4023
4024 auto CheckReturnValue = [&](Value &RV) -> bool {
4025 if (Constant *C = dyn_cast<Constant>(&RV))
4026 if (C->isNullValue() || isa<UndefValue>(C))
4027 return true;
4028
4029 /// For now, we can only deduce noalias if we have call sites.
4030 /// FIXME: add more support.
4031 if (!isa<CallBase>(&RV))
4032 return false;
4033
4034 const IRPosition &RVPos = IRPosition::value(RV);
4035 bool IsKnownNoAlias;
4037 A, this, RVPos, DepClassTy::REQUIRED, IsKnownNoAlias))
4038 return false;
4039
4040 bool IsKnownNoCapture;
4041 const AANoCapture *NoCaptureAA = nullptr;
4042 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
4043 A, this, RVPos, DepClassTy::REQUIRED, IsKnownNoCapture, false,
4044 &NoCaptureAA);
4045 return IsAssumedNoCapture ||
4046 (NoCaptureAA && NoCaptureAA->isAssumedNoCaptureMaybeReturned());
4047 };
4048
4049 if (!A.checkForAllReturnedValues(CheckReturnValue, *this))
4050 return indicatePessimisticFixpoint();
4051
4052 return ChangeStatus::UNCHANGED;
4053 }
4054
4055 /// See AbstractAttribute::trackStatistics()
4056 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noalias) }
4057};
4058
4059/// NoAlias attribute deduction for a call site return value.
4060struct AANoAliasCallSiteReturned final
4061 : AACalleeToCallSite<AANoAlias, AANoAliasImpl> {
4062 AANoAliasCallSiteReturned(const IRPosition &IRP, Attributor &A)
4063 : AACalleeToCallSite<AANoAlias, AANoAliasImpl>(IRP, A) {}
4064
4065 /// See AbstractAttribute::trackStatistics()
4066 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(noalias); }
4067};
4068} // namespace
4069
4070/// -------------------AAIsDead Function Attribute-----------------------
4071
4072namespace {
4073struct AAIsDeadValueImpl : public AAIsDead {
4074 AAIsDeadValueImpl(const IRPosition &IRP, Attributor &A) : AAIsDead(IRP, A) {}
4075
4076 /// See AAIsDead::isAssumedDead().
4077 bool isAssumedDead() const override { return isAssumed(IS_DEAD); }
4078
4079 /// See AAIsDead::isKnownDead().
4080 bool isKnownDead() const override { return isKnown(IS_DEAD); }
4081
4082 /// See AAIsDead::isAssumedDead(BasicBlock *).
4083 bool isAssumedDead(const BasicBlock *BB) const override { return false; }
4084
4085 /// See AAIsDead::isKnownDead(BasicBlock *).
4086 bool isKnownDead(const BasicBlock *BB) const override { return false; }
4087
4088 /// See AAIsDead::isAssumedDead(Instruction *I).
4089 bool isAssumedDead(const Instruction *I) const override {
4090 return I == getCtxI() && isAssumedDead();
4091 }
4092
4093 /// See AAIsDead::isKnownDead(Instruction *I).
4094 bool isKnownDead(const Instruction *I) const override {
4095 return isAssumedDead(I) && isKnownDead();
4096 }
4097
4098 /// See AbstractAttribute::getAsStr().
4099 const std::string getAsStr(Attributor *A) const override {
4100 return isAssumedDead() ? "assumed-dead" : "assumed-live";
4101 }
4102
4103 /// Check if all uses are assumed dead.
4104 bool areAllUsesAssumedDead(Attributor &A, Value &V) {
4105 // Callers might not check the type, void has no uses.
4106 if (V.getType()->isVoidTy() || V.use_empty())
4107 return true;
4108
4109 // If we replace a value with a constant there are no uses left afterwards.
4110 if (!isa<Constant>(V)) {
4111 if (auto *I = dyn_cast<Instruction>(&V))
4112 if (!A.isRunOn(*I->getFunction()))
4113 return false;
4114 bool UsedAssumedInformation = false;
4115 std::optional<Constant *> C =
4116 A.getAssumedConstant(V, *this, UsedAssumedInformation);
4117 if (!C || *C)
4118 return true;
4119 }
4120
4121 auto UsePred = [&](const Use &U, bool &Follow) { return false; };
4122 // Explicitly set the dependence class to required because we want a long
4123 // chain of N dependent instructions to be considered live as soon as one is
4124 // without going through N update cycles. This is not required for
4125 // correctness.
4126 return A.checkForAllUses(UsePred, *this, V, /* CheckBBLivenessOnly */ false,
4127 DepClassTy::REQUIRED,
4128 /* IgnoreDroppableUses */ false);
4129 }
4130
4131 /// Determine if \p I is assumed to be side-effect free.
4132 bool isAssumedSideEffectFree(Attributor &A, Instruction *I) {
4134 return true;
4135
4136 if (!I->isTerminator() && !I->mayHaveSideEffects())
4137 return true;
4138
4139 auto *CB = dyn_cast<CallBase>(I);
4140 if (!CB || isa<IntrinsicInst>(CB))
4141 return false;
4142
4143 const IRPosition &CallIRP = IRPosition::callsite_function(*CB);
4144
4145 bool IsKnownNoUnwind;
4147 A, this, CallIRP, DepClassTy::OPTIONAL, IsKnownNoUnwind))
4148 return false;
4149
4150 bool IsKnown;
4151 return AA::isAssumedReadOnly(A, CallIRP, *this, IsKnown);
4152 }
4153};
4154
4155struct AAIsDeadFloating : public AAIsDeadValueImpl {
4156 AAIsDeadFloating(const IRPosition &IRP, Attributor &A)
4157 : AAIsDeadValueImpl(IRP, A) {}
4158
4159 /// See AbstractAttribute::initialize(...).
4160 void initialize(Attributor &A) override {
4161 AAIsDeadValueImpl::initialize(A);
4162
4163 if (isa<UndefValue>(getAssociatedValue())) {
4164 indicatePessimisticFixpoint();
4165 return;
4166 }
4167
4168 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
4169 if (!isAssumedSideEffectFree(A, I)) {
4171 indicatePessimisticFixpoint();
4172 else
4173 removeAssumedBits(HAS_NO_EFFECT);
4174 }
4175 }
4176
4177 bool isDeadFence(Attributor &A, FenceInst &FI) {
4178 const auto *ExecDomainAA = A.lookupAAFor<AAExecutionDomain>(
4179 IRPosition::function(*FI.getFunction()), *this, DepClassTy::NONE);
4180 if (!ExecDomainAA || !ExecDomainAA->isNoOpFence(FI))
4181 return false;
4182 A.recordDependence(*ExecDomainAA, *this, DepClassTy::OPTIONAL);
4183 return true;
4184 }
4185
4186 bool isDeadStore(Attributor &A, StoreInst &SI,
4187 SmallSetVector<Instruction *, 8> *AssumeOnlyInst = nullptr) {
4188 // Lang ref now states volatile store is not UB/dead, let's skip them.
4189 if (SI.isVolatile())
4190 return false;
4191
4192 // If we are collecting assumes to be deleted we are in the manifest stage.
4193 // It's problematic to collect the potential copies again now so we use the
4194 // cached ones.
4195 bool UsedAssumedInformation = false;
4196 if (!AssumeOnlyInst) {
4197 PotentialCopies.clear();
4198 if (!AA::getPotentialCopiesOfStoredValue(A, SI, PotentialCopies, *this,
4199 UsedAssumedInformation)) {
4200 LLVM_DEBUG(
4201 dbgs()
4202 << "[AAIsDead] Could not determine potential copies of store!\n");
4203 return false;
4204 }
4205 }
4206 LLVM_DEBUG(dbgs() << "[AAIsDead] Store has " << PotentialCopies.size()
4207 << " potential copies.\n");
4208
4209 InformationCache &InfoCache = A.getInfoCache();
4210 return llvm::all_of(PotentialCopies, [&](Value *V) {
4211 if (A.isAssumedDead(IRPosition::value(*V), this, nullptr,
4212 UsedAssumedInformation))
4213 return true;
4214 if (auto *LI = dyn_cast<LoadInst>(V)) {
4215 if (llvm::all_of(LI->uses(), [&](const Use &U) {
4216 auto &UserI = cast<Instruction>(*U.getUser());
4217 if (InfoCache.isOnlyUsedByAssume(UserI)) {
4218 if (AssumeOnlyInst)
4219 AssumeOnlyInst->insert(&UserI);
4220 return true;
4221 }
4222 return A.isAssumedDead(U, this, nullptr, UsedAssumedInformation);
4223 })) {
4224 return true;
4225 }
4226 }
4227 LLVM_DEBUG(dbgs() << "[AAIsDead] Potential copy " << *V
4228 << " is assumed live!\n");
4229 return false;
4230 });
4231 }
4232
4233 /// See AbstractAttribute::getAsStr().
4234 const std::string getAsStr(Attributor *A) const override {
4235 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
4237 if (isValidState())
4238 return "assumed-dead-store";
4240 if (isValidState())
4241 return "assumed-dead-fence";
4242 return AAIsDeadValueImpl::getAsStr(A);
4243 }
4244
4245 /// See AbstractAttribute::updateImpl(...).
4246 ChangeStatus updateImpl(Attributor &A) override {
4247 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
4248 if (auto *SI = dyn_cast_or_null<StoreInst>(I)) {
4249 if (!isDeadStore(A, *SI))
4250 return indicatePessimisticFixpoint();
4251 } else if (auto *FI = dyn_cast_or_null<FenceInst>(I)) {
4252 if (!isDeadFence(A, *FI))
4253 return indicatePessimisticFixpoint();
4254 } else {
4255 if (!isAssumedSideEffectFree(A, I))
4256 return indicatePessimisticFixpoint();
4257 if (!areAllUsesAssumedDead(A, getAssociatedValue()))
4258 return indicatePessimisticFixpoint();
4259 }
4261 }
4262
4263 bool isRemovableStore() const override {
4264 return isAssumed(IS_REMOVABLE) && isa<StoreInst>(&getAssociatedValue());
4265 }
4266
4267 /// See AbstractAttribute::manifest(...).
4268 ChangeStatus manifest(Attributor &A) override {
4269 Value &V = getAssociatedValue();
4270 if (auto *I = dyn_cast<Instruction>(&V)) {
4271 // If we get here we basically know the users are all dead. We check if
4272 // isAssumedSideEffectFree returns true here again because it might not be
4273 // the case and only the users are dead but the instruction (=call) is
4274 // still needed.
4275 if (auto *SI = dyn_cast<StoreInst>(I)) {
4276 SmallSetVector<Instruction *, 8> AssumeOnlyInst;
4277 bool IsDead = isDeadStore(A, *SI, &AssumeOnlyInst);
4278 (void)IsDead;
4279 assert(IsDead && "Store was assumed to be dead!");
4280 A.deleteAfterManifest(*I);
4281 for (size_t i = 0; i < AssumeOnlyInst.size(); ++i) {
4282 Instruction *AOI = AssumeOnlyInst[i];
4283 for (auto *Usr : AOI->users())
4284 AssumeOnlyInst.insert(cast<Instruction>(Usr));
4285 A.deleteAfterManifest(*AOI);
4286 }
4287 return ChangeStatus::CHANGED;
4288 }
4289 if (auto *FI = dyn_cast<FenceInst>(I)) {
4290 assert(isDeadFence(A, *FI));
4291 A.deleteAfterManifest(*FI);
4292 return ChangeStatus::CHANGED;
4293 }
4294 if (isAssumedSideEffectFree(A, I) && !isa<InvokeInst>(I)) {
4295 A.deleteAfterManifest(*I);
4296 return ChangeStatus::CHANGED;
4297 }
4298 }
4300 }
4301
4302 /// See AbstractAttribute::trackStatistics()
4303 void trackStatistics() const override {
4305 }
4306
4307private:
4308 // The potential copies of a dead store, used for deletion during manifest.
4309 SmallSetVector<Value *, 4> PotentialCopies;
4310};
4311
4312struct AAIsDeadArgument : public AAIsDeadFloating {
4313 AAIsDeadArgument(const IRPosition &IRP, Attributor &A)
4314 : AAIsDeadFloating(IRP, A) {}
4315
4316 /// See AbstractAttribute::manifest(...).
4317 ChangeStatus manifest(Attributor &A) override {
4318 Argument &Arg = *getAssociatedArgument();
4319 if (A.isValidFunctionSignatureRewrite(Arg, /* ReplacementTypes */ {}))
4320 if (A.registerFunctionSignatureRewrite(
4321 Arg, /* ReplacementTypes */ {},
4324 return ChangeStatus::CHANGED;
4325 }
4326 return ChangeStatus::UNCHANGED;
4327 }
4328
4329 /// See AbstractAttribute::trackStatistics()
4330 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(IsDead) }
4331};
4332
4333struct AAIsDeadCallSiteArgument : public AAIsDeadValueImpl {
4334 AAIsDeadCallSiteArgument(const IRPosition &IRP, Attributor &A)
4335 : AAIsDeadValueImpl(IRP, A) {}
4336
4337 /// See AbstractAttribute::initialize(...).
4338 void initialize(Attributor &A) override {
4339 AAIsDeadValueImpl::initialize(A);
4340 if (isa<UndefValue>(getAssociatedValue()))
4341 indicatePessimisticFixpoint();
4342 }
4343
4344 /// See AbstractAttribute::updateImpl(...).
4345 ChangeStatus updateImpl(Attributor &A) override {
4346 // TODO: Once we have call site specific value information we can provide
4347 // call site specific liveness information and then it makes
4348 // sense to specialize attributes for call sites arguments instead of
4349 // redirecting requests to the callee argument.
4350 Argument *Arg = getAssociatedArgument();
4351 if (!Arg)
4352 return indicatePessimisticFixpoint();
4353 const IRPosition &ArgPos = IRPosition::argument(*Arg);
4354 auto *ArgAA = A.getAAFor<AAIsDead>(*this, ArgPos, DepClassTy::REQUIRED);
4355 if (!ArgAA)
4356 return indicatePessimisticFixpoint();
4357 return clampStateAndIndicateChange(getState(), ArgAA->getState());
4358 }
4359
4360 /// See AbstractAttribute::manifest(...).
4361 ChangeStatus manifest(Attributor &A) override {
4362 CallBase &CB = cast<CallBase>(getAnchorValue());
4363 Use &U = CB.getArgOperandUse(getCallSiteArgNo());
4364 assert(!isa<UndefValue>(U.get()) &&
4365 "Expected undef values to be filtered out!");
4366 UndefValue &UV = *UndefValue::get(U->getType());
4367 if (A.changeUseAfterManifest(U, UV))
4368 return ChangeStatus::CHANGED;
4369 return ChangeStatus::UNCHANGED;
4370 }
4371
4372 /// See AbstractAttribute::trackStatistics()
4373 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(IsDead) }
4374};
4375
4376struct AAIsDeadCallSiteReturned : public AAIsDeadFloating {
4377 AAIsDeadCallSiteReturned(const IRPosition &IRP, Attributor &A)
4378 : AAIsDeadFloating(IRP, A) {}
4379
4380 /// See AAIsDead::isAssumedDead().
4381 bool isAssumedDead() const override {
4382 return AAIsDeadFloating::isAssumedDead() && IsAssumedSideEffectFree;
4383 }
4384
4385 /// See AbstractAttribute::initialize(...).
4386 void initialize(Attributor &A) override {
4387 AAIsDeadFloating::initialize(A);
4388 if (isa<UndefValue>(getAssociatedValue())) {
4389 indicatePessimisticFixpoint();
4390 return;
4391 }
4392
4393 // We track this separately as a secondary state.
4394 IsAssumedSideEffectFree = isAssumedSideEffectFree(A, getCtxI());
4395 }
4396
4397 /// See AbstractAttribute::updateImpl(...).
4398 ChangeStatus updateImpl(Attributor &A) override {
4399 ChangeStatus Changed = ChangeStatus::UNCHANGED;
4400 if (IsAssumedSideEffectFree && !isAssumedSideEffectFree(A, getCtxI())) {
4401 IsAssumedSideEffectFree = false;
4402 Changed = ChangeStatus::CHANGED;
4403 }
4404 if (!areAllUsesAssumedDead(A, getAssociatedValue()))
4405 return indicatePessimisticFixpoint();
4406 return Changed;
4407 }
4408
4409 /// See AbstractAttribute::trackStatistics()
4410 void trackStatistics() const override {
4411 if (IsAssumedSideEffectFree)
4413 else
4414 STATS_DECLTRACK_CSRET_ATTR(UnusedResult)
4415 }
4416
4417 /// See AbstractAttribute::getAsStr().
4418 const std::string getAsStr(Attributor *A) const override {
4419 return isAssumedDead()
4420 ? "assumed-dead"
4421 : (getAssumed() ? "assumed-dead-users" : "assumed-live");
4422 }
4423
4424private:
4425 bool IsAssumedSideEffectFree = true;
4426};
4427
4428struct AAIsDeadReturned : public AAIsDeadValueImpl {
4429 AAIsDeadReturned(const IRPosition &IRP, Attributor &A)
4430 : AAIsDeadValueImpl(IRP, A) {}
4431
4432 /// See AbstractAttribute::updateImpl(...).
4433 ChangeStatus updateImpl(Attributor &A) override {
4434
4435 bool UsedAssumedInformation = false;
4436 A.checkForAllInstructions([](Instruction &) { return true; }, *this,
4437 {Instruction::Ret}, UsedAssumedInformation);
4438
4439 auto PredForCallSite = [&](AbstractCallSite ACS) {
4440 if (ACS.isCallbackCall() || !ACS.getInstruction())
4441 return false;
4442 return areAllUsesAssumedDead(A, *ACS.getInstruction());
4443 };
4444
4445 if (!A.checkForAllCallSites(PredForCallSite, *this, true,
4446 UsedAssumedInformation))
4447 return indicatePessimisticFixpoint();
4448
4449 return ChangeStatus::UNCHANGED;
4450 }
4451
4452 /// See AbstractAttribute::manifest(...).
4453 ChangeStatus manifest(Attributor &A) override {
4454 // TODO: Rewrite the signature to return void?
4455 bool AnyChange = false;
4456 UndefValue &UV = *UndefValue::get(getAssociatedFunction()->getReturnType());
4457 auto RetInstPred = [&](Instruction &I) {
4458 ReturnInst &RI = cast<ReturnInst>(I);
4460 AnyChange |= A.changeUseAfterManifest(RI.getOperandUse(0), UV);
4461 return true;
4462 };
4463 bool UsedAssumedInformation = false;
4464 A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret},
4465 UsedAssumedInformation);
4466 return AnyChange ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
4467 }
4468
4469 /// See AbstractAttribute::trackStatistics()
4470 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(IsDead) }
4471};
4472
4473struct AAIsDeadFunction : public AAIsDead {
4474 AAIsDeadFunction(const IRPosition &IRP, Attributor &A) : AAIsDead(IRP, A) {}
4475
4476 /// See AbstractAttribute::initialize(...).
4477 void initialize(Attributor &A) override {
4478 Function *F = getAnchorScope();
4479 assert(F && "Did expect an anchor function");
4480 if (!isAssumedDeadInternalFunction(A)) {
4481 ToBeExploredFrom.insert(&F->getEntryBlock().front());
4482 assumeLive(A, F->getEntryBlock());
4483 }
4484 }
4485
4486 bool isAssumedDeadInternalFunction(Attributor &A) {
4487 if (!getAnchorScope()->hasLocalLinkage())
4488 return false;
4489 bool UsedAssumedInformation = false;
4490 return A.checkForAllCallSites([](AbstractCallSite) { return false; }, *this,
4491 true, UsedAssumedInformation);
4492 }
4493
4494 /// See AbstractAttribute::getAsStr().
4495 const std::string getAsStr(Attributor *A) const override {
4496 return "Live[#BB " + std::to_string(AssumedLiveBlocks.size()) + "/" +
4497 std::to_string(getAnchorScope()->size()) + "][#TBEP " +
4498 std::to_string(ToBeExploredFrom.size()) + "][#KDE " +
4499 std::to_string(KnownDeadEnds.size()) + "]";
4500 }
4501
4502 /// See AbstractAttribute::manifest(...).
4503 ChangeStatus manifest(Attributor &A) override {
4504 assert(getState().isValidState() &&
4505 "Attempted to manifest an invalid state!");
4506
4507 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
4508 Function &F = *getAnchorScope();
4509
4510 if (AssumedLiveBlocks.empty()) {
4511 A.deleteAfterManifest(F);
4512 return ChangeStatus::CHANGED;
4513 }
4514
4515 // Flag to determine if we can change an invoke to a call assuming the
4516 // callee is nounwind. This is not possible if the personality of the
4517 // function allows to catch asynchronous exceptions.
4518 bool Invoke2CallAllowed = !mayCatchAsynchronousExceptions(F);
4519
4520 KnownDeadEnds.set_union(ToBeExploredFrom);
4521 for (const Instruction *DeadEndI : KnownDeadEnds) {
4522 auto *CB = dyn_cast<CallBase>(DeadEndI);
4523 if (!CB)
4524 continue;
4525 bool IsKnownNoReturn;
4527 A, this, IRPosition::callsite_function(*CB), DepClassTy::OPTIONAL,
4528 IsKnownNoReturn);
4529 if (MayReturn && (!Invoke2CallAllowed || !isa<InvokeInst>(CB)))
4530 continue;
4531
4532 if (auto *II = dyn_cast<InvokeInst>(DeadEndI))
4533 A.registerInvokeWithDeadSuccessor(const_cast<InvokeInst &>(*II));
4534 else
4535 A.changeToUnreachableAfterManifest(
4536 const_cast<Instruction *>(DeadEndI->getNextNode()));
4537 HasChanged = ChangeStatus::CHANGED;
4538 }
4539
4540 STATS_DECL(AAIsDead, BasicBlock, "Number of dead basic blocks deleted.");
4541 for (BasicBlock &BB : F)
4542 if (!AssumedLiveBlocks.count(&BB)) {
4543 A.deleteAfterManifest(BB);
4544 ++BUILD_STAT_NAME(AAIsDead, BasicBlock);
4545 HasChanged = ChangeStatus::CHANGED;
4546 }
4547
4548 return HasChanged;
4549 }
4550
4551 /// See AbstractAttribute::updateImpl(...).
4552 ChangeStatus updateImpl(Attributor &A) override;
4553
4554 bool isEdgeDead(const BasicBlock *From, const BasicBlock *To) const override {
4555 assert(From->getParent() == getAnchorScope() &&
4556 To->getParent() == getAnchorScope() &&
4557 "Used AAIsDead of the wrong function");
4558 return isValidState() && !AssumedLiveEdges.count(std::make_pair(From, To));
4559 }
4560
4561 /// See AbstractAttribute::trackStatistics()
4562 void trackStatistics() const override {}
4563
4564 /// Returns true if the function is assumed dead.
4565 bool isAssumedDead() const override { return false; }
4566
4567 /// See AAIsDead::isKnownDead().
4568 bool isKnownDead() const override { return false; }
4569
4570 /// See AAIsDead::isAssumedDead(BasicBlock *).
4571 bool isAssumedDead(const BasicBlock *BB) const override {
4572 assert(BB->getParent() == getAnchorScope() &&
4573 "BB must be in the same anchor scope function.");
4574
4575 if (!getAssumed())
4576 return false;
4577 return !AssumedLiveBlocks.count(BB);
4578 }
4579
4580 /// See AAIsDead::isKnownDead(BasicBlock *).
4581 bool isKnownDead(const BasicBlock *BB) const override {
4582 return getKnown() && isAssumedDead(BB);
4583 }
4584
4585 /// See AAIsDead::isAssumed(Instruction *I).
4586 bool isAssumedDead(const Instruction *I) const override {
4587 assert(I->getParent()->getParent() == getAnchorScope() &&
4588 "Instruction must be in the same anchor scope function.");
4589
4590 if (!getAssumed())
4591 return false;
4592
4593 // If it is not in AssumedLiveBlocks then it for sure dead.
4594 // Otherwise, it can still be after noreturn call in a live block.
4595 if (!AssumedLiveBlocks.count(I->getParent()))
4596 return true;
4597
4598 // If it is not after a liveness barrier it is live.
4599 const Instruction *PrevI = I->getPrevNode();
4600 while (PrevI) {
4601 if (KnownDeadEnds.count(PrevI) || ToBeExploredFrom.count(PrevI))
4602 return true;
4603 PrevI = PrevI->getPrevNode();
4604 }
4605 return false;
4606 }
4607
4608 /// See AAIsDead::isKnownDead(Instruction *I).
4609 bool isKnownDead(const Instruction *I) const override {
4610 return getKnown() && isAssumedDead(I);
4611 }
4612
4613 /// Assume \p BB is (partially) live now and indicate to the Attributor \p A
4614 /// that internal function called from \p BB should now be looked at.
4615 bool assumeLive(Attributor &A, const BasicBlock &BB) {
4616 if (!AssumedLiveBlocks.insert(&BB).second)
4617 return false;
4618
4619 // We assume that all of BB is (probably) live now and if there are calls to
4620 // internal functions we will assume that those are now live as well. This
4621 // is a performance optimization for blocks with calls to a lot of internal
4622 // functions. It can however cause dead functions to be treated as live.
4623 for (const Instruction &I : BB)
4624 if (const auto *CB = dyn_cast<CallBase>(&I))
4626 if (F->hasLocalLinkage())
4627 A.markLiveInternalFunction(*F);
4628 return true;
4629 }
4630
4631 /// Collection of instructions that need to be explored again, e.g., we
4632 /// did assume they do not transfer control to (one of their) successors.
4633 SmallSetVector<const Instruction *, 8> ToBeExploredFrom;
4634
4635 /// Collection of instructions that are known to not transfer control.
4636 SmallSetVector<const Instruction *, 8> KnownDeadEnds;
4637
4638 /// Collection of all assumed live edges
4639 DenseSet<std::pair<const BasicBlock *, const BasicBlock *>> AssumedLiveEdges;
4640
4641 /// Collection of all assumed live BasicBlocks.
4642 DenseSet<const BasicBlock *> AssumedLiveBlocks;
4643};
4644
4645static bool
4646identifyAliveSuccessors(Attributor &A, const CallBase &CB,
4647 AbstractAttribute &AA,
4648 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4649 const IRPosition &IPos = IRPosition::callsite_function(CB);
4650
4651 bool IsKnownNoReturn;
4653 A, &AA, IPos, DepClassTy::OPTIONAL, IsKnownNoReturn))
4654 return !IsKnownNoReturn;
4655 if (CB.isTerminator())
4656 AliveSuccessors.push_back(&CB.getSuccessor(0)->front());
4657 else
4658 AliveSuccessors.push_back(CB.getNextNode());
4659 return false;
4660}
4661
4662static bool
4663identifyAliveSuccessors(Attributor &A, const InvokeInst &II,
4664 AbstractAttribute &AA,
4665 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4666 bool UsedAssumedInformation =
4667 identifyAliveSuccessors(A, cast<CallBase>(II), AA, AliveSuccessors);
4668
4669 // First, determine if we can change an invoke to a call assuming the
4670 // callee is nounwind. This is not possible if the personality of the
4671 // function allows to catch asynchronous exceptions.
4672 if (AAIsDeadFunction::mayCatchAsynchronousExceptions(*II.getFunction())) {
4673 AliveSuccessors.push_back(&II.getUnwindDest()->front());
4674 } else {
4675 const IRPosition &IPos = IRPosition::callsite_function(II);
4676
4677 bool IsKnownNoUnwind;
4679 A, &AA, IPos, DepClassTy::OPTIONAL, IsKnownNoUnwind)) {
4680 UsedAssumedInformation |= !IsKnownNoUnwind;
4681 } else {
4682 AliveSuccessors.push_back(&II.getUnwindDest()->front());
4683 }
4684 }
4685 return UsedAssumedInformation;
4686}
4687
4688static bool
4689identifyAliveSuccessors(Attributor &, const UncondBrInst &BI,
4690 AbstractAttribute &,
4691 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4692 AliveSuccessors.push_back(&BI.getSuccessor()->front());
4693 return false;
4694}
4695
4696static bool
4697identifyAliveSuccessors(Attributor &A, const CondBrInst &BI,
4698 AbstractAttribute &AA,
4699 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4700 bool UsedAssumedInformation = false;
4701 std::optional<Constant *> C =
4702 A.getAssumedConstant(*BI.getCondition(), AA, UsedAssumedInformation);
4703 if (!C || isa_and_nonnull<UndefValue>(*C)) {
4704 // No value yet, assume both edges are dead.
4705 } else if (isa_and_nonnull<ConstantInt>(*C)) {
4706 const BasicBlock *SuccBB =
4707 BI.getSuccessor(1 - cast<ConstantInt>(*C)->getValue().getZExtValue());
4708 AliveSuccessors.push_back(&SuccBB->front());
4709 } else {
4710 AliveSuccessors.push_back(&BI.getSuccessor(0)->front());
4711 AliveSuccessors.push_back(&BI.getSuccessor(1)->front());
4712 UsedAssumedInformation = false;
4713 }
4714 return UsedAssumedInformation;
4715}
4716
4717static bool
4718identifyAliveSuccessors(Attributor &A, const SwitchInst &SI,
4719 AbstractAttribute &AA,
4720 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4721 bool UsedAssumedInformation = false;
4723 if (!A.getAssumedSimplifiedValues(IRPosition::value(*SI.getCondition()), &AA,
4724 Values, AA::AnyScope,
4725 UsedAssumedInformation)) {
4726 // Something went wrong, assume all successors are live.
4727 for (const BasicBlock *SuccBB : successors(SI.getParent()))
4728 AliveSuccessors.push_back(&SuccBB->front());
4729 return false;
4730 }
4731
4732 if (Values.empty() ||
4733 (Values.size() == 1 &&
4734 isa_and_nonnull<UndefValue>(Values.front().getValue()))) {
4735 // No valid value yet, assume all edges are dead.
4736 return UsedAssumedInformation;
4737 }
4738
4739 Type &Ty = *SI.getCondition()->getType();
4740 SmallPtrSet<ConstantInt *, 8> Constants;
4741 auto CheckForConstantInt = [&](Value *V) {
4742 if (auto *CI = dyn_cast_if_present<ConstantInt>(AA::getWithType(*V, Ty))) {
4743 Constants.insert(CI);
4744 return true;
4745 }
4746 return false;
4747 };
4748
4749 if (!all_of(Values, [&](AA::ValueAndContext &VAC) {
4750 return CheckForConstantInt(VAC.getValue());
4751 })) {
4752 for (const BasicBlock *SuccBB : successors(SI.getParent()))
4753 AliveSuccessors.push_back(&SuccBB->front());
4754 return UsedAssumedInformation;
4755 }
4756
4757 unsigned MatchedCases = 0;
4758 for (const auto &CaseIt : SI.cases()) {
4759 if (Constants.count(CaseIt.getCaseValue())) {
4760 ++MatchedCases;
4761 AliveSuccessors.push_back(&CaseIt.getCaseSuccessor()->front());
4762 }
4763 }
4764
4765 // If all potential values have been matched, we will not visit the default
4766 // case.
4767 if (MatchedCases < Constants.size())
4768 AliveSuccessors.push_back(&SI.getDefaultDest()->front());
4769 return UsedAssumedInformation;
4770}
4771
4772ChangeStatus AAIsDeadFunction::updateImpl(Attributor &A) {
4774
4775 if (AssumedLiveBlocks.empty()) {
4776 if (isAssumedDeadInternalFunction(A))
4778
4779 Function *F = getAnchorScope();
4780 ToBeExploredFrom.insert(&F->getEntryBlock().front());
4781 assumeLive(A, F->getEntryBlock());
4782 Change = ChangeStatus::CHANGED;
4783 }
4784
4785 LLVM_DEBUG(dbgs() << "[AAIsDead] Live [" << AssumedLiveBlocks.size() << "/"
4786 << getAnchorScope()->size() << "] BBs and "
4787 << ToBeExploredFrom.size() << " exploration points and "
4788 << KnownDeadEnds.size() << " known dead ends\n");
4789
4790 // Copy and clear the list of instructions we need to explore from. It is
4791 // refilled with instructions the next update has to look at.
4792 SmallVector<const Instruction *, 8> Worklist(ToBeExploredFrom.begin(),
4793 ToBeExploredFrom.end());
4794 decltype(ToBeExploredFrom) NewToBeExploredFrom;
4795
4797 while (!Worklist.empty()) {
4798 const Instruction *I = Worklist.pop_back_val();
4799 LLVM_DEBUG(dbgs() << "[AAIsDead] Exploration inst: " << *I << "\n");
4800
4801 // Fast forward for uninteresting instructions. We could look for UB here
4802 // though.
4803 while (!I->isTerminator() && !isa<CallBase>(I))
4804 I = I->getNextNode();
4805
4806 AliveSuccessors.clear();
4807
4808 bool UsedAssumedInformation = false;
4809 switch (I->getOpcode()) {
4810 // TODO: look for (assumed) UB to backwards propagate "deadness".
4811 default:
4812 assert(I->isTerminator() &&
4813 "Expected non-terminators to be handled already!");
4814 for (const BasicBlock *SuccBB : successors(I->getParent()))
4815 AliveSuccessors.push_back(&SuccBB->front());
4816 break;
4817 case Instruction::Call:
4818 UsedAssumedInformation = identifyAliveSuccessors(A, cast<CallInst>(*I),
4819 *this, AliveSuccessors);
4820 break;
4821 case Instruction::Invoke:
4822 UsedAssumedInformation = identifyAliveSuccessors(A, cast<InvokeInst>(*I),
4823 *this, AliveSuccessors);
4824 break;
4825 case Instruction::UncondBr:
4826 UsedAssumedInformation = identifyAliveSuccessors(
4827 A, cast<UncondBrInst>(*I), *this, AliveSuccessors);
4828 break;
4829 case Instruction::CondBr:
4830 UsedAssumedInformation = identifyAliveSuccessors(A, cast<CondBrInst>(*I),
4831 *this, AliveSuccessors);
4832 break;
4833 case Instruction::Switch:
4834 UsedAssumedInformation = identifyAliveSuccessors(A, cast<SwitchInst>(*I),
4835 *this, AliveSuccessors);
4836 break;
4837 }
4838
4839 if (UsedAssumedInformation) {
4840 NewToBeExploredFrom.insert(I);
4841 } else if (AliveSuccessors.empty() ||
4842 (I->isTerminator() &&
4843 AliveSuccessors.size() < I->getNumSuccessors())) {
4844 if (KnownDeadEnds.insert(I))
4845 Change = ChangeStatus::CHANGED;
4846 }
4847
4848 LLVM_DEBUG(dbgs() << "[AAIsDead] #AliveSuccessors: "
4849 << AliveSuccessors.size() << " UsedAssumedInformation: "
4850 << UsedAssumedInformation << "\n");
4851
4852 for (const Instruction *AliveSuccessor : AliveSuccessors) {
4853 if (!I->isTerminator()) {
4854 assert(AliveSuccessors.size() == 1 &&
4855 "Non-terminator expected to have a single successor!");
4856 Worklist.push_back(AliveSuccessor);
4857 } else {
4858 // record the assumed live edge
4859 auto Edge = std::make_pair(I->getParent(), AliveSuccessor->getParent());
4860 if (AssumedLiveEdges.insert(Edge).second)
4861 Change = ChangeStatus::CHANGED;
4862 if (assumeLive(A, *AliveSuccessor->getParent()))
4863 Worklist.push_back(AliveSuccessor);
4864 }
4865 }
4866 }
4867
4868 // Check if the content of ToBeExploredFrom changed, ignore the order.
4869 if (NewToBeExploredFrom.size() != ToBeExploredFrom.size() ||
4870 llvm::any_of(NewToBeExploredFrom, [&](const Instruction *I) {
4871 return !ToBeExploredFrom.count(I);
4872 })) {
4873 Change = ChangeStatus::CHANGED;
4874 ToBeExploredFrom = std::move(NewToBeExploredFrom);
4875 }
4876
4877 // If we know everything is live there is no need to query for liveness.
4878 // Instead, indicating a pessimistic fixpoint will cause the state to be
4879 // "invalid" and all queries to be answered conservatively without lookups.
4880 // To be in this state we have to (1) finished the exploration and (3) not
4881 // discovered any non-trivial dead end and (2) not ruled unreachable code
4882 // dead.
4883 if (ToBeExploredFrom.empty() &&
4884 getAnchorScope()->size() == AssumedLiveBlocks.size() &&
4885 llvm::all_of(KnownDeadEnds, [](const Instruction *DeadEndI) {
4886 return DeadEndI->isTerminator() && DeadEndI->getNumSuccessors() == 0;
4887 }))
4888 return indicatePessimisticFixpoint();
4889 return Change;
4890}
4891
4892/// Liveness information for a call sites.
4893struct AAIsDeadCallSite final : AAIsDeadFunction {
4894 AAIsDeadCallSite(const IRPosition &IRP, Attributor &A)
4895 : AAIsDeadFunction(IRP, A) {}
4896
4897 /// See AbstractAttribute::initialize(...).
4898 void initialize(Attributor &A) override {
4899 // TODO: Once we have call site specific value information we can provide
4900 // call site specific liveness information and then it makes
4901 // sense to specialize attributes for call sites instead of
4902 // redirecting requests to the callee.
4903 llvm_unreachable("Abstract attributes for liveness are not "
4904 "supported for call sites yet!");
4905 }
4906
4907 /// See AbstractAttribute::updateImpl(...).
4908 ChangeStatus updateImpl(Attributor &A) override {
4909 return indicatePessimisticFixpoint();
4910 }
4911
4912 /// See AbstractAttribute::trackStatistics()
4913 void trackStatistics() const override {}
4914};
4915} // namespace
4916
4917/// -------------------- Dereferenceable Argument Attribute --------------------
4918
4919namespace {
4920struct AADereferenceableImpl : AADereferenceable {
4921 AADereferenceableImpl(const IRPosition &IRP, Attributor &A)
4922 : AADereferenceable(IRP, A) {}
4923 using StateType = DerefState;
4924
4925 /// See AbstractAttribute::initialize(...).
4926 void initialize(Attributor &A) override {
4927 Value &V = *getAssociatedValue().stripPointerCasts();
4929 A.getAttrs(getIRPosition(),
4930 {Attribute::Dereferenceable, Attribute::DereferenceableOrNull},
4931 Attrs, /* IgnoreSubsumingPositions */ false);
4932 for (const Attribute &Attr : Attrs)
4933 takeKnownDerefBytesMaximum(Attr.getValueAsInt());
4934
4935 // Ensure we initialize the non-null AA (if necessary).
4936 bool IsKnownNonNull;
4938 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNonNull);
4939
4940 bool CanBeNull, CanBeFreed;
4941 takeKnownDerefBytesMaximum(V.getPointerDereferenceableBytes(
4942 A.getDataLayout(), CanBeNull, CanBeFreed));
4943
4944 if (Instruction *CtxI = getCtxI())
4945 followUsesInMBEC(*this, A, getState(), *CtxI);
4946 }
4947
4948 /// See AbstractAttribute::getState()
4949 /// {
4950 StateType &getState() override { return *this; }
4951 const StateType &getState() const override { return *this; }
4952 /// }
4953
4954 /// Helper function for collecting accessed bytes in must-be-executed-context
4955 void addAccessedBytesForUse(Attributor &A, const Use *U, const Instruction *I,
4956 DerefState &State) {
4957 const Value *UseV = U->get();
4958 if (!UseV->getType()->isPointerTy())
4959 return;
4960
4961 std::optional<MemoryLocation> Loc = MemoryLocation::getOrNone(I);
4962 if (!Loc || Loc->Ptr != UseV || !Loc->Size.isPrecise() || I->isVolatile())
4963 return;
4964
4965 int64_t Offset;
4967 Loc->Ptr, Offset, A.getDataLayout(), /*AllowNonInbounds*/ true);
4968 if (Base && Base == &getAssociatedValue())
4969 State.addAccessedBytes(Offset, Loc->Size.getValue());
4970 }
4971
4972 /// See followUsesInMBEC
4973 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
4974 AADereferenceable::StateType &State) {
4975 bool IsNonNull = false;
4976 bool TrackUse = false;
4977 int64_t DerefBytes = getKnownNonNullAndDerefBytesForUse(
4978 A, *this, getAssociatedValue(), U, I, IsNonNull, TrackUse);
4979 LLVM_DEBUG(dbgs() << "[AADereferenceable] Deref bytes: " << DerefBytes
4980 << " for instruction " << *I << "\n");
4981
4982 addAccessedBytesForUse(A, U, I, State);
4983 State.takeKnownDerefBytesMaximum(DerefBytes);
4984 return TrackUse;
4985 }
4986
4987 /// See AbstractAttribute::manifest(...).
4988 ChangeStatus manifest(Attributor &A) override {
4989 ChangeStatus Change = AADereferenceable::manifest(A);
4990 bool IsKnownNonNull;
4991 bool IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>(
4992 A, this, getIRPosition(), DepClassTy::NONE, IsKnownNonNull);
4993 if (IsAssumedNonNull &&
4994 A.hasAttr(getIRPosition(), Attribute::DereferenceableOrNull)) {
4995 A.removeAttrs(getIRPosition(), {Attribute::DereferenceableOrNull});
4996 return ChangeStatus::CHANGED;
4997 }
4998 return Change;
4999 }
5000
5001 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
5002 SmallVectorImpl<Attribute> &Attrs) const override {
5003 // TODO: Add *_globally support
5004 bool IsKnownNonNull;
5005 bool IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>(
5006 A, this, getIRPosition(), DepClassTy::NONE, IsKnownNonNull);
5007 if (IsAssumedNonNull)
5008 Attrs.emplace_back(Attribute::getWithDereferenceableBytes(
5009 Ctx, getAssumedDereferenceableBytes()));
5010 else
5011 Attrs.emplace_back(Attribute::getWithDereferenceableOrNullBytes(
5012 Ctx, getAssumedDereferenceableBytes()));
5013 }
5014
5015 /// See AbstractAttribute::getAsStr().
5016 const std::string getAsStr(Attributor *A) const override {
5017 if (!getAssumedDereferenceableBytes())
5018 return "unknown-dereferenceable";
5019 bool IsKnownNonNull;
5020 bool IsAssumedNonNull = false;
5021 if (A)
5023 *A, this, getIRPosition(), DepClassTy::NONE, IsKnownNonNull);
5024 return std::string("dereferenceable") +
5025 (IsAssumedNonNull ? "" : "_or_null") +
5026 (isAssumedGlobal() ? "_globally" : "") + "<" +
5027 std::to_string(getKnownDereferenceableBytes()) + "-" +
5028 std::to_string(getAssumedDereferenceableBytes()) + ">" +
5029 (!A ? " [non-null is unknown]" : "");
5030 }
5031};
5032
5033/// Dereferenceable attribute for a floating value.
5034struct AADereferenceableFloating : AADereferenceableImpl {
5035 AADereferenceableFloating(const IRPosition &IRP, Attributor &A)
5036 : AADereferenceableImpl(IRP, A) {}
5037
5038 /// See AbstractAttribute::updateImpl(...).
5039 ChangeStatus updateImpl(Attributor &A) override {
5040 bool Stripped;
5041 bool UsedAssumedInformation = false;
5043 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
5044 AA::AnyScope, UsedAssumedInformation)) {
5045 Values.push_back({getAssociatedValue(), getCtxI()});
5046 Stripped = false;
5047 } else {
5048 Stripped = Values.size() != 1 ||
5049 Values.front().getValue() != &getAssociatedValue();
5050 }
5051
5052 const DataLayout &DL = A.getDataLayout();
5053 DerefState T;
5054
5055 auto VisitValueCB = [&](const Value &V) -> bool {
5056 unsigned IdxWidth =
5057 DL.getIndexSizeInBits(V.getType()->getPointerAddressSpace());
5058 APInt Offset(IdxWidth, 0);
5060 A, *this, &V, DL, Offset, /* GetMinOffset */ false,
5061 /* AllowNonInbounds */ true);
5062
5063 const auto *AA = A.getAAFor<AADereferenceable>(
5064 *this, IRPosition::value(*Base), DepClassTy::REQUIRED);
5065 int64_t DerefBytes = 0;
5066 if (!AA || (!Stripped && this == AA)) {
5067 // Use IR information if we did not strip anything.
5068 // TODO: track globally.
5069 bool CanBeNull, CanBeFreed;
5070 DerefBytes =
5071 Base->getPointerDereferenceableBytes(DL, CanBeNull, CanBeFreed);
5072 T.GlobalState.indicatePessimisticFixpoint();
5073 } else {
5074 const DerefState &DS = AA->getState();
5075 DerefBytes = DS.DerefBytesState.getAssumed();
5076 T.GlobalState &= DS.GlobalState;
5077 }
5078
5079 // For now we do not try to "increase" dereferenceability due to negative
5080 // indices as we first have to come up with code to deal with loops and
5081 // for overflows of the dereferenceable bytes.
5082 int64_t OffsetSExt = Offset.getSExtValue();
5083 if (OffsetSExt < 0)
5084 OffsetSExt = 0;
5085
5086 T.takeAssumedDerefBytesMinimum(
5087 std::max(int64_t(0), DerefBytes - OffsetSExt));
5088
5089 if (this == AA) {
5090 if (!Stripped) {
5091 // If nothing was stripped IR information is all we got.
5092 T.takeKnownDerefBytesMaximum(
5093 std::max(int64_t(0), DerefBytes - OffsetSExt));
5094 T.indicatePessimisticFixpoint();
5095 } else if (OffsetSExt > 0) {
5096 // If something was stripped but there is circular reasoning we look
5097 // for the offset. If it is positive we basically decrease the
5098 // dereferenceable bytes in a circular loop now, which will simply
5099 // drive them down to the known value in a very slow way which we
5100 // can accelerate.
5101 T.indicatePessimisticFixpoint();
5102 }
5103 }
5104
5105 return T.isValidState();
5106 };
5107
5108 for (const auto &VAC : Values)
5109 if (!VisitValueCB(*VAC.getValue()))
5110 return indicatePessimisticFixpoint();
5111
5112 return clampStateAndIndicateChange(getState(), T);
5113 }
5114
5115 /// See AbstractAttribute::trackStatistics()
5116 void trackStatistics() const override {
5117 STATS_DECLTRACK_FLOATING_ATTR(dereferenceable)
5118 }
5119};
5120
5121/// Dereferenceable attribute for a return value.
5122struct AADereferenceableReturned final
5123 : AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl> {
5124 using Base =
5125 AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl>;
5126 AADereferenceableReturned(const IRPosition &IRP, Attributor &A)
5127 : Base(IRP, A) {}
5128
5129 /// See AbstractAttribute::trackStatistics()
5130 void trackStatistics() const override {
5131 STATS_DECLTRACK_FNRET_ATTR(dereferenceable)
5132 }
5133};
5134
5135/// Dereferenceable attribute for an argument
5136struct AADereferenceableArgument final
5137 : AAArgumentFromCallSiteArguments<AADereferenceable,
5138 AADereferenceableImpl> {
5139 using Base =
5140 AAArgumentFromCallSiteArguments<AADereferenceable, AADereferenceableImpl>;
5141 AADereferenceableArgument(const IRPosition &IRP, Attributor &A)
5142 : Base(IRP, A) {}
5143
5144 /// See AbstractAttribute::trackStatistics()
5145 void trackStatistics() const override {
5146 STATS_DECLTRACK_ARG_ATTR(dereferenceable)
5147 }
5148};
5149
5150/// Dereferenceable attribute for a call site argument.
5151struct AADereferenceableCallSiteArgument final : AADereferenceableFloating {
5152 AADereferenceableCallSiteArgument(const IRPosition &IRP, Attributor &A)
5153 : AADereferenceableFloating(IRP, A) {}
5154
5155 /// See AbstractAttribute::trackStatistics()
5156 void trackStatistics() const override {
5157 STATS_DECLTRACK_CSARG_ATTR(dereferenceable)
5158 }
5159};
5160
5161/// Dereferenceable attribute deduction for a call site return value.
5162struct AADereferenceableCallSiteReturned final
5163 : AACalleeToCallSite<AADereferenceable, AADereferenceableImpl> {
5164 using Base = AACalleeToCallSite<AADereferenceable, AADereferenceableImpl>;
5165 AADereferenceableCallSiteReturned(const IRPosition &IRP, Attributor &A)
5166 : Base(IRP, A) {}
5167
5168 /// See AbstractAttribute::trackStatistics()
5169 void trackStatistics() const override {
5170 STATS_DECLTRACK_CS_ATTR(dereferenceable);
5171 }
5172};
5173} // namespace
5174
5175// ------------------------ Align Argument Attribute ------------------------
5176
5177namespace {
5178
5179static unsigned getKnownAlignForUse(Attributor &A, AAAlign &QueryingAA,
5180 Value &AssociatedValue, const Use *U,
5181 const Instruction *I, bool &TrackUse) {
5182 // We need to follow common pointer manipulation uses to the accesses they
5183 // feed into.
5184 if (isa<CastInst>(I)) {
5185 // Follow all but ptr2int casts.
5186 TrackUse = !isa<PtrToIntInst>(I);
5187 return 0;
5188 }
5189 if (auto *GEP = dyn_cast<GetElementPtrInst>(I)) {
5190 if (GEP->hasAllConstantIndices())
5191 TrackUse = true;
5192 return 0;
5193 }
5194 if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(I))
5195 switch (II->getIntrinsicID()) {
5196 case Intrinsic::ptrmask: {
5197 // Is it appropriate to pull attribute in initialization?
5198 const auto *ConstVals = A.getAAFor<AAPotentialConstantValues>(
5199 QueryingAA, IRPosition::value(*II->getOperand(1)), DepClassTy::NONE);
5200 const auto *AlignAA = A.getAAFor<AAAlign>(
5201 QueryingAA, IRPosition::value(*II), DepClassTy::NONE);
5202 if (ConstVals && ConstVals->isValidState() && ConstVals->isAtFixpoint()) {
5203 unsigned ShiftValue = std::min(ConstVals->getAssumedMinTrailingZeros(),
5205 Align ConstAlign(UINT64_C(1) << ShiftValue);
5206 if (ConstAlign >= AlignAA->getKnownAlign())
5207 return Align(1).value();
5208 }
5209 if (AlignAA)
5210 return AlignAA->getKnownAlign().value();
5211 break;
5212 }
5213 case Intrinsic::amdgcn_make_buffer_rsrc: {
5214 const auto *AlignAA = A.getAAFor<AAAlign>(
5215 QueryingAA, IRPosition::value(*II), DepClassTy::NONE);
5216 if (AlignAA)
5217 return AlignAA->getKnownAlign().value();
5218 break;
5219 }
5220 default:
5221 break;
5222 }
5223
5224 MaybeAlign MA;
5225 if (const auto *CB = dyn_cast<CallBase>(I)) {
5226 if (CB->isBundleOperand(U) || CB->isCallee(U))
5227 return 0;
5228
5229 unsigned ArgNo = CB->getArgOperandNo(U);
5230 IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo);
5231 // As long as we only use known information there is no need to track
5232 // dependences here.
5233 auto *AlignAA = A.getAAFor<AAAlign>(QueryingAA, IRP, DepClassTy::NONE);
5234 if (AlignAA)
5235 MA = MaybeAlign(AlignAA->getKnownAlign());
5236 }
5237
5238 const DataLayout &DL = A.getDataLayout();
5239 const Value *UseV = U->get();
5240 if (auto *SI = dyn_cast<StoreInst>(I)) {
5241 if (SI->getPointerOperand() == UseV)
5242 MA = SI->getAlign();
5243 } else if (auto *LI = dyn_cast<LoadInst>(I)) {
5244 if (LI->getPointerOperand() == UseV)
5245 MA = LI->getAlign();
5246 } else if (auto *AI = dyn_cast<AtomicRMWInst>(I)) {
5247 if (AI->getPointerOperand() == UseV)
5248 MA = AI->getAlign();
5249 } else if (auto *AI = dyn_cast<AtomicCmpXchgInst>(I)) {
5250 if (AI->getPointerOperand() == UseV)
5251 MA = AI->getAlign();
5252 }
5253
5254 if (!MA || *MA <= QueryingAA.getKnownAlign())
5255 return 0;
5256
5257 unsigned Alignment = MA->value();
5258 int64_t Offset;
5259
5260 if (const Value *Base = GetPointerBaseWithConstantOffset(UseV, Offset, DL)) {
5261 if (Base == &AssociatedValue) {
5262 // BasePointerAddr + Offset = Alignment * Q for some integer Q.
5263 // So we can say that the maximum power of two which is a divisor of
5264 // gcd(Offset, Alignment) is an alignment.
5265
5266 uint32_t gcd = std::gcd(uint32_t(abs((int32_t)Offset)), Alignment);
5267 Alignment = llvm::bit_floor(gcd);
5268 }
5269 }
5270
5271 return Alignment;
5272}
5273
5274struct AAAlignImpl : AAAlign {
5275 AAAlignImpl(const IRPosition &IRP, Attributor &A) : AAAlign(IRP, A) {}
5276
5277 /// See AbstractAttribute::initialize(...).
5278 void initialize(Attributor &A) override {
5280 A.getAttrs(getIRPosition(), {Attribute::Alignment}, Attrs);
5281 for (const Attribute &Attr : Attrs)
5282 takeKnownMaximum(Attr.getValueAsInt());
5283
5284 Value &V = *getAssociatedValue().stripPointerCasts();
5285 takeKnownMaximum(V.getPointerAlignment(A.getDataLayout()).value());
5286
5287 if (Instruction *CtxI = getCtxI())
5288 followUsesInMBEC(*this, A, getState(), *CtxI);
5289 }
5290
5291 /// See AbstractAttribute::manifest(...).
5292 ChangeStatus manifest(Attributor &A) override {
5293 ChangeStatus InstrChanged = ChangeStatus::UNCHANGED;
5294
5295 // Check for users that allow alignment annotations.
5296 Value &AssociatedValue = getAssociatedValue();
5297 if (isa<ConstantData>(AssociatedValue))
5298 return ChangeStatus::UNCHANGED;
5299
5300 for (const Use &U : AssociatedValue.uses()) {
5301 if (auto *SI = dyn_cast<StoreInst>(U.getUser())) {
5302 if (SI->getPointerOperand() == &AssociatedValue)
5303 if (SI->getAlign() < getAssumedAlign()) {
5304 STATS_DECLTRACK(AAAlign, Store,
5305 "Number of times alignment added to a store");
5306 SI->setAlignment(getAssumedAlign());
5307 InstrChanged = ChangeStatus::CHANGED;
5308 }
5309 } else if (auto *LI = dyn_cast<LoadInst>(U.getUser())) {
5310 if (LI->getPointerOperand() == &AssociatedValue)
5311 if (LI->getAlign() < getAssumedAlign()) {
5312 LI->setAlignment(getAssumedAlign());
5313 STATS_DECLTRACK(AAAlign, Load,
5314 "Number of times alignment added to a load");
5315 InstrChanged = ChangeStatus::CHANGED;
5316 }
5317 } else if (auto *RMW = dyn_cast<AtomicRMWInst>(U.getUser())) {
5318 if (RMW->getPointerOperand() == &AssociatedValue) {
5319 if (RMW->getAlign() < getAssumedAlign()) {
5320 STATS_DECLTRACK(AAAlign, AtomicRMW,
5321 "Number of times alignment added to atomicrmw");
5322
5323 RMW->setAlignment(getAssumedAlign());
5324 InstrChanged = ChangeStatus::CHANGED;
5325 }
5326 }
5327 } else if (auto *CAS = dyn_cast<AtomicCmpXchgInst>(U.getUser())) {
5328 if (CAS->getPointerOperand() == &AssociatedValue) {
5329 if (CAS->getAlign() < getAssumedAlign()) {
5330 STATS_DECLTRACK(AAAlign, AtomicCmpXchg,
5331 "Number of times alignment added to cmpxchg");
5332 CAS->setAlignment(getAssumedAlign());
5333 InstrChanged = ChangeStatus::CHANGED;
5334 }
5335 }
5336 }
5337 }
5338
5339 ChangeStatus Changed = AAAlign::manifest(A);
5340
5341 Align InheritAlign =
5342 getAssociatedValue().getPointerAlignment(A.getDataLayout());
5343 if (InheritAlign >= getAssumedAlign())
5344 return InstrChanged;
5345 return Changed | InstrChanged;
5346 }
5347
5348 // TODO: Provide a helper to determine the implied ABI alignment and check in
5349 // the existing manifest method and a new one for AAAlignImpl that value
5350 // to avoid making the alignment explicit if it did not improve.
5351
5352 /// See AbstractAttribute::getDeducedAttributes
5353 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
5354 SmallVectorImpl<Attribute> &Attrs) const override {
5355 if (getAssumedAlign() > 1)
5356 Attrs.emplace_back(
5357 Attribute::getWithAlignment(Ctx, Align(getAssumedAlign())));
5358 }
5359
5360 /// See followUsesInMBEC
5361 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
5362 AAAlign::StateType &State) {
5363 bool TrackUse = false;
5364
5365 unsigned int KnownAlign =
5366 getKnownAlignForUse(A, *this, getAssociatedValue(), U, I, TrackUse);
5367 State.takeKnownMaximum(KnownAlign);
5368
5369 return TrackUse;
5370 }
5371
5372 /// See AbstractAttribute::getAsStr().
5373 const std::string getAsStr(Attributor *A) const override {
5374 return "align<" + std::to_string(getKnownAlign().value()) + "-" +
5375 std::to_string(getAssumedAlign().value()) + ">";
5376 }
5377};
5378
5379/// Align attribute for a floating value.
5380struct AAAlignFloating : AAAlignImpl {
5381 AAAlignFloating(const IRPosition &IRP, Attributor &A) : AAAlignImpl(IRP, A) {}
5382
5383 /// See AbstractAttribute::updateImpl(...).
5384 ChangeStatus updateImpl(Attributor &A) override {
5385 const DataLayout &DL = A.getDataLayout();
5386
5387 bool Stripped;
5388 bool UsedAssumedInformation = false;
5390 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
5391 AA::AnyScope, UsedAssumedInformation)) {
5392 Values.push_back({getAssociatedValue(), getCtxI()});
5393 Stripped = false;
5394 } else {
5395 Stripped = Values.size() != 1 ||
5396 Values.front().getValue() != &getAssociatedValue();
5397 }
5398
5399 StateType T;
5400 auto VisitValueCB = [&](Value &V) -> bool {
5402 return true;
5403 const auto *AA = A.getAAFor<AAAlign>(*this, IRPosition::value(V),
5404 DepClassTy::REQUIRED);
5405 if (!AA || (!Stripped && this == AA)) {
5406 int64_t Offset;
5407 unsigned Alignment = 1;
5408 if (const Value *Base =
5410 // TODO: Use AAAlign for the base too.
5411 Align PA = Base->getPointerAlignment(DL);
5412 // BasePointerAddr + Offset = Alignment * Q for some integer Q.
5413 // So we can say that the maximum power of two which is a divisor of
5414 // gcd(Offset, Alignment) is an alignment.
5415
5416 uint32_t gcd =
5417 std::gcd(uint32_t(abs((int32_t)Offset)), uint32_t(PA.value()));
5418 Alignment = llvm::bit_floor(gcd);
5419 } else {
5420 Alignment = V.getPointerAlignment(DL).value();
5421 }
5422 // Use only IR information if we did not strip anything.
5423 T.takeKnownMaximum(Alignment);
5424 T.indicatePessimisticFixpoint();
5425 } else {
5426 // Use abstract attribute information.
5427 const AAAlign::StateType &DS = AA->getState();
5428 T ^= DS;
5429 }
5430 return T.isValidState();
5431 };
5432
5433 for (const auto &VAC : Values) {
5434 if (!VisitValueCB(*VAC.getValue()))
5435 return indicatePessimisticFixpoint();
5436 }
5437
5438 // TODO: If we know we visited all incoming values, thus no are assumed
5439 // dead, we can take the known information from the state T.
5440 return clampStateAndIndicateChange(getState(), T);
5441 }
5442
5443 /// See AbstractAttribute::trackStatistics()
5444 void trackStatistics() const override { STATS_DECLTRACK_FLOATING_ATTR(align) }
5445};
5446
5447/// Align attribute for function return value.
5448struct AAAlignReturned final
5449 : AAReturnedFromReturnedValues<AAAlign, AAAlignImpl> {
5450 using Base = AAReturnedFromReturnedValues<AAAlign, AAAlignImpl>;
5451 AAAlignReturned(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {}
5452
5453 /// See AbstractAttribute::trackStatistics()
5454 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(aligned) }
5455};
5456
5457/// Align attribute for function argument.
5458struct AAAlignArgument final
5459 : AAArgumentFromCallSiteArguments<AAAlign, AAAlignImpl> {
5460 using Base = AAArgumentFromCallSiteArguments<AAAlign, AAAlignImpl>;
5461 AAAlignArgument(const IRPosition &IRP, Attributor &A) : Base(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 (A.getInfoCache().isInvolvedInMustTailCall(*getAssociatedArgument()))
5469 return ChangeStatus::UNCHANGED;
5470 return Base::manifest(A);
5471 }
5472
5473 /// See AbstractAttribute::trackStatistics()
5474 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(aligned) }
5475};
5476
5477struct AAAlignCallSiteArgument final : AAAlignFloating {
5478 AAAlignCallSiteArgument(const IRPosition &IRP, Attributor &A)
5479 : AAAlignFloating(IRP, A) {}
5480
5481 /// See AbstractAttribute::manifest(...).
5482 ChangeStatus manifest(Attributor &A) override {
5483 // If the associated argument is involved in a must-tail call we give up
5484 // because we would need to keep the argument alignments of caller and
5485 // callee in-sync. Just does not seem worth the trouble right now.
5486 if (Argument *Arg = getAssociatedArgument())
5487 if (A.getInfoCache().isInvolvedInMustTailCall(*Arg))
5488 return ChangeStatus::UNCHANGED;
5489 ChangeStatus Changed = AAAlignImpl::manifest(A);
5490 Align InheritAlign =
5491 getAssociatedValue().getPointerAlignment(A.getDataLayout());
5492 if (InheritAlign >= getAssumedAlign())
5493 Changed = ChangeStatus::UNCHANGED;
5494 return Changed;
5495 }
5496
5497 /// See AbstractAttribute::updateImpl(Attributor &A).
5498 ChangeStatus updateImpl(Attributor &A) override {
5499 ChangeStatus Changed = AAAlignFloating::updateImpl(A);
5500 if (Argument *Arg = getAssociatedArgument()) {
5501 // We only take known information from the argument
5502 // so we do not need to track a dependence.
5503 const auto *ArgAlignAA = A.getAAFor<AAAlign>(
5504 *this, IRPosition::argument(*Arg), DepClassTy::NONE);
5505 if (ArgAlignAA)
5506 takeKnownMaximum(ArgAlignAA->getKnownAlign().value());
5507 }
5508 return Changed;
5509 }
5510
5511 /// See AbstractAttribute::trackStatistics()
5512 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(aligned) }
5513};
5514
5515/// Align attribute deduction for a call site return value.
5516struct AAAlignCallSiteReturned final
5517 : AACalleeToCallSite<AAAlign, AAAlignImpl> {
5518 using Base = AACalleeToCallSite<AAAlign, AAAlignImpl>;
5519 AAAlignCallSiteReturned(const IRPosition &IRP, Attributor &A)
5520 : Base(IRP, A) {}
5521
5522 ChangeStatus updateImpl(Attributor &A) override {
5523 Instruction *I = getIRPosition().getCtxI();
5524 if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) {
5525 switch (II->getIntrinsicID()) {
5526 case Intrinsic::ptrmask: {
5527 Align Alignment;
5528 bool Valid = false;
5529
5530 const auto *ConstVals = A.getAAFor<AAPotentialConstantValues>(
5531 *this, IRPosition::value(*II->getOperand(1)), DepClassTy::REQUIRED);
5532 if (ConstVals && ConstVals->isValidState()) {
5533 unsigned ShiftValue =
5534 std::min(ConstVals->getAssumedMinTrailingZeros(),
5535 Value::MaxAlignmentExponent);
5536 Alignment = Align(UINT64_C(1) << ShiftValue);
5537 Valid = true;
5538 }
5539
5540 const auto *AlignAA =
5541 A.getAAFor<AAAlign>(*this, IRPosition::value(*(II->getOperand(0))),
5542 DepClassTy::REQUIRED);
5543 if (AlignAA) {
5544 Alignment = std::max(AlignAA->getAssumedAlign(), Alignment);
5545 Valid = true;
5546 }
5547
5548 if (Valid)
5550 this->getState(),
5551 std::min(this->getAssumedAlign(), Alignment).value());
5552 break;
5553 }
5554 // FIXME: Should introduce target specific sub-attributes and letting
5555 // getAAfor<AAAlign> lead to create sub-attribute to handle target
5556 // specific intrinsics.
5557 case Intrinsic::amdgcn_make_buffer_rsrc: {
5558 const auto *AlignAA =
5559 A.getAAFor<AAAlign>(*this, IRPosition::value(*(II->getOperand(0))),
5560 DepClassTy::REQUIRED);
5561 if (AlignAA)
5563 this->getState(), AlignAA->getAssumedAlign().value());
5564 break;
5565 }
5566 default:
5567 break;
5568 }
5569 }
5570 return Base::updateImpl(A);
5571 };
5572 /// See AbstractAttribute::trackStatistics()
5573 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(align); }
5574};
5575} // namespace
5576
5577/// ------------------ Function No-Return Attribute ----------------------------
5578namespace {
5579struct AANoReturnImpl : public AANoReturn {
5580 AANoReturnImpl(const IRPosition &IRP, Attributor &A) : AANoReturn(IRP, A) {}
5581
5582 /// See AbstractAttribute::initialize(...).
5583 void initialize(Attributor &A) override {
5584 bool IsKnown;
5586 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
5587 (void)IsKnown;
5588 }
5589
5590 /// See AbstractAttribute::getAsStr().
5591 const std::string getAsStr(Attributor *A) const override {
5592 return getAssumed() ? "noreturn" : "may-return";
5593 }
5594
5595 /// See AbstractAttribute::updateImpl(Attributor &A).
5596 ChangeStatus updateImpl(Attributor &A) override {
5597 auto CheckForNoReturn = [](Instruction &) { return false; };
5598 bool UsedAssumedInformation = false;
5599 if (!A.checkForAllInstructions(CheckForNoReturn, *this,
5600 {(unsigned)Instruction::Ret},
5601 UsedAssumedInformation))
5602 return indicatePessimisticFixpoint();
5603 return ChangeStatus::UNCHANGED;
5604 }
5605};
5606
5607struct AANoReturnFunction final : AANoReturnImpl {
5608 AANoReturnFunction(const IRPosition &IRP, Attributor &A)
5609 : AANoReturnImpl(IRP, A) {}
5610
5611 /// See AbstractAttribute::trackStatistics()
5612 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(noreturn) }
5613};
5614
5615/// NoReturn attribute deduction for a call sites.
5616struct AANoReturnCallSite final
5617 : AACalleeToCallSite<AANoReturn, AANoReturnImpl> {
5618 AANoReturnCallSite(const IRPosition &IRP, Attributor &A)
5619 : AACalleeToCallSite<AANoReturn, AANoReturnImpl>(IRP, A) {}
5620
5621 /// See AbstractAttribute::trackStatistics()
5622 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(noreturn); }
5623};
5624} // namespace
5625
5626/// ----------------------- Instance Info ---------------------------------
5627
5628namespace {
5629/// A class to hold the state of for no-capture attributes.
5630struct AAInstanceInfoImpl : public AAInstanceInfo {
5631 AAInstanceInfoImpl(const IRPosition &IRP, Attributor &A)
5632 : AAInstanceInfo(IRP, A) {}
5633
5634 /// See AbstractAttribute::initialize(...).
5635 void initialize(Attributor &A) override {
5636 Value &V = getAssociatedValue();
5637 if (auto *C = dyn_cast<Constant>(&V)) {
5638 if (C->isThreadDependent())
5639 indicatePessimisticFixpoint();
5640 else
5641 indicateOptimisticFixpoint();
5642 return;
5643 }
5644 if (auto *CB = dyn_cast<CallBase>(&V))
5645 if (CB->arg_size() == 0 && !CB->mayHaveSideEffects() &&
5646 !CB->mayReadFromMemory()) {
5647 indicateOptimisticFixpoint();
5648 return;
5649 }
5650 if (auto *I = dyn_cast<Instruction>(&V)) {
5651 const auto *CI =
5652 A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>(
5653 *I->getFunction());
5654 if (mayBeInCycle(CI, I, /* HeaderOnly */ false)) {
5655 indicatePessimisticFixpoint();
5656 return;
5657 }
5658 }
5659 }
5660
5661 /// See AbstractAttribute::updateImpl(...).
5662 ChangeStatus updateImpl(Attributor &A) override {
5663 ChangeStatus Changed = ChangeStatus::UNCHANGED;
5664
5665 Value &V = getAssociatedValue();
5666 const Function *Scope = nullptr;
5667 if (auto *I = dyn_cast<Instruction>(&V))
5668 Scope = I->getFunction();
5669 if (auto *A = dyn_cast<Argument>(&V)) {
5670 Scope = A->getParent();
5671 if (!Scope->hasLocalLinkage())
5672 return Changed;
5673 }
5674 if (!Scope)
5675 return indicateOptimisticFixpoint();
5676
5677 bool IsKnownNoRecurse;
5679 A, this, IRPosition::function(*Scope), DepClassTy::OPTIONAL,
5680 IsKnownNoRecurse))
5681 return Changed;
5682
5683 auto UsePred = [&](const Use &U, bool &Follow) {
5684 const Instruction *UserI = dyn_cast<Instruction>(U.getUser());
5685 if (!UserI || isa<GetElementPtrInst>(UserI) || isa<CastInst>(UserI) ||
5686 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) {
5687 Follow = true;
5688 return true;
5689 }
5690 if (isa<LoadInst>(UserI) || isa<CmpInst>(UserI) ||
5691 (isa<StoreInst>(UserI) &&
5692 cast<StoreInst>(UserI)->getValueOperand() != U.get()))
5693 return true;
5694 if (auto *CB = dyn_cast<CallBase>(UserI)) {
5695 // This check is not guaranteeing uniqueness but for now that we cannot
5696 // end up with two versions of \p U thinking it was one.
5698 if (!Callee || !Callee->hasLocalLinkage())
5699 return true;
5700 if (!CB->isArgOperand(&U))
5701 return false;
5702 const auto *ArgInstanceInfoAA = A.getAAFor<AAInstanceInfo>(
5704 DepClassTy::OPTIONAL);
5705 if (!ArgInstanceInfoAA ||
5706 !ArgInstanceInfoAA->isAssumedUniqueForAnalysis())
5707 return false;
5708 // If this call base might reach the scope again we might forward the
5709 // argument back here. This is very conservative.
5711 A, *CB, *Scope, *this, /* ExclusionSet */ nullptr,
5712 [Scope](const Function &Fn) { return &Fn != Scope; }))
5713 return false;
5714 return true;
5715 }
5716 return false;
5717 };
5718
5719 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) {
5720 if (auto *SI = dyn_cast<StoreInst>(OldU.getUser())) {
5721 auto *Ptr = SI->getPointerOperand()->stripPointerCasts();
5722 if ((isa<AllocaInst>(Ptr) || isNoAliasCall(Ptr)) &&
5723 AA::isDynamicallyUnique(A, *this, *Ptr))
5724 return true;
5725 }
5726 return false;
5727 };
5728
5729 if (!A.checkForAllUses(UsePred, *this, V, /* CheckBBLivenessOnly */ true,
5730 DepClassTy::OPTIONAL,
5731 /* IgnoreDroppableUses */ true, EquivalentUseCB))
5732 return indicatePessimisticFixpoint();
5733
5734 return Changed;
5735 }
5736
5737 /// See AbstractState::getAsStr().
5738 const std::string getAsStr(Attributor *A) const override {
5739 return isAssumedUniqueForAnalysis() ? "<unique [fAa]>" : "<unknown>";
5740 }
5741
5742 /// See AbstractAttribute::trackStatistics()
5743 void trackStatistics() const override {}
5744};
5745
5746/// InstanceInfo attribute for floating values.
5747struct AAInstanceInfoFloating : AAInstanceInfoImpl {
5748 AAInstanceInfoFloating(const IRPosition &IRP, Attributor &A)
5749 : AAInstanceInfoImpl(IRP, A) {}
5750};
5751
5752/// NoCapture attribute for function arguments.
5753struct AAInstanceInfoArgument final : AAInstanceInfoFloating {
5754 AAInstanceInfoArgument(const IRPosition &IRP, Attributor &A)
5755 : AAInstanceInfoFloating(IRP, A) {}
5756};
5757
5758/// InstanceInfo attribute for call site arguments.
5759struct AAInstanceInfoCallSiteArgument final : AAInstanceInfoImpl {
5760 AAInstanceInfoCallSiteArgument(const IRPosition &IRP, Attributor &A)
5761 : AAInstanceInfoImpl(IRP, A) {}
5762
5763 /// See AbstractAttribute::updateImpl(...).
5764 ChangeStatus updateImpl(Attributor &A) override {
5765 // TODO: Once we have call site specific value information we can provide
5766 // call site specific liveness information and then it makes
5767 // sense to specialize attributes for call sites arguments instead of
5768 // redirecting requests to the callee argument.
5769 Argument *Arg = getAssociatedArgument();
5770 if (!Arg)
5771 return indicatePessimisticFixpoint();
5772 const IRPosition &ArgPos = IRPosition::argument(*Arg);
5773 auto *ArgAA =
5774 A.getAAFor<AAInstanceInfo>(*this, ArgPos, DepClassTy::REQUIRED);
5775 if (!ArgAA)
5776 return indicatePessimisticFixpoint();
5777 return clampStateAndIndicateChange(getState(), ArgAA->getState());
5778 }
5779};
5780
5781/// InstanceInfo attribute for function return value.
5782struct AAInstanceInfoReturned final : AAInstanceInfoImpl {
5783 AAInstanceInfoReturned(const IRPosition &IRP, Attributor &A)
5784 : AAInstanceInfoImpl(IRP, A) {
5785 llvm_unreachable("InstanceInfo is not applicable to function returns!");
5786 }
5787
5788 /// See AbstractAttribute::initialize(...).
5789 void initialize(Attributor &A) override {
5790 llvm_unreachable("InstanceInfo is not applicable to function returns!");
5791 }
5792
5793 /// See AbstractAttribute::updateImpl(...).
5794 ChangeStatus updateImpl(Attributor &A) override {
5795 llvm_unreachable("InstanceInfo is not applicable to function returns!");
5796 }
5797};
5798
5799/// InstanceInfo attribute deduction for a call site return value.
5800struct AAInstanceInfoCallSiteReturned final : AAInstanceInfoFloating {
5801 AAInstanceInfoCallSiteReturned(const IRPosition &IRP, Attributor &A)
5802 : AAInstanceInfoFloating(IRP, A) {}
5803};
5804} // namespace
5805
5806/// ----------------------- Variable Capturing ---------------------------------
5808 Attribute::AttrKind ImpliedAttributeKind,
5809 bool IgnoreSubsumingPositions) {
5810 assert(ImpliedAttributeKind == Attribute::Captures &&
5811 "Unexpected attribute kind");
5812 Value &V = IRP.getAssociatedValue();
5813 if (!isa<Constant>(V) && !IRP.isArgumentPosition())
5814 return V.use_empty();
5815
5816 // You cannot "capture" null in the default address space.
5817 //
5818 // FIXME: This should use NullPointerIsDefined to account for the function
5819 // attribute.
5821 V.getType()->getPointerAddressSpace() == 0)) {
5822 return true;
5823 }
5824
5826 A.getAttrs(IRP, {Attribute::Captures}, Attrs,
5827 /* IgnoreSubsumingPositions */ true);
5828 for (const Attribute &Attr : Attrs)
5829 if (capturesNothing(Attr.getCaptureInfo()))
5830 return true;
5831
5833 if (Argument *Arg = IRP.getAssociatedArgument()) {
5835 A.getAttrs(IRPosition::argument(*Arg),
5836 {Attribute::Captures, Attribute::ByVal}, Attrs,
5837 /* IgnoreSubsumingPositions */ true);
5838 bool ArgNoCapture = any_of(Attrs, [](Attribute Attr) {
5839 return Attr.getKindAsEnum() == Attribute::ByVal ||
5841 });
5842 if (ArgNoCapture) {
5843 A.manifestAttrs(IRP, Attribute::getWithCaptureInfo(
5844 V.getContext(), CaptureInfo::none()));
5845 return true;
5846 }
5847 }
5848
5849 if (const Function *F = IRP.getAssociatedFunction()) {
5850 // Check what state the associated function can actually capture.
5853 if (State.isKnown(NO_CAPTURE)) {
5854 A.manifestAttrs(IRP, Attribute::getWithCaptureInfo(V.getContext(),
5856 return true;
5857 }
5858 }
5859
5860 return false;
5861}
5862
5863/// Set the NOT_CAPTURED_IN_MEM and NOT_CAPTURED_IN_RET bits in \p Known
5864/// depending on the ability of the function associated with \p IRP to capture
5865/// state in memory and through "returning/throwing", respectively.
5867 const Function &F,
5868 BitIntegerState &State) {
5869 // TODO: Once we have memory behavior attributes we should use them here.
5870
5871 // If we know we cannot communicate or write to memory, we do not care about
5872 // ptr2int anymore.
5873 bool ReadOnly = F.onlyReadsMemory();
5874 bool NoThrow = F.doesNotThrow();
5875 bool IsVoidReturn = F.getReturnType()->isVoidTy();
5876 if (ReadOnly && NoThrow && IsVoidReturn) {
5877 State.addKnownBits(NO_CAPTURE);
5878 return;
5879 }
5880
5881 // A function cannot capture state in memory if it only reads memory, it can
5882 // however return/throw state and the state might be influenced by the
5883 // pointer value, e.g., loading from a returned pointer might reveal a bit.
5884 if (ReadOnly)
5885 State.addKnownBits(NOT_CAPTURED_IN_MEM);
5886
5887 // A function cannot communicate state back if it does not through
5888 // exceptions and doesn not return values.
5889 if (NoThrow && IsVoidReturn)
5890 State.addKnownBits(NOT_CAPTURED_IN_RET);
5891
5892 // Check existing "returned" attributes.
5893 int ArgNo = IRP.getCalleeArgNo();
5894 if (!NoThrow || ArgNo < 0 ||
5895 !F.getAttributes().hasAttrSomewhere(Attribute::Returned))
5896 return;
5897
5898 for (unsigned U = 0, E = F.arg_size(); U < E; ++U)
5899 if (F.hasParamAttribute(U, Attribute::Returned)) {
5900 if (U == unsigned(ArgNo))
5901 State.removeAssumedBits(NOT_CAPTURED_IN_RET);
5902 else if (ReadOnly)
5903 State.addKnownBits(NO_CAPTURE);
5904 else
5905 State.addKnownBits(NOT_CAPTURED_IN_RET);
5906 break;
5907 }
5908}
5909
5910namespace {
5911/// A class to hold the state of for no-capture attributes.
5912struct AANoCaptureImpl : public AANoCapture {
5913 AANoCaptureImpl(const IRPosition &IRP, Attributor &A) : AANoCapture(IRP, A) {}
5914
5915 /// See AbstractAttribute::initialize(...).
5916 void initialize(Attributor &A) override {
5917 bool IsKnown;
5919 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
5920 (void)IsKnown;
5921 }
5922
5923 /// See AbstractAttribute::updateImpl(...).
5924 ChangeStatus updateImpl(Attributor &A) override;
5925
5926 /// see AbstractAttribute::isAssumedNoCaptureMaybeReturned(...).
5927 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
5928 SmallVectorImpl<Attribute> &Attrs) const override {
5929 if (!isAssumedNoCaptureMaybeReturned())
5930 return;
5931
5932 if (isArgumentPosition()) {
5933 if (isAssumedNoCapture())
5934 Attrs.emplace_back(Attribute::get(Ctx, Attribute::Captures));
5935 else if (ManifestInternal)
5936 Attrs.emplace_back(Attribute::get(Ctx, "no-capture-maybe-returned"));
5937 }
5938 }
5939
5940 /// See AbstractState::getAsStr().
5941 const std::string getAsStr(Attributor *A) const override {
5942 if (isKnownNoCapture())
5943 return "known not-captured";
5944 if (isAssumedNoCapture())
5945 return "assumed not-captured";
5946 if (isKnownNoCaptureMaybeReturned())
5947 return "known not-captured-maybe-returned";
5948 if (isAssumedNoCaptureMaybeReturned())
5949 return "assumed not-captured-maybe-returned";
5950 return "assumed-captured";
5951 }
5952
5953 /// Check the use \p U and update \p State accordingly. Return true if we
5954 /// should continue to update the state.
5955 bool checkUse(Attributor &A, AANoCapture::StateType &State, const Use &U,
5956 bool &Follow) {
5957 Instruction *UInst = cast<Instruction>(U.getUser());
5958 LLVM_DEBUG(dbgs() << "[AANoCapture] Check use: " << *U.get() << " in "
5959 << *UInst << "\n");
5960
5961 // Deal with ptr2int by following uses.
5962 if (isa<PtrToIntInst>(UInst)) {
5963 LLVM_DEBUG(dbgs() << " - ptr2int assume the worst!\n");
5964 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
5965 /* Return */ true);
5966 }
5967
5968 // For stores we already checked if we can follow them, if they make it
5969 // here we give up.
5970 if (isa<StoreInst>(UInst))
5971 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
5972 /* Return */ true);
5973
5974 // Explicitly catch return instructions.
5975 if (isa<ReturnInst>(UInst)) {
5976 if (UInst->getFunction() == getAnchorScope())
5977 return isCapturedIn(State, /* Memory */ false, /* Integer */ false,
5978 /* Return */ true);
5979 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
5980 /* Return */ true);
5981 }
5982
5983 // For now we only use special logic for call sites. However, the tracker
5984 // itself knows about a lot of other non-capturing cases already.
5985 auto *CB = dyn_cast<CallBase>(UInst);
5986 if (!CB || !CB->isArgOperand(&U))
5987 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
5988 /* Return */ true);
5989
5990 unsigned ArgNo = CB->getArgOperandNo(&U);
5991 const IRPosition &CSArgPos = IRPosition::callsite_argument(*CB, ArgNo);
5992 // If we have a abstract no-capture attribute for the argument we can use
5993 // it to justify a non-capture attribute here. This allows recursion!
5994 bool IsKnownNoCapture;
5995 const AANoCapture *ArgNoCaptureAA = nullptr;
5996 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
5997 A, this, CSArgPos, DepClassTy::REQUIRED, IsKnownNoCapture, false,
5998 &ArgNoCaptureAA);
5999 if (IsAssumedNoCapture)
6000 return isCapturedIn(State, /* Memory */ false, /* Integer */ false,
6001 /* Return */ false);
6002 if (ArgNoCaptureAA && ArgNoCaptureAA->isAssumedNoCaptureMaybeReturned()) {
6003 Follow = true;
6004 return isCapturedIn(State, /* Memory */ false, /* Integer */ false,
6005 /* Return */ false);
6006 }
6007
6008 // Lastly, we could not find a reason no-capture can be assumed so we don't.
6009 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
6010 /* Return */ true);
6011 }
6012
6013 /// Update \p State according to \p CapturedInMem, \p CapturedInInt, and
6014 /// \p CapturedInRet, then return true if we should continue updating the
6015 /// state.
6016 static bool isCapturedIn(AANoCapture::StateType &State, bool CapturedInMem,
6017 bool CapturedInInt, bool CapturedInRet) {
6018 LLVM_DEBUG(dbgs() << " - captures [Mem " << CapturedInMem << "|Int "
6019 << CapturedInInt << "|Ret " << CapturedInRet << "]\n");
6020 if (CapturedInMem)
6021 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_MEM);
6022 if (CapturedInInt)
6023 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_INT);
6024 if (CapturedInRet)
6025 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_RET);
6026 return State.isAssumed(AANoCapture::NO_CAPTURE_MAYBE_RETURNED);
6027 }
6028};
6029
6030ChangeStatus AANoCaptureImpl::updateImpl(Attributor &A) {
6031 const IRPosition &IRP = getIRPosition();
6032 Value *V = isArgumentPosition() ? IRP.getAssociatedArgument()
6033 : &IRP.getAssociatedValue();
6034 if (!V)
6035 return indicatePessimisticFixpoint();
6036
6037 const Function *F =
6038 isArgumentPosition() ? IRP.getAssociatedFunction() : IRP.getAnchorScope();
6039
6040 // TODO: Is the checkForAllUses below useful for constants?
6041 if (!F)
6042 return indicatePessimisticFixpoint();
6043
6045 const IRPosition &FnPos = IRPosition::function(*F);
6046
6047 // Readonly means we cannot capture through memory.
6048 bool IsKnown;
6049 if (AA::isAssumedReadOnly(A, FnPos, *this, IsKnown)) {
6050 T.addKnownBits(NOT_CAPTURED_IN_MEM);
6051 if (IsKnown)
6052 addKnownBits(NOT_CAPTURED_IN_MEM);
6053 }
6054
6055 // Make sure all returned values are different than the underlying value.
6056 // TODO: we could do this in a more sophisticated way inside
6057 // AAReturnedValues, e.g., track all values that escape through returns
6058 // directly somehow.
6059 auto CheckReturnedArgs = [&](bool &UsedAssumedInformation) {
6061 if (!A.getAssumedSimplifiedValues(IRPosition::returned(*F), this, Values,
6063 UsedAssumedInformation))
6064 return false;
6065 bool SeenConstant = false;
6066 for (const AA::ValueAndContext &VAC : Values) {
6067 if (isa<Constant>(VAC.getValue())) {
6068 if (SeenConstant)
6069 return false;
6070 SeenConstant = true;
6071 } else if (!isa<Argument>(VAC.getValue()) ||
6072 VAC.getValue() == getAssociatedArgument())
6073 return false;
6074 }
6075 return true;
6076 };
6077
6078 bool IsKnownNoUnwind;
6080 A, this, FnPos, DepClassTy::OPTIONAL, IsKnownNoUnwind)) {
6081 bool IsVoidTy = F->getReturnType()->isVoidTy();
6082 bool UsedAssumedInformation = false;
6083 if (IsVoidTy || CheckReturnedArgs(UsedAssumedInformation)) {
6084 T.addKnownBits(NOT_CAPTURED_IN_RET);
6085 if (T.isKnown(NOT_CAPTURED_IN_MEM))
6087 if (IsKnownNoUnwind && (IsVoidTy || !UsedAssumedInformation)) {
6088 addKnownBits(NOT_CAPTURED_IN_RET);
6089 if (isKnown(NOT_CAPTURED_IN_MEM))
6090 return indicateOptimisticFixpoint();
6091 }
6092 }
6093 }
6094
6095 auto UseCheck = [&](const Use &U, bool &Follow) -> bool {
6096 // TODO(captures): Make this more precise.
6097 UseCaptureInfo CI = DetermineUseCaptureKind(U, /*Base=*/nullptr);
6098 if (capturesNothing(CI))
6099 return true;
6100 if (CI.isPassthrough()) {
6101 Follow = true;
6102 return true;
6103 }
6104 return checkUse(A, T, U, Follow);
6105 };
6106
6107 if (!A.checkForAllUses(UseCheck, *this, *V))
6108 return indicatePessimisticFixpoint();
6109
6110 AANoCapture::StateType &S = getState();
6111 auto Assumed = S.getAssumed();
6112 S.intersectAssumedBits(T.getAssumed());
6113 if (!isAssumedNoCaptureMaybeReturned())
6114 return indicatePessimisticFixpoint();
6115 return Assumed == S.getAssumed() ? ChangeStatus::UNCHANGED
6117}
6118
6119/// NoCapture attribute for function arguments.
6120struct AANoCaptureArgument final : AANoCaptureImpl {
6121 AANoCaptureArgument(const IRPosition &IRP, Attributor &A)
6122 : AANoCaptureImpl(IRP, A) {}
6123
6124 /// See AbstractAttribute::trackStatistics()
6125 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nocapture) }
6126};
6127
6128/// NoCapture attribute for call site arguments.
6129struct AANoCaptureCallSiteArgument final : AANoCaptureImpl {
6130 AANoCaptureCallSiteArgument(const IRPosition &IRP, Attributor &A)
6131 : AANoCaptureImpl(IRP, A) {}
6132
6133 /// See AbstractAttribute::updateImpl(...).
6134 ChangeStatus updateImpl(Attributor &A) override {
6135 // TODO: Once we have call site specific value information we can provide
6136 // call site specific liveness information and then it makes
6137 // sense to specialize attributes for call sites arguments instead of
6138 // redirecting requests to the callee argument.
6139 Argument *Arg = getAssociatedArgument();
6140 if (!Arg)
6141 return indicatePessimisticFixpoint();
6142 const IRPosition &ArgPos = IRPosition::argument(*Arg);
6143 bool IsKnownNoCapture;
6144 const AANoCapture *ArgAA = nullptr;
6146 A, this, ArgPos, DepClassTy::REQUIRED, IsKnownNoCapture, false,
6147 &ArgAA))
6148 return ChangeStatus::UNCHANGED;
6149 if (!ArgAA || !ArgAA->isAssumedNoCaptureMaybeReturned())
6150 return indicatePessimisticFixpoint();
6151 return clampStateAndIndicateChange(getState(), ArgAA->getState());
6152 }
6153
6154 /// See AbstractAttribute::trackStatistics()
6155 void trackStatistics() const override {
6157 };
6158};
6159
6160/// NoCapture attribute for floating values.
6161struct AANoCaptureFloating final : AANoCaptureImpl {
6162 AANoCaptureFloating(const IRPosition &IRP, Attributor &A)
6163 : AANoCaptureImpl(IRP, A) {}
6164
6165 /// See AbstractAttribute::trackStatistics()
6166 void trackStatistics() const override {
6168 }
6169};
6170
6171/// NoCapture attribute for function return value.
6172struct AANoCaptureReturned final : AANoCaptureImpl {
6173 AANoCaptureReturned(const IRPosition &IRP, Attributor &A)
6174 : AANoCaptureImpl(IRP, A) {
6175 llvm_unreachable("NoCapture is not applicable to function returns!");
6176 }
6177
6178 /// See AbstractAttribute::initialize(...).
6179 void initialize(Attributor &A) override {
6180 llvm_unreachable("NoCapture is not applicable to function returns!");
6181 }
6182
6183 /// See AbstractAttribute::updateImpl(...).
6184 ChangeStatus updateImpl(Attributor &A) override {
6185 llvm_unreachable("NoCapture is not applicable to function returns!");
6186 }
6187
6188 /// See AbstractAttribute::trackStatistics()
6189 void trackStatistics() const override {}
6190};
6191
6192/// NoCapture attribute deduction for a call site return value.
6193struct AANoCaptureCallSiteReturned final : AANoCaptureImpl {
6194 AANoCaptureCallSiteReturned(const IRPosition &IRP, Attributor &A)
6195 : AANoCaptureImpl(IRP, A) {}
6196
6197 /// See AbstractAttribute::initialize(...).
6198 void initialize(Attributor &A) override {
6199 const Function *F = getAnchorScope();
6200 // Check what state the associated function can actually capture.
6201 determineFunctionCaptureCapabilities(getIRPosition(), *F, *this);
6202 }
6203
6204 /// See AbstractAttribute::trackStatistics()
6205 void trackStatistics() const override {
6207 }
6208};
6209} // namespace
6210
6211/// ------------------ Value Simplify Attribute ----------------------------
6212
6213bool ValueSimplifyStateType::unionAssumed(std::optional<Value *> Other) {
6214 // FIXME: Add a typecast support.
6217 if (SimplifiedAssociatedValue == std::optional<Value *>(nullptr))
6218 return false;
6219
6220 LLVM_DEBUG({
6222 dbgs() << "[ValueSimplify] is assumed to be "
6223 << **SimplifiedAssociatedValue << "\n";
6224 else
6225 dbgs() << "[ValueSimplify] is assumed to be <none>\n";
6226 });
6227 return true;
6228}
6229
6230namespace {
6231struct AAValueSimplifyImpl : AAValueSimplify {
6232 AAValueSimplifyImpl(const IRPosition &IRP, Attributor &A)
6233 : AAValueSimplify(IRP, A) {}
6234
6235 /// See AbstractAttribute::initialize(...).
6236 void initialize(Attributor &A) override {
6237 if (getAssociatedValue().getType()->isVoidTy())
6238 indicatePessimisticFixpoint();
6239 if (A.hasSimplificationCallback(getIRPosition()))
6240 indicatePessimisticFixpoint();
6241 }
6242
6243 /// See AbstractAttribute::getAsStr().
6244 const std::string getAsStr(Attributor *A) const override {
6245 LLVM_DEBUG({
6246 dbgs() << "SAV: " << (bool)SimplifiedAssociatedValue << " ";
6247 if (SimplifiedAssociatedValue && *SimplifiedAssociatedValue)
6248 dbgs() << "SAV: " << **SimplifiedAssociatedValue << " ";
6249 });
6250 return isValidState() ? (isAtFixpoint() ? "simplified" : "maybe-simple")
6251 : "not-simple";
6252 }
6253
6254 /// See AbstractAttribute::trackStatistics()
6255 void trackStatistics() const override {}
6256
6257 /// See AAValueSimplify::getAssumedSimplifiedValue()
6258 std::optional<Value *>
6259 getAssumedSimplifiedValue(Attributor &A) const override {
6260 return SimplifiedAssociatedValue;
6261 }
6262
6263 /// Ensure the return value is \p V with type \p Ty, if not possible return
6264 /// nullptr. If \p Check is true we will only verify such an operation would
6265 /// suceed and return a non-nullptr value if that is the case. No IR is
6266 /// generated or modified.
6267 static Value *ensureType(Attributor &A, Value &V, Type &Ty, Instruction *CtxI,
6268 bool Check) {
6269 if (auto *TypedV = AA::getWithType(V, Ty))
6270 return TypedV;
6271 if (CtxI && V.getType()->canLosslesslyBitCastTo(&Ty))
6272 return Check ? &V
6273 : BitCastInst::CreatePointerBitCastOrAddrSpaceCast(
6274 &V, &Ty, "", CtxI->getIterator());
6275 return nullptr;
6276 }
6277
6278 /// Reproduce \p I with type \p Ty or return nullptr if that is not posisble.
6279 /// If \p Check is true we will only verify such an operation would suceed and
6280 /// return a non-nullptr value if that is the case. No IR is generated or
6281 /// modified.
6282 static Value *reproduceInst(Attributor &A,
6283 const AbstractAttribute &QueryingAA,
6284 Instruction &I, Type &Ty, Instruction *CtxI,
6285 bool Check, ValueToValueMapTy &VMap) {
6286 assert(CtxI && "Cannot reproduce an instruction without context!");
6287 if (Check && (I.mayReadFromMemory() ||
6288 !isSafeToSpeculativelyExecute(&I, CtxI, /* DT */ nullptr,
6289 /* TLI */ nullptr)))
6290 return nullptr;
6291 for (Value *Op : I.operands()) {
6292 Value *NewOp = reproduceValue(A, QueryingAA, *Op, Ty, CtxI, Check, VMap);
6293 if (!NewOp) {
6294 assert(Check && "Manifest of new value unexpectedly failed!");
6295 return nullptr;
6296 }
6297 if (!Check)
6298 VMap[Op] = NewOp;
6299 }
6300 if (Check)
6301 return &I;
6302
6303 Instruction *CloneI = I.clone();
6304 // TODO: Try to salvage debug information here.
6305 CloneI->setDebugLoc(DebugLoc());
6306 VMap[&I] = CloneI;
6307 CloneI->insertBefore(CtxI->getIterator());
6308 RemapInstruction(CloneI, VMap);
6309 return CloneI;
6310 }
6311
6312 /// Reproduce \p V with type \p Ty or return nullptr if that is not posisble.
6313 /// If \p Check is true we will only verify such an operation would suceed and
6314 /// return a non-nullptr value if that is the case. No IR is generated or
6315 /// modified.
6316 static Value *reproduceValue(Attributor &A,
6317 const AbstractAttribute &QueryingAA, Value &V,
6318 Type &Ty, Instruction *CtxI, bool Check,
6319 ValueToValueMapTy &VMap) {
6320 if (const auto &NewV = VMap.lookup(&V))
6321 return NewV;
6322 bool UsedAssumedInformation = false;
6323 std::optional<Value *> SimpleV = A.getAssumedSimplified(
6324 V, QueryingAA, UsedAssumedInformation, AA::Interprocedural);
6325 if (!SimpleV.has_value())
6326 return PoisonValue::get(&Ty);
6327 Value *EffectiveV = &V;
6328 if (*SimpleV)
6329 EffectiveV = *SimpleV;
6330 if (auto *C = dyn_cast<Constant>(EffectiveV))
6331 return C;
6332 if (CtxI && AA::isValidAtPosition(AA::ValueAndContext(*EffectiveV, *CtxI),
6333 A.getInfoCache()))
6334 return ensureType(A, *EffectiveV, Ty, CtxI, Check);
6335 if (auto *I = dyn_cast<Instruction>(EffectiveV))
6336 if (Value *NewV = reproduceInst(A, QueryingAA, *I, Ty, CtxI, Check, VMap))
6337 return ensureType(A, *NewV, Ty, CtxI, Check);
6338 return nullptr;
6339 }
6340
6341 /// Return a value we can use as replacement for the associated one, or
6342 /// nullptr if we don't have one that makes sense.
6343 Value *manifestReplacementValue(Attributor &A, Instruction *CtxI) const {
6344 Value *NewV = SimplifiedAssociatedValue
6345 ? *SimplifiedAssociatedValue
6346 : UndefValue::get(getAssociatedType());
6347 if (NewV && NewV != &getAssociatedValue()) {
6348 ValueToValueMapTy VMap;
6349 // First verify we can reprduce the value with the required type at the
6350 // context location before we actually start modifying the IR.
6351 if (reproduceValue(A, *this, *NewV, *getAssociatedType(), CtxI,
6352 /* CheckOnly */ true, VMap))
6353 return reproduceValue(A, *this, *NewV, *getAssociatedType(), CtxI,
6354 /* CheckOnly */ false, VMap);
6355 }
6356 return nullptr;
6357 }
6358
6359 /// Helper function for querying AAValueSimplify and updating candidate.
6360 /// \param IRP The value position we are trying to unify with SimplifiedValue
6361 bool checkAndUpdate(Attributor &A, const AbstractAttribute &QueryingAA,
6362 const IRPosition &IRP, bool Simplify = true) {
6363 bool UsedAssumedInformation = false;
6364 std::optional<Value *> QueryingValueSimplified = &IRP.getAssociatedValue();
6365 if (Simplify)
6366 QueryingValueSimplified = A.getAssumedSimplified(
6367 IRP, QueryingAA, UsedAssumedInformation, AA::Interprocedural);
6368 return unionAssumed(QueryingValueSimplified);
6369 }
6370
6371 /// Returns a candidate is found or not
6372 template <typename AAType> bool askSimplifiedValueFor(Attributor &A) {
6373 if (!getAssociatedValue().getType()->isIntegerTy())
6374 return false;
6375
6376 // This will also pass the call base context.
6377 const auto *AA =
6378 A.getAAFor<AAType>(*this, getIRPosition(), DepClassTy::NONE);
6379 if (!AA)
6380 return false;
6381
6382 std::optional<Constant *> COpt = AA->getAssumedConstant(A);
6383
6384 if (!COpt) {
6385 SimplifiedAssociatedValue = std::nullopt;
6386 A.recordDependence(*AA, *this, DepClassTy::OPTIONAL);
6387 return true;
6388 }
6389 if (auto *C = *COpt) {
6390 SimplifiedAssociatedValue = C;
6391 A.recordDependence(*AA, *this, DepClassTy::OPTIONAL);
6392 return true;
6393 }
6394 return false;
6395 }
6396
6397 bool askSimplifiedValueForOtherAAs(Attributor &A) {
6398 if (askSimplifiedValueFor<AAValueConstantRange>(A))
6399 return true;
6400 if (askSimplifiedValueFor<AAPotentialConstantValues>(A))
6401 return true;
6402 return false;
6403 }
6404
6405 /// See AbstractAttribute::manifest(...).
6406 ChangeStatus manifest(Attributor &A) override {
6407 ChangeStatus Changed = ChangeStatus::UNCHANGED;
6408 for (auto &U : getAssociatedValue().uses()) {
6409 // Check if we need to adjust the insertion point to make sure the IR is
6410 // valid.
6411 Instruction *IP = dyn_cast<Instruction>(U.getUser());
6412 if (auto *PHI = dyn_cast_or_null<PHINode>(IP))
6413 IP = PHI->getIncomingBlock(U)->getTerminator();
6414 if (auto *NewV = manifestReplacementValue(A, IP)) {
6415 LLVM_DEBUG(dbgs() << "[ValueSimplify] " << getAssociatedValue()
6416 << " -> " << *NewV << " :: " << *this << "\n");
6417 if (A.changeUseAfterManifest(U, *NewV))
6418 Changed = ChangeStatus::CHANGED;
6419 }
6420 }
6421
6422 return Changed | AAValueSimplify::manifest(A);
6423 }
6424
6425 /// See AbstractState::indicatePessimisticFixpoint(...).
6426 ChangeStatus indicatePessimisticFixpoint() override {
6427 SimplifiedAssociatedValue = &getAssociatedValue();
6428 return AAValueSimplify::indicatePessimisticFixpoint();
6429 }
6430};
6431
6432struct AAValueSimplifyArgument final : AAValueSimplifyImpl {
6433 AAValueSimplifyArgument(const IRPosition &IRP, Attributor &A)
6434 : AAValueSimplifyImpl(IRP, A) {}
6435
6436 void initialize(Attributor &A) override {
6437 AAValueSimplifyImpl::initialize(A);
6438 if (A.hasAttr(getIRPosition(),
6439 {Attribute::InAlloca, Attribute::Preallocated,
6440 Attribute::StructRet, Attribute::Nest, Attribute::ByVal},
6441 /* IgnoreSubsumingPositions */ true))
6442 indicatePessimisticFixpoint();
6443 }
6444
6445 /// See AbstractAttribute::updateImpl(...).
6446 ChangeStatus updateImpl(Attributor &A) override {
6447 // Byval is only replacable if it is readonly otherwise we would write into
6448 // the replaced value and not the copy that byval creates implicitly.
6449 Argument *Arg = getAssociatedArgument();
6450 if (Arg->hasByValAttr()) {
6451 // TODO: We probably need to verify synchronization is not an issue, e.g.,
6452 // there is no race by not copying a constant byval.
6453 bool IsKnown;
6454 if (!AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown))
6455 return indicatePessimisticFixpoint();
6456 }
6457
6458 auto Before = SimplifiedAssociatedValue;
6459
6460 auto PredForCallSite = [&](AbstractCallSite ACS) {
6461 const IRPosition &ACSArgPos =
6462 IRPosition::callsite_argument(ACS, getCallSiteArgNo());
6463 // Check if a coresponding argument was found or if it is on not
6464 // associated (which can happen for callback calls).
6465 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
6466 return false;
6467
6468 // Simplify the argument operand explicitly and check if the result is
6469 // valid in the current scope. This avoids refering to simplified values
6470 // in other functions, e.g., we don't want to say a an argument in a
6471 // static function is actually an argument in a different function.
6472 bool UsedAssumedInformation = false;
6473 std::optional<Constant *> SimpleArgOp =
6474 A.getAssumedConstant(ACSArgPos, *this, UsedAssumedInformation);
6475 if (!SimpleArgOp)
6476 return true;
6477 if (!*SimpleArgOp)
6478 return false;
6479 if (!AA::isDynamicallyUnique(A, *this, **SimpleArgOp))
6480 return false;
6481 return unionAssumed(*SimpleArgOp);
6482 };
6483
6484 // Generate a answer specific to a call site context.
6485 bool Success;
6486 bool UsedAssumedInformation = false;
6487 if (hasCallBaseContext() &&
6488 getCallBaseContext()->getCalledOperand() == Arg->getParent())
6489 Success = PredForCallSite(
6490 AbstractCallSite(&getCallBaseContext()->getCalledOperandUse()));
6491 else
6492 Success = A.checkForAllCallSites(PredForCallSite, *this, true,
6493 UsedAssumedInformation);
6494
6495 if (!Success)
6496 if (!askSimplifiedValueForOtherAAs(A))
6497 return indicatePessimisticFixpoint();
6498
6499 // If a candidate was found in this update, return CHANGED.
6500 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED
6501 : ChangeStatus ::CHANGED;
6502 }
6503
6504 /// See AbstractAttribute::trackStatistics()
6505 void trackStatistics() const override {
6506 STATS_DECLTRACK_ARG_ATTR(value_simplify)
6507 }
6508};
6509
6510struct AAValueSimplifyReturned : AAValueSimplifyImpl {
6511 AAValueSimplifyReturned(const IRPosition &IRP, Attributor &A)
6512 : AAValueSimplifyImpl(IRP, A) {}
6513
6514 /// See AAValueSimplify::getAssumedSimplifiedValue()
6515 std::optional<Value *>
6516 getAssumedSimplifiedValue(Attributor &A) const override {
6517 if (!isValidState())
6518 return nullptr;
6519 return SimplifiedAssociatedValue;
6520 }
6521
6522 /// See AbstractAttribute::updateImpl(...).
6523 ChangeStatus updateImpl(Attributor &A) override {
6524 auto Before = SimplifiedAssociatedValue;
6525
6526 auto ReturnInstCB = [&](Instruction &I) {
6527 auto &RI = cast<ReturnInst>(I);
6528 return checkAndUpdate(
6529 A, *this,
6530 IRPosition::value(*RI.getReturnValue(), getCallBaseContext()));
6531 };
6532
6533 bool UsedAssumedInformation = false;
6534 if (!A.checkForAllInstructions(ReturnInstCB, *this, {Instruction::Ret},
6535 UsedAssumedInformation))
6536 if (!askSimplifiedValueForOtherAAs(A))
6537 return indicatePessimisticFixpoint();
6538
6539 // If a candidate was found in this update, return CHANGED.
6540 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED
6541 : ChangeStatus ::CHANGED;
6542 }
6543
6544 ChangeStatus manifest(Attributor &A) override {
6545 // We queried AAValueSimplify for the returned values so they will be
6546 // replaced if a simplified form was found. Nothing to do here.
6547 return ChangeStatus::UNCHANGED;
6548 }
6549
6550 /// See AbstractAttribute::trackStatistics()
6551 void trackStatistics() const override {
6552 STATS_DECLTRACK_FNRET_ATTR(value_simplify)
6553 }
6554};
6555
6556struct AAValueSimplifyFloating : AAValueSimplifyImpl {
6557 AAValueSimplifyFloating(const IRPosition &IRP, Attributor &A)
6558 : AAValueSimplifyImpl(IRP, A) {}
6559
6560 /// See AbstractAttribute::initialize(...).
6561 void initialize(Attributor &A) override {
6562 AAValueSimplifyImpl::initialize(A);
6563 Value &V = getAnchorValue();
6564
6565 // TODO: add other stuffs
6566 if (isa<Constant>(V))
6567 indicatePessimisticFixpoint();
6568 }
6569
6570 /// See AbstractAttribute::updateImpl(...).
6571 ChangeStatus updateImpl(Attributor &A) override {
6572 auto Before = SimplifiedAssociatedValue;
6573 if (!askSimplifiedValueForOtherAAs(A))
6574 return indicatePessimisticFixpoint();
6575
6576 // If a candidate was found in this update, return CHANGED.
6577 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED
6578 : ChangeStatus ::CHANGED;
6579 }
6580
6581 /// See AbstractAttribute::trackStatistics()
6582 void trackStatistics() const override {
6583 STATS_DECLTRACK_FLOATING_ATTR(value_simplify)
6584 }
6585};
6586
6587struct AAValueSimplifyFunction : AAValueSimplifyImpl {
6588 AAValueSimplifyFunction(const IRPosition &IRP, Attributor &A)
6589 : AAValueSimplifyImpl(IRP, A) {}
6590
6591 /// See AbstractAttribute::initialize(...).
6592 void initialize(Attributor &A) override {
6593 SimplifiedAssociatedValue = nullptr;
6594 indicateOptimisticFixpoint();
6595 }
6596 /// See AbstractAttribute::initialize(...).
6597 ChangeStatus updateImpl(Attributor &A) override {
6599 "AAValueSimplify(Function|CallSite)::updateImpl will not be called");
6600 }
6601 /// See AbstractAttribute::trackStatistics()
6602 void trackStatistics() const override {
6603 STATS_DECLTRACK_FN_ATTR(value_simplify)
6604 }
6605};
6606
6607struct AAValueSimplifyCallSite : AAValueSimplifyFunction {
6608 AAValueSimplifyCallSite(const IRPosition &IRP, Attributor &A)
6609 : AAValueSimplifyFunction(IRP, A) {}
6610 /// See AbstractAttribute::trackStatistics()
6611 void trackStatistics() const override {
6612 STATS_DECLTRACK_CS_ATTR(value_simplify)
6613 }
6614};
6615
6616struct AAValueSimplifyCallSiteReturned : AAValueSimplifyImpl {
6617 AAValueSimplifyCallSiteReturned(const IRPosition &IRP, Attributor &A)
6618 : AAValueSimplifyImpl(IRP, A) {}
6619
6620 void initialize(Attributor &A) override {
6621 AAValueSimplifyImpl::initialize(A);
6622 Function *Fn = getAssociatedFunction();
6623 assert(Fn && "Did expect an associted function");
6624 for (Argument &Arg : Fn->args()) {
6625 if (Arg.hasReturnedAttr()) {
6626 auto IRP = IRPosition::callsite_argument(*cast<CallBase>(getCtxI()),
6627 Arg.getArgNo());
6629 checkAndUpdate(A, *this, IRP))
6630 indicateOptimisticFixpoint();
6631 else
6632 indicatePessimisticFixpoint();
6633 return;
6634 }
6635 }
6636 }
6637
6638 /// See AbstractAttribute::updateImpl(...).
6639 ChangeStatus updateImpl(Attributor &A) override {
6640 return indicatePessimisticFixpoint();
6641 }
6642
6643 void trackStatistics() const override {
6644 STATS_DECLTRACK_CSRET_ATTR(value_simplify)
6645 }
6646};
6647
6648struct AAValueSimplifyCallSiteArgument : AAValueSimplifyFloating {
6649 AAValueSimplifyCallSiteArgument(const IRPosition &IRP, Attributor &A)
6650 : AAValueSimplifyFloating(IRP, A) {}
6651
6652 /// See AbstractAttribute::manifest(...).
6653 ChangeStatus manifest(Attributor &A) override {
6654 ChangeStatus Changed = ChangeStatus::UNCHANGED;
6655 // TODO: We should avoid simplification duplication to begin with.
6656 auto *FloatAA = A.lookupAAFor<AAValueSimplify>(
6657 IRPosition::value(getAssociatedValue()), this, DepClassTy::NONE);
6658 if (FloatAA && FloatAA->getState().isValidState())
6659 return Changed;
6660
6661 if (auto *NewV = manifestReplacementValue(A, getCtxI())) {
6662 Use &U = cast<CallBase>(&getAnchorValue())
6663 ->getArgOperandUse(getCallSiteArgNo());
6664 if (A.changeUseAfterManifest(U, *NewV))
6665 Changed = ChangeStatus::CHANGED;
6666 }
6667
6668 return Changed | AAValueSimplify::manifest(A);
6669 }
6670
6671 void trackStatistics() const override {
6672 STATS_DECLTRACK_CSARG_ATTR(value_simplify)
6673 }
6674};
6675} // namespace
6676
6677/// ----------------------- Heap-To-Stack Conversion ---------------------------
6678namespace {
6679struct AAHeapToStackFunction final : public AAHeapToStack {
6680
6681 static bool isGlobalizedLocal(const CallBase &CB) {
6682 Attribute A = CB.getFnAttr("alloc-family");
6683 return A.isValid() && A.getValueAsString() == "__kmpc_alloc_shared";
6684 }
6685
6686 struct AllocationInfo {
6687 /// The call that allocates the memory.
6688 CallBase *const CB;
6689
6690 /// Whether this allocation is an OpenMP globalized local variable.
6691 bool IsGlobalizedLocal = false;
6692
6693 /// The status wrt. a rewrite.
6694 enum {
6695 STACK_DUE_TO_USE,
6696 STACK_DUE_TO_FREE,
6697 INVALID,
6698 } Status = STACK_DUE_TO_USE;
6699
6700 /// Flag to indicate if we encountered a use that might free this allocation
6701 /// but which is not in the deallocation infos.
6702 bool HasPotentiallyFreeingUnknownUses = false;
6703
6704 /// Flag to indicate that we should place the new alloca in the function
6705 /// entry block rather than where the call site (CB) is.
6706 bool MoveAllocaIntoEntry = true;
6707
6708 /// The set of free calls that use this allocation.
6709 SmallSetVector<CallBase *, 1> PotentialFreeCalls{};
6710 };
6711
6712 struct DeallocationInfo {
6713 /// The call that deallocates the memory.
6714 CallBase *const CB;
6715 /// The value freed by the call.
6716 Value *FreedOp;
6717
6718 /// Flag to indicate if we don't know all objects this deallocation might
6719 /// free.
6720 bool MightFreeUnknownObjects = false;
6721
6722 /// The set of allocation calls that are potentially freed.
6723 SmallSetVector<CallBase *, 1> PotentialAllocationCalls{};
6724 };
6725
6726 AAHeapToStackFunction(const IRPosition &IRP, Attributor &A)
6727 : AAHeapToStack(IRP, A) {}
6728
6729 ~AAHeapToStackFunction() override {
6730 // Ensure we call the destructor so we release any memory allocated in the
6731 // sets.
6732 for (auto &It : AllocationInfos)
6733 It.second->~AllocationInfo();
6734 for (auto &It : DeallocationInfos)
6735 It.second->~DeallocationInfo();
6736 }
6737
6738 void initialize(Attributor &A) override {
6739 AAHeapToStack::initialize(A);
6740
6741 const Function *F = getAnchorScope();
6742 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
6743
6744 auto AllocationIdentifierCB = [&](Instruction &I) {
6745 CallBase *CB = dyn_cast<CallBase>(&I);
6746 if (!CB)
6747 return true;
6748 if (Value *FreedOp = getFreedOperand(CB, TLI)) {
6749 DeallocationInfos[CB] = new (A.Allocator) DeallocationInfo{CB, FreedOp};
6750 return true;
6751 }
6752 // To do heap to stack, we need to know that the allocation itself is
6753 // removable once uses are rewritten, and that we can initialize the
6754 // alloca to the same pattern as the original allocation result.
6755 if (isRemovableAlloc(CB, TLI)) {
6756 auto *I8Ty = Type::getInt8Ty(CB->getParent()->getContext());
6757 if (nullptr != getInitialValueOfAllocation(CB, TLI, I8Ty)) {
6758 AllocationInfo *AI = new (A.Allocator) AllocationInfo{CB};
6759 AllocationInfos[CB] = AI;
6760 AI->IsGlobalizedLocal = isGlobalizedLocal(*CB);
6761 }
6762 }
6763 return true;
6764 };
6765
6766 bool UsedAssumedInformation = false;
6767 bool Success = A.checkForAllCallLikeInstructions(
6768 AllocationIdentifierCB, *this, UsedAssumedInformation,
6769 /* CheckBBLivenessOnly */ false,
6770 /* CheckPotentiallyDead */ true);
6771 (void)Success;
6772 assert(Success && "Did not expect the call base visit callback to fail!");
6773
6775 [](const IRPosition &, const AbstractAttribute *,
6776 bool &) -> std::optional<Value *> { return nullptr; };
6777 for (const auto &It : AllocationInfos)
6778 A.registerSimplificationCallback(IRPosition::callsite_returned(*It.first),
6779 SCB);
6780 for (const auto &It : DeallocationInfos)
6781 A.registerSimplificationCallback(IRPosition::callsite_returned(*It.first),
6782 SCB);
6783 }
6784
6785 const std::string getAsStr(Attributor *A) const override {
6786 unsigned NumH2SMallocs = 0, NumInvalidMallocs = 0;
6787 for (const auto &It : AllocationInfos) {
6788 if (It.second->Status == AllocationInfo::INVALID)
6789 ++NumInvalidMallocs;
6790 else
6791 ++NumH2SMallocs;
6792 }
6793 return "[H2S] Mallocs Good/Bad: " + std::to_string(NumH2SMallocs) + "/" +
6794 std::to_string(NumInvalidMallocs);
6795 }
6796
6797 /// See AbstractAttribute::trackStatistics().
6798 void trackStatistics() const override {
6799 STATS_DECL(
6800 MallocCalls, Function,
6801 "Number of malloc/calloc/aligned_alloc calls converted to allocas");
6802 for (const auto &It : AllocationInfos)
6803 if (It.second->Status != AllocationInfo::INVALID)
6804 ++BUILD_STAT_NAME(MallocCalls, Function);
6805 }
6806
6807 bool isAssumedHeapToStack(const CallBase &CB) const override {
6808 if (isValidState())
6809 if (AllocationInfo *AI =
6810 AllocationInfos.lookup(const_cast<CallBase *>(&CB)))
6811 return AI->Status != AllocationInfo::INVALID;
6812 return false;
6813 }
6814
6815 bool isAssumedHeapToStackRemovedFree(CallBase &CB) const override {
6816 if (!isValidState())
6817 return false;
6818
6819 for (const auto &It : AllocationInfos) {
6820 AllocationInfo &AI = *It.second;
6821 if (AI.Status == AllocationInfo::INVALID)
6822 continue;
6823
6824 if (AI.PotentialFreeCalls.count(&CB))
6825 return true;
6826 }
6827
6828 return false;
6829 }
6830
6831 ChangeStatus manifest(Attributor &A) override {
6832 assert(getState().isValidState() &&
6833 "Attempted to manifest an invalid state!");
6834
6835 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
6836 Function *F = getAnchorScope();
6837 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
6838
6839 for (auto &It : AllocationInfos) {
6840 AllocationInfo &AI = *It.second;
6841 if (AI.Status == AllocationInfo::INVALID)
6842 continue;
6843
6844 for (CallBase *FreeCall : AI.PotentialFreeCalls) {
6845 LLVM_DEBUG(dbgs() << "H2S: Removing free call: " << *FreeCall << "\n");
6846 A.deleteAfterManifest(*FreeCall);
6847 HasChanged = ChangeStatus::CHANGED;
6848 }
6849
6850 LLVM_DEBUG(dbgs() << "H2S: Removing malloc-like call: " << *AI.CB
6851 << "\n");
6852
6853 auto Remark = [&](OptimizationRemark OR) {
6854 if (AI.IsGlobalizedLocal)
6855 return OR << "Moving globalized variable to the stack.";
6856 return OR << "Moving memory allocation from the heap to the stack.";
6857 };
6858 if (AI.IsGlobalizedLocal)
6859 A.emitRemark<OptimizationRemark>(AI.CB, "OMP110", Remark);
6860 else
6861 A.emitRemark<OptimizationRemark>(AI.CB, "HeapToStack", Remark);
6862
6863 const DataLayout &DL = A.getInfoCache().getDL();
6864 Value *Size;
6865 std::optional<APInt> SizeAPI = getSize(A, *this, AI);
6866 if (SizeAPI) {
6867 Size = ConstantInt::get(AI.CB->getContext(), *SizeAPI);
6868 } else {
6869 LLVMContext &Ctx = AI.CB->getContext();
6870 ObjectSizeOpts Opts;
6871 ObjectSizeOffsetEvaluator Eval(DL, TLI, Ctx, Opts);
6872 SizeOffsetValue SizeOffsetPair = Eval.compute(AI.CB);
6873 assert(SizeOffsetPair != ObjectSizeOffsetEvaluator::unknown() &&
6874 cast<ConstantInt>(SizeOffsetPair.Offset)->isZero());
6875 Size = SizeOffsetPair.Size;
6876 }
6877
6878 BasicBlock::iterator IP = AI.MoveAllocaIntoEntry
6879 ? F->getEntryBlock().begin()
6880 : AI.CB->getIterator();
6881
6882 Align Alignment(1);
6883 if (MaybeAlign RetAlign = AI.CB->getRetAlign())
6884 Alignment = std::max(Alignment, *RetAlign);
6885 if (Value *Align = getAllocAlignment(AI.CB, TLI)) {
6886 std::optional<APInt> AlignmentAPI = getAPInt(A, *this, *Align);
6887 assert(AlignmentAPI && AlignmentAPI->getZExtValue() > 0 &&
6888 "Expected an alignment during manifest!");
6889 Alignment =
6890 std::max(Alignment, assumeAligned(AlignmentAPI->getZExtValue()));
6891 }
6892
6893 // TODO: Hoist the alloca towards the function entry.
6894 unsigned AS = DL.getAllocaAddrSpace();
6895 Instruction *Alloca =
6896 new AllocaInst(Type::getInt8Ty(F->getContext()), AS, Size, Alignment,
6897 AI.CB->getName() + ".h2s", IP);
6898
6899 if (Alloca->getType() != AI.CB->getType())
6900 Alloca = BitCastInst::CreatePointerBitCastOrAddrSpaceCast(
6901 Alloca, AI.CB->getType(), "malloc_cast", AI.CB->getIterator());
6902
6903 auto *I8Ty = Type::getInt8Ty(F->getContext());
6904 auto *InitVal = getInitialValueOfAllocation(AI.CB, TLI, I8Ty);
6905 assert(InitVal &&
6906 "Must be able to materialize initial memory state of allocation");
6907
6908 A.changeAfterManifest(IRPosition::inst(*AI.CB), *Alloca);
6909
6910 if (auto *II = dyn_cast<InvokeInst>(AI.CB)) {
6911 auto *NBB = II->getNormalDest();
6912 UncondBrInst::Create(NBB, AI.CB->getParent());
6913 A.deleteAfterManifest(*AI.CB);
6914 } else {
6915 A.deleteAfterManifest(*AI.CB);
6916 }
6917
6918 // Initialize the alloca with the same value as used by the allocation
6919 // function. We can skip undef as the initial value of an alloc is
6920 // undef, and the memset would simply end up being DSEd.
6921 if (!isa<UndefValue>(InitVal)) {
6922 IRBuilder<> Builder(Alloca->getNextNode());
6923 // TODO: Use alignment above if align!=1
6924 Builder.CreateMemSet(Alloca, InitVal, Size, std::nullopt);
6925 }
6926 HasChanged = ChangeStatus::CHANGED;
6927 }
6928
6929 return HasChanged;
6930 }
6931
6932 std::optional<APInt> getAPInt(Attributor &A, const AbstractAttribute &AA,
6933 Value &V) {
6934 bool UsedAssumedInformation = false;
6935 std::optional<Constant *> SimpleV =
6936 A.getAssumedConstant(V, AA, UsedAssumedInformation);
6937 if (!SimpleV)
6938 return APInt(64, 0);
6939 if (auto *CI = dyn_cast_or_null<ConstantInt>(*SimpleV))
6940 return CI->getValue();
6941 return std::nullopt;
6942 }
6943
6944 std::optional<APInt> getSize(Attributor &A, const AbstractAttribute &AA,
6945 AllocationInfo &AI) {
6946 auto Mapper = [&](const Value *V) -> const Value * {
6947 bool UsedAssumedInformation = false;
6948 if (std::optional<Constant *> SimpleV =
6949 A.getAssumedConstant(*V, AA, UsedAssumedInformation))
6950 if (*SimpleV)
6951 return *SimpleV;
6952 return V;
6953 };
6954
6955 const Function *F = getAnchorScope();
6956 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
6957 return getAllocSize(AI.CB, TLI, Mapper);
6958 }
6959
6960 /// Collection of all malloc-like calls in a function with associated
6961 /// information.
6962 MapVector<CallBase *, AllocationInfo *> AllocationInfos;
6963
6964 /// Collection of all free-like calls in a function with associated
6965 /// information.
6966 MapVector<CallBase *, DeallocationInfo *> DeallocationInfos;
6967
6968 ChangeStatus updateImpl(Attributor &A) override;
6969};
6970
6971ChangeStatus AAHeapToStackFunction::updateImpl(Attributor &A) {
6973 const Function *F = getAnchorScope();
6974 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
6975
6976 const auto *LivenessAA =
6977 A.getAAFor<AAIsDead>(*this, IRPosition::function(*F), DepClassTy::NONE);
6978
6979 MustBeExecutedContextExplorer *Explorer =
6980 A.getInfoCache().getMustBeExecutedContextExplorer();
6981
6982 bool StackIsAccessibleByOtherThreads =
6983 A.getInfoCache().stackIsAccessibleByOtherThreads();
6984
6985 LoopInfo *LI =
6986 A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(*F);
6987 std::optional<bool> MayContainIrreducibleControl;
6988 auto IsInLoop = [&](BasicBlock &BB) {
6989 if (&F->getEntryBlock() == &BB)
6990 return false;
6991 if (!MayContainIrreducibleControl.has_value())
6992 MayContainIrreducibleControl = mayContainIrreducibleControl(*F, LI);
6993 if (*MayContainIrreducibleControl)
6994 return true;
6995 if (!LI)
6996 return true;
6997 return LI->getLoopFor(&BB) != nullptr;
6998 };
6999
7000 // Flag to ensure we update our deallocation information at most once per
7001 // updateImpl call and only if we use the free check reasoning.
7002 bool HasUpdatedFrees = false;
7003
7004 auto UpdateFrees = [&]() {
7005 HasUpdatedFrees = true;
7006
7007 for (auto &It : DeallocationInfos) {
7008 DeallocationInfo &DI = *It.second;
7009 // For now we cannot use deallocations that have unknown inputs, skip
7010 // them.
7011 if (DI.MightFreeUnknownObjects)
7012 continue;
7013
7014 // No need to analyze dead calls, ignore them instead.
7015 bool UsedAssumedInformation = false;
7016 if (A.isAssumedDead(*DI.CB, this, LivenessAA, UsedAssumedInformation,
7017 /* CheckBBLivenessOnly */ true))
7018 continue;
7019
7020 // Use the non-optimistic version to get the freed object.
7021 Value *Obj = getUnderlyingObject(DI.FreedOp);
7022 if (!Obj) {
7023 LLVM_DEBUG(dbgs() << "[H2S] Unknown underlying object for free!\n");
7024 DI.MightFreeUnknownObjects = true;
7025 continue;
7026 }
7027
7028 // Free of null and undef can be ignored as no-ops (or UB in the latter
7029 // case).
7031 continue;
7032
7033 CallBase *ObjCB = dyn_cast<CallBase>(Obj);
7034 if (!ObjCB) {
7035 LLVM_DEBUG(dbgs() << "[H2S] Free of a non-call object: " << *Obj
7036 << "\n");
7037 DI.MightFreeUnknownObjects = true;
7038 continue;
7039 }
7040
7041 AllocationInfo *AI = AllocationInfos.lookup(ObjCB);
7042 if (!AI) {
7043 LLVM_DEBUG(dbgs() << "[H2S] Free of a non-allocation object: " << *Obj
7044 << "\n");
7045 DI.MightFreeUnknownObjects = true;
7046 continue;
7047 }
7048
7049 DI.PotentialAllocationCalls.insert(ObjCB);
7050 }
7051 };
7052
7053 auto FreeCheck = [&](AllocationInfo &AI) {
7054 // If the stack is not accessible by other threads, the "must-free" logic
7055 // doesn't apply as the pointer could be shared and needs to be places in
7056 // "shareable" memory.
7057 if (!StackIsAccessibleByOtherThreads) {
7058 bool IsKnownNoSycn;
7060 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNoSycn)) {
7061 LLVM_DEBUG(
7062 dbgs() << "[H2S] found an escaping use, stack is not accessible by "
7063 "other threads and function is not nosync:\n");
7064 return false;
7065 }
7066 }
7067 if (!HasUpdatedFrees)
7068 UpdateFrees();
7069
7070 // TODO: Allow multi exit functions that have different free calls.
7071 if (AI.PotentialFreeCalls.size() != 1) {
7072 LLVM_DEBUG(dbgs() << "[H2S] did not find one free call but "
7073 << AI.PotentialFreeCalls.size() << "\n");
7074 return false;
7075 }
7076 CallBase *UniqueFree = *AI.PotentialFreeCalls.begin();
7077 DeallocationInfo *DI = DeallocationInfos.lookup(UniqueFree);
7078 if (!DI) {
7079 LLVM_DEBUG(
7080 dbgs() << "[H2S] unique free call was not known as deallocation call "
7081 << *UniqueFree << "\n");
7082 return false;
7083 }
7084 if (DI->MightFreeUnknownObjects) {
7085 LLVM_DEBUG(
7086 dbgs() << "[H2S] unique free call might free unknown allocations\n");
7087 return false;
7088 }
7089 if (DI->PotentialAllocationCalls.empty())
7090 return true;
7091 if (DI->PotentialAllocationCalls.size() > 1) {
7092 LLVM_DEBUG(dbgs() << "[H2S] unique free call might free "
7093 << DI->PotentialAllocationCalls.size()
7094 << " different allocations\n");
7095 return false;
7096 }
7097 if (*DI->PotentialAllocationCalls.begin() != AI.CB) {
7098 LLVM_DEBUG(
7099 dbgs()
7100 << "[H2S] unique free call not known to free this allocation but "
7101 << **DI->PotentialAllocationCalls.begin() << "\n");
7102 return false;
7103 }
7104
7105 // __kmpc_alloc_shared and __kmpc_free_shared are by construction matched.
7106 if (!AI.IsGlobalizedLocal) {
7107 Instruction *CtxI = isa<InvokeInst>(AI.CB) ? AI.CB : AI.CB->getNextNode();
7108 if (!Explorer || !Explorer->findInContextOf(UniqueFree, CtxI)) {
7109 LLVM_DEBUG(dbgs() << "[H2S] unique free call might not be executed "
7110 "with the allocation "
7111 << *UniqueFree << "\n");
7112 return false;
7113 }
7114 }
7115 return true;
7116 };
7117
7118 auto UsesCheck = [&](AllocationInfo &AI) {
7119 bool ValidUsesOnly = true;
7120
7121 auto Pred = [&](const Use &U, bool &Follow) -> bool {
7122 Instruction *UserI = cast<Instruction>(U.getUser());
7123 if (isa<LoadInst>(UserI))
7124 return true;
7125 if (auto *SI = dyn_cast<StoreInst>(UserI)) {
7126 if (SI->getValueOperand() == U.get()) {
7128 << "[H2S] escaping store to memory: " << *UserI << "\n");
7129 ValidUsesOnly = false;
7130 } else {
7131 // A store into the malloc'ed memory is fine.
7132 }
7133 return true;
7134 }
7135 if (auto *CB = dyn_cast<CallBase>(UserI)) {
7136 if (!CB->isArgOperand(&U) || CB->isLifetimeStartOrEnd())
7137 return true;
7138 if (DeallocationInfos.count(CB)) {
7139 AI.PotentialFreeCalls.insert(CB);
7140 return true;
7141 }
7142
7143 unsigned ArgNo = CB->getArgOperandNo(&U);
7144 auto CBIRP = IRPosition::callsite_argument(*CB, ArgNo);
7145
7146 bool IsKnownNoCapture;
7147 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
7148 A, this, CBIRP, DepClassTy::OPTIONAL, IsKnownNoCapture);
7149
7150 // If a call site argument use is nofree, we are fine.
7151 bool IsKnownNoFree;
7152 bool IsAssumedNoFree = AA::hasAssumedIRAttr<Attribute::NoFree>(
7153 A, this, CBIRP, DepClassTy::OPTIONAL, IsKnownNoFree);
7154
7155 if (!IsAssumedNoCapture ||
7156 (!AI.IsGlobalizedLocal && !IsAssumedNoFree)) {
7157 AI.HasPotentiallyFreeingUnknownUses |= !IsAssumedNoFree;
7158
7159 // Emit a missed remark if this is missed OpenMP globalization.
7160 auto Remark = [&](OptimizationRemarkMissed ORM) {
7161 return ORM
7162 << "Could not move globalized variable to the stack. "
7163 "Variable is potentially captured in call. Mark "
7164 "parameter as `__attribute__((noescape))` to override.";
7165 };
7166
7167 if (ValidUsesOnly && AI.IsGlobalizedLocal)
7168 A.emitRemark<OptimizationRemarkMissed>(CB, "OMP113", Remark);
7169
7170 LLVM_DEBUG(dbgs() << "[H2S] Bad user: " << *UserI << "\n");
7171 ValidUsesOnly = false;
7172 }
7173 return true;
7174 }
7175
7176 if (isa<GetElementPtrInst>(UserI) || isa<BitCastInst>(UserI) ||
7177 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) {
7178 Follow = true;
7179 return true;
7180 }
7181 // Unknown user for which we can not track uses further (in a way that
7182 // makes sense).
7183 LLVM_DEBUG(dbgs() << "[H2S] Unknown user: " << *UserI << "\n");
7184 ValidUsesOnly = false;
7185 return true;
7186 };
7187 if (!A.checkForAllUses(Pred, *this, *AI.CB, /* CheckBBLivenessOnly */ false,
7188 DepClassTy::OPTIONAL, /* IgnoreDroppableUses */ true,
7189 [&](const Use &OldU, const Use &NewU) {
7190 auto *SI = dyn_cast<StoreInst>(OldU.getUser());
7191 return !SI || StackIsAccessibleByOtherThreads ||
7192 AA::isAssumedThreadLocalObject(
7193 A, *SI->getPointerOperand(), *this);
7194 }))
7195 return false;
7196 return ValidUsesOnly;
7197 };
7198
7199 // The actual update starts here. We look at all allocations and depending on
7200 // their status perform the appropriate check(s).
7201 for (auto &It : AllocationInfos) {
7202 AllocationInfo &AI = *It.second;
7203 if (AI.Status == AllocationInfo::INVALID)
7204 continue;
7205
7206 if (Value *Align = getAllocAlignment(AI.CB, TLI)) {
7207 std::optional<APInt> APAlign = getAPInt(A, *this, *Align);
7208 if (!APAlign) {
7209 // Can't generate an alloca which respects the required alignment
7210 // on the allocation.
7211 LLVM_DEBUG(dbgs() << "[H2S] Unknown allocation alignment: " << *AI.CB
7212 << "\n");
7213 AI.Status = AllocationInfo::INVALID;
7215 continue;
7216 }
7217 if (APAlign->ugt(llvm::Value::MaximumAlignment) ||
7218 !APAlign->isPowerOf2()) {
7219 LLVM_DEBUG(dbgs() << "[H2S] Invalid allocation alignment: " << APAlign
7220 << "\n");
7221 AI.Status = AllocationInfo::INVALID;
7223 continue;
7224 }
7225 }
7226
7227 std::optional<APInt> Size = getSize(A, *this, AI);
7228 if (!AI.IsGlobalizedLocal && MaxHeapToStackSize != -1) {
7229 if (!Size || Size->ugt(MaxHeapToStackSize)) {
7230 LLVM_DEBUG({
7231 if (!Size)
7232 dbgs() << "[H2S] Unknown allocation size: " << *AI.CB << "\n";
7233 else
7234 dbgs() << "[H2S] Allocation size too large: " << *AI.CB << " vs. "
7235 << MaxHeapToStackSize << "\n";
7236 });
7237
7238 AI.Status = AllocationInfo::INVALID;
7240 continue;
7241 }
7242 }
7243
7244 switch (AI.Status) {
7245 case AllocationInfo::STACK_DUE_TO_USE:
7246 if (UsesCheck(AI))
7247 break;
7248 AI.Status = AllocationInfo::STACK_DUE_TO_FREE;
7249 [[fallthrough]];
7250 case AllocationInfo::STACK_DUE_TO_FREE:
7251 if (FreeCheck(AI))
7252 break;
7253 AI.Status = AllocationInfo::INVALID;
7255 break;
7256 case AllocationInfo::INVALID:
7257 llvm_unreachable("Invalid allocations should never reach this point!");
7258 };
7259
7260 // Check if we still think we can move it into the entry block. If the
7261 // alloca comes from a converted __kmpc_alloc_shared then we can usually
7262 // ignore the potential complications associated with loops.
7263 bool IsGlobalizedLocal = AI.IsGlobalizedLocal;
7264 if (AI.MoveAllocaIntoEntry &&
7265 (!Size.has_value() ||
7266 (!IsGlobalizedLocal && IsInLoop(*AI.CB->getParent()))))
7267 AI.MoveAllocaIntoEntry = false;
7268 }
7269
7270 return Changed;
7271}
7272} // namespace
7273
7274/// ----------------------- Privatizable Pointers ------------------------------
7275namespace {
7276struct AAPrivatizablePtrImpl : public AAPrivatizablePtr {
7277 AAPrivatizablePtrImpl(const IRPosition &IRP, Attributor &A)
7278 : AAPrivatizablePtr(IRP, A), PrivatizableType(std::nullopt) {}
7279
7280 ChangeStatus indicatePessimisticFixpoint() override {
7281 AAPrivatizablePtr::indicatePessimisticFixpoint();
7282 PrivatizableType = nullptr;
7283 return ChangeStatus::CHANGED;
7284 }
7285
7286 /// Identify the type we can chose for a private copy of the underlying
7287 /// argument. std::nullopt means it is not clear yet, nullptr means there is
7288 /// none.
7289 virtual std::optional<Type *> identifyPrivatizableType(Attributor &A) = 0;
7290
7291 /// Return a privatizable type that encloses both T0 and T1.
7292 /// TODO: This is merely a stub for now as we should manage a mapping as well.
7293 std::optional<Type *> combineTypes(std::optional<Type *> T0,
7294 std::optional<Type *> T1) {
7295 if (!T0)
7296 return T1;
7297 if (!T1)
7298 return T0;
7299 if (T0 == T1)
7300 return T0;
7301 return nullptr;
7302 }
7303
7304 std::optional<Type *> getPrivatizableType() const override {
7305 return PrivatizableType;
7306 }
7307
7308 const std::string getAsStr(Attributor *A) const override {
7309 return isAssumedPrivatizablePtr() ? "[priv]" : "[no-priv]";
7310 }
7311
7312protected:
7313 std::optional<Type *> PrivatizableType;
7314};
7315
7316// TODO: Do this for call site arguments (probably also other values) as well.
7317
7318struct AAPrivatizablePtrArgument final : public AAPrivatizablePtrImpl {
7319 AAPrivatizablePtrArgument(const IRPosition &IRP, Attributor &A)
7320 : AAPrivatizablePtrImpl(IRP, A) {}
7321
7322 /// See AAPrivatizablePtrImpl::identifyPrivatizableType(...)
7323 std::optional<Type *> identifyPrivatizableType(Attributor &A) override {
7324 // If this is a byval argument and we know all the call sites (so we can
7325 // rewrite them), there is no need to check them explicitly.
7326 bool UsedAssumedInformation = false;
7328 A.getAttrs(getIRPosition(), {Attribute::ByVal}, Attrs,
7329 /* IgnoreSubsumingPositions */ true);
7330 if (!Attrs.empty() &&
7331 A.checkForAllCallSites([](AbstractCallSite ACS) { return true; }, *this,
7332 true, UsedAssumedInformation))
7333 return Attrs[0].getValueAsType();
7334
7335 std::optional<Type *> Ty;
7336 unsigned ArgNo = getIRPosition().getCallSiteArgNo();
7337
7338 // Make sure the associated call site argument has the same type at all call
7339 // sites and it is an allocation we know is safe to privatize, for now that
7340 // means we only allow alloca instructions.
7341 // TODO: We can additionally analyze the accesses in the callee to create
7342 // the type from that information instead. That is a little more
7343 // involved and will be done in a follow up patch.
7344 auto CallSiteCheck = [&](AbstractCallSite ACS) {
7345 IRPosition ACSArgPos = IRPosition::callsite_argument(ACS, ArgNo);
7346 // Check if a coresponding argument was found or if it is one not
7347 // associated (which can happen for callback calls).
7348 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
7349 return false;
7350
7351 // Check that all call sites agree on a type.
7352 auto *PrivCSArgAA =
7353 A.getAAFor<AAPrivatizablePtr>(*this, ACSArgPos, DepClassTy::REQUIRED);
7354 if (!PrivCSArgAA)
7355 return false;
7356 std::optional<Type *> CSTy = PrivCSArgAA->getPrivatizableType();
7357
7358 LLVM_DEBUG({
7359 dbgs() << "[AAPrivatizablePtr] ACSPos: " << ACSArgPos << ", CSTy: ";
7360 if (CSTy && *CSTy)
7361 (*CSTy)->print(dbgs());
7362 else if (CSTy)
7363 dbgs() << "<nullptr>";
7364 else
7365 dbgs() << "<none>";
7366 });
7367
7368 Ty = combineTypes(Ty, CSTy);
7369
7370 LLVM_DEBUG({
7371 dbgs() << " : New Type: ";
7372 if (Ty && *Ty)
7373 (*Ty)->print(dbgs());
7374 else if (Ty)
7375 dbgs() << "<nullptr>";
7376 else
7377 dbgs() << "<none>";
7378 dbgs() << "\n";
7379 });
7380
7381 return !Ty || *Ty;
7382 };
7383
7384 if (!A.checkForAllCallSites(CallSiteCheck, *this, true,
7385 UsedAssumedInformation))
7386 return nullptr;
7387 return Ty;
7388 }
7389
7390 /// See AbstractAttribute::updateImpl(...).
7391 ChangeStatus updateImpl(Attributor &A) override {
7392 PrivatizableType = identifyPrivatizableType(A);
7393 if (!PrivatizableType)
7394 return ChangeStatus::UNCHANGED;
7395 if (!*PrivatizableType)
7396 return indicatePessimisticFixpoint();
7397
7398 // The dependence is optional so we don't give up once we give up on the
7399 // alignment.
7400 A.getAAFor<AAAlign>(*this, IRPosition::value(getAssociatedValue()),
7401 DepClassTy::OPTIONAL);
7402
7403 // Avoid arguments with padding for now.
7404 if (!A.hasAttr(getIRPosition(), Attribute::ByVal) &&
7405 !isDenselyPacked(*PrivatizableType, A.getInfoCache().getDL())) {
7406 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Padding detected\n");
7407 return indicatePessimisticFixpoint();
7408 }
7409
7410 // Collect the types that will replace the privatizable type in the function
7411 // signature.
7412 SmallVector<Type *, 16> ReplacementTypes;
7413 identifyReplacementTypes(*PrivatizableType, ReplacementTypes);
7414
7415 // Verify callee and caller agree on how the promoted argument would be
7416 // passed.
7417 Function &Fn = *getIRPosition().getAnchorScope();
7418 const auto *TTI =
7419 A.getInfoCache().getAnalysisResultForFunction<TargetIRAnalysis>(Fn);
7420 if (!TTI) {
7421 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Missing TTI for function "
7422 << Fn.getName() << "\n");
7423 return indicatePessimisticFixpoint();
7424 }
7425
7426 auto CallSiteCheck = [&](AbstractCallSite ACS) {
7427 CallBase *CB = ACS.getInstruction();
7428 return TTI->areTypesABICompatible(
7429 CB->getCaller(),
7431 ReplacementTypes);
7432 };
7433 bool UsedAssumedInformation = false;
7434 if (!A.checkForAllCallSites(CallSiteCheck, *this, true,
7435 UsedAssumedInformation)) {
7436 LLVM_DEBUG(
7437 dbgs() << "[AAPrivatizablePtr] ABI incompatibility detected for "
7438 << Fn.getName() << "\n");
7439 return indicatePessimisticFixpoint();
7440 }
7441
7442 // Register a rewrite of the argument.
7443 Argument *Arg = getAssociatedArgument();
7444 if (!A.isValidFunctionSignatureRewrite(*Arg, ReplacementTypes)) {
7445 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Rewrite not valid\n");
7446 return indicatePessimisticFixpoint();
7447 }
7448
7449 unsigned ArgNo = Arg->getArgNo();
7450
7451 // Helper to check if for the given call site the associated argument is
7452 // passed to a callback where the privatization would be different.
7453 auto IsCompatiblePrivArgOfCallback = [&](CallBase &CB) {
7454 SmallVector<const Use *, 4> CallbackUses;
7455 AbstractCallSite::getCallbackUses(CB, CallbackUses);
7456 for (const Use *U : CallbackUses) {
7457 AbstractCallSite CBACS(U);
7458 assert(CBACS && CBACS.isCallbackCall());
7459 for (Argument &CBArg : CBACS.getCalledFunction()->args()) {
7460 int CBArgNo = CBACS.getCallArgOperandNo(CBArg);
7461
7462 LLVM_DEBUG({
7463 dbgs()
7464 << "[AAPrivatizablePtr] Argument " << *Arg
7465 << "check if can be privatized in the context of its parent ("
7466 << Arg->getParent()->getName()
7467 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7468 "callback ("
7469 << CBArgNo << "@" << CBACS.getCalledFunction()->getName()
7470 << ")\n[AAPrivatizablePtr] " << CBArg << " : "
7471 << CBACS.getCallArgOperand(CBArg) << " vs "
7472 << CB.getArgOperand(ArgNo) << "\n"
7473 << "[AAPrivatizablePtr] " << CBArg << " : "
7474 << CBACS.getCallArgOperandNo(CBArg) << " vs " << ArgNo << "\n";
7475 });
7476
7477 if (CBArgNo != int(ArgNo))
7478 continue;
7479 const auto *CBArgPrivAA = A.getAAFor<AAPrivatizablePtr>(
7480 *this, IRPosition::argument(CBArg), DepClassTy::REQUIRED);
7481 if (CBArgPrivAA && CBArgPrivAA->isValidState()) {
7482 auto CBArgPrivTy = CBArgPrivAA->getPrivatizableType();
7483 if (!CBArgPrivTy)
7484 continue;
7485 if (*CBArgPrivTy == PrivatizableType)
7486 continue;
7487 }
7488
7489 LLVM_DEBUG({
7490 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
7491 << " cannot be privatized in the context of its parent ("
7492 << Arg->getParent()->getName()
7493 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7494 "callback ("
7495 << CBArgNo << "@" << CBACS.getCalledFunction()->getName()
7496 << ").\n[AAPrivatizablePtr] for which the argument "
7497 "privatization is not compatible.\n";
7498 });
7499 return false;
7500 }
7501 }
7502 return true;
7503 };
7504
7505 // Helper to check if for the given call site the associated argument is
7506 // passed to a direct call where the privatization would be different.
7507 auto IsCompatiblePrivArgOfDirectCS = [&](AbstractCallSite ACS) {
7508 CallBase *DC = cast<CallBase>(ACS.getInstruction());
7509 int DCArgNo = ACS.getCallArgOperandNo(ArgNo);
7510 assert(DCArgNo >= 0 && unsigned(DCArgNo) < DC->arg_size() &&
7511 "Expected a direct call operand for callback call operand");
7512
7513 Function *DCCallee =
7515 LLVM_DEBUG({
7516 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
7517 << " check if be privatized in the context of its parent ("
7518 << Arg->getParent()->getName()
7519 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7520 "direct call of ("
7521 << DCArgNo << "@" << DCCallee->getName() << ").\n";
7522 });
7523
7524 if (unsigned(DCArgNo) < DCCallee->arg_size()) {
7525 const auto *DCArgPrivAA = A.getAAFor<AAPrivatizablePtr>(
7526 *this, IRPosition::argument(*DCCallee->getArg(DCArgNo)),
7527 DepClassTy::REQUIRED);
7528 if (DCArgPrivAA && DCArgPrivAA->isValidState()) {
7529 auto DCArgPrivTy = DCArgPrivAA->getPrivatizableType();
7530 if (!DCArgPrivTy)
7531 return true;
7532 if (*DCArgPrivTy == PrivatizableType)
7533 return true;
7534 }
7535 }
7536
7537 LLVM_DEBUG({
7538 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
7539 << " cannot be privatized in the context of its parent ("
7540 << Arg->getParent()->getName()
7541 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7542 "direct call of ("
7544 << ").\n[AAPrivatizablePtr] for which the argument "
7545 "privatization is not compatible.\n";
7546 });
7547 return false;
7548 };
7549
7550 // Helper to check if the associated argument is used at the given abstract
7551 // call site in a way that is incompatible with the privatization assumed
7552 // here.
7553 auto IsCompatiblePrivArgOfOtherCallSite = [&](AbstractCallSite ACS) {
7554 if (ACS.isDirectCall())
7555 return IsCompatiblePrivArgOfCallback(*ACS.getInstruction());
7556 if (ACS.isCallbackCall())
7557 return IsCompatiblePrivArgOfDirectCS(ACS);
7558 return false;
7559 };
7560
7561 if (!A.checkForAllCallSites(IsCompatiblePrivArgOfOtherCallSite, *this, true,
7562 UsedAssumedInformation))
7563 return indicatePessimisticFixpoint();
7564
7565 return ChangeStatus::UNCHANGED;
7566 }
7567
7568 /// Given a type to private \p PrivType, collect the constituates (which are
7569 /// used) in \p ReplacementTypes.
7570 static void
7571 identifyReplacementTypes(Type *PrivType,
7572 SmallVectorImpl<Type *> &ReplacementTypes) {
7573 // TODO: For now we expand the privatization type to the fullest which can
7574 // lead to dead arguments that need to be removed later.
7575 assert(PrivType && "Expected privatizable type!");
7576
7577 // Traverse the type, extract constituate types on the outermost level.
7578 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) {
7579 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++)
7580 ReplacementTypes.push_back(PrivStructType->getElementType(u));
7581 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) {
7582 ReplacementTypes.append(PrivArrayType->getNumElements(),
7583 PrivArrayType->getElementType());
7584 } else {
7585 ReplacementTypes.push_back(PrivType);
7586 }
7587 }
7588
7589 /// Initialize \p Base according to the type \p PrivType at position \p IP.
7590 /// The values needed are taken from the arguments of \p F starting at
7591 /// position \p ArgNo.
7592 static void createInitialization(Type *PrivType, Value &Base, Function &F,
7593 unsigned ArgNo, BasicBlock::iterator IP) {
7594 assert(PrivType && "Expected privatizable type!");
7595
7596 IRBuilder<NoFolder> IRB(IP->getParent(), IP);
7597 const DataLayout &DL = F.getDataLayout();
7598
7599 // Traverse the type, build GEPs and stores.
7600 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) {
7601 const StructLayout *PrivStructLayout = DL.getStructLayout(PrivStructType);
7602 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++) {
7603 Value *Ptr =
7604 constructPointer(&Base, PrivStructLayout->getElementOffset(u), IRB);
7605 new StoreInst(F.getArg(ArgNo + u), Ptr, IP);
7606 }
7607 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) {
7608 Type *PointeeTy = PrivArrayType->getElementType();
7609 uint64_t PointeeTySize = DL.getTypeStoreSize(PointeeTy);
7610 for (unsigned u = 0, e = PrivArrayType->getNumElements(); u < e; u++) {
7611 Value *Ptr = constructPointer(&Base, u * PointeeTySize, IRB);
7612 new StoreInst(F.getArg(ArgNo + u), Ptr, IP);
7613 }
7614 } else {
7615 new StoreInst(F.getArg(ArgNo), &Base, IP);
7616 }
7617 }
7618
7619 /// Extract values from \p Base according to the type \p PrivType at the
7620 /// call position \p ACS. The values are appended to \p ReplacementValues.
7621 void createReplacementValues(Align Alignment, Type *PrivType,
7622 AbstractCallSite ACS, Value *Base,
7623 SmallVectorImpl<Value *> &ReplacementValues) {
7624 assert(Base && "Expected base value!");
7625 assert(PrivType && "Expected privatizable type!");
7626 Instruction *IP = ACS.getInstruction();
7627
7628 IRBuilder<NoFolder> IRB(IP);
7629 const DataLayout &DL = IP->getDataLayout();
7630
7631 // Traverse the type, build GEPs and loads.
7632 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) {
7633 const StructLayout *PrivStructLayout = DL.getStructLayout(PrivStructType);
7634 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++) {
7635 Type *PointeeTy = PrivStructType->getElementType(u);
7636 Value *Ptr =
7637 constructPointer(Base, PrivStructLayout->getElementOffset(u), IRB);
7638 LoadInst *L = new LoadInst(PointeeTy, Ptr, "", IP->getIterator());
7639 L->setAlignment(Alignment);
7640 ReplacementValues.push_back(L);
7641 }
7642 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) {
7643 Type *PointeeTy = PrivArrayType->getElementType();
7644 uint64_t PointeeTySize = DL.getTypeStoreSize(PointeeTy);
7645 for (unsigned u = 0, e = PrivArrayType->getNumElements(); u < e; u++) {
7646 Value *Ptr = constructPointer(Base, u * PointeeTySize, IRB);
7647 LoadInst *L = new LoadInst(PointeeTy, Ptr, "", IP->getIterator());
7648 L->setAlignment(Alignment);
7649 ReplacementValues.push_back(L);
7650 }
7651 } else {
7652 LoadInst *L = new LoadInst(PrivType, Base, "", IP->getIterator());
7653 L->setAlignment(Alignment);
7654 ReplacementValues.push_back(L);
7655 }
7656 }
7657
7658 /// See AbstractAttribute::manifest(...)
7659 ChangeStatus manifest(Attributor &A) override {
7660 if (!PrivatizableType)
7661 return ChangeStatus::UNCHANGED;
7662 assert(*PrivatizableType && "Expected privatizable type!");
7663
7664 // Collect all tail calls in the function as we cannot allow new allocas to
7665 // escape into tail recursion.
7666 // TODO: Be smarter about new allocas escaping into tail calls.
7668 bool UsedAssumedInformation = false;
7669 if (!A.checkForAllInstructions(
7670 [&](Instruction &I) {
7671 CallInst &CI = cast<CallInst>(I);
7672 if (CI.isTailCall())
7673 TailCalls.push_back(&CI);
7674 return true;
7675 },
7676 *this, {Instruction::Call}, UsedAssumedInformation))
7677 return ChangeStatus::UNCHANGED;
7678
7679 Argument *Arg = getAssociatedArgument();
7680 // Query AAAlign attribute for alignment of associated argument to
7681 // determine the best alignment of loads.
7682 const auto *AlignAA =
7683 A.getAAFor<AAAlign>(*this, IRPosition::value(*Arg), DepClassTy::NONE);
7684
7685 // Callback to repair the associated function. A new alloca is placed at the
7686 // beginning and initialized with the values passed through arguments. The
7687 // new alloca replaces the use of the old pointer argument.
7689 [=](const Attributor::ArgumentReplacementInfo &ARI,
7690 Function &ReplacementFn, Function::arg_iterator ArgIt) {
7691 BasicBlock &EntryBB = ReplacementFn.getEntryBlock();
7693 const DataLayout &DL = IP->getDataLayout();
7694 unsigned AS = DL.getAllocaAddrSpace();
7695 Instruction *AI = new AllocaInst(*PrivatizableType, AS,
7696 Arg->getName() + ".priv", IP);
7697 createInitialization(*PrivatizableType, *AI, ReplacementFn,
7698 ArgIt->getArgNo(), IP);
7699
7700 if (AI->getType() != Arg->getType())
7701 AI = BitCastInst::CreatePointerBitCastOrAddrSpaceCast(
7702 AI, Arg->getType(), "", IP);
7703 Arg->replaceAllUsesWith(AI);
7704
7705 for (CallInst *CI : TailCalls)
7706 CI->setTailCall(false);
7707 };
7708
7709 // Callback to repair a call site of the associated function. The elements
7710 // of the privatizable type are loaded prior to the call and passed to the
7711 // new function version.
7713 [=](const Attributor::ArgumentReplacementInfo &ARI,
7714 AbstractCallSite ACS, SmallVectorImpl<Value *> &NewArgOperands) {
7715 // When no alignment is specified for the load instruction,
7716 // natural alignment is assumed.
7717 createReplacementValues(
7718 AlignAA ? AlignAA->getAssumedAlign() : Align(0),
7719 *PrivatizableType, ACS,
7720 ACS.getCallArgOperand(ARI.getReplacedArg().getArgNo()),
7721 NewArgOperands);
7722 };
7723
7724 // Collect the types that will replace the privatizable type in the function
7725 // signature.
7726 SmallVector<Type *, 16> ReplacementTypes;
7727 identifyReplacementTypes(*PrivatizableType, ReplacementTypes);
7728
7729 // Register a rewrite of the argument.
7730 if (A.registerFunctionSignatureRewrite(*Arg, ReplacementTypes,
7731 std::move(FnRepairCB),
7732 std::move(ACSRepairCB)))
7733 return ChangeStatus::CHANGED;
7734 return ChangeStatus::UNCHANGED;
7735 }
7736
7737 /// See AbstractAttribute::trackStatistics()
7738 void trackStatistics() const override {
7739 STATS_DECLTRACK_ARG_ATTR(privatizable_ptr);
7740 }
7741};
7742
7743struct AAPrivatizablePtrFloating : public AAPrivatizablePtrImpl {
7744 AAPrivatizablePtrFloating(const IRPosition &IRP, Attributor &A)
7745 : AAPrivatizablePtrImpl(IRP, A) {}
7746
7747 /// See AbstractAttribute::initialize(...).
7748 void initialize(Attributor &A) override {
7749 // TODO: We can privatize more than arguments.
7750 indicatePessimisticFixpoint();
7751 }
7752
7753 ChangeStatus updateImpl(Attributor &A) override {
7754 llvm_unreachable("AAPrivatizablePtr(Floating|Returned|CallSiteReturned)::"
7755 "updateImpl will not be called");
7756 }
7757
7758 /// See AAPrivatizablePtrImpl::identifyPrivatizableType(...)
7759 std::optional<Type *> identifyPrivatizableType(Attributor &A) override {
7760 Value *Obj = getUnderlyingObject(&getAssociatedValue());
7761 if (!Obj) {
7762 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] No underlying object found!\n");
7763 return nullptr;
7764 }
7765
7766 if (auto *AI = dyn_cast<AllocaInst>(Obj))
7767 if (auto *CI = dyn_cast<ConstantInt>(AI->getArraySize()))
7768 if (CI->isOne())
7769 return AI->getAllocatedType();
7770 if (auto *Arg = dyn_cast<Argument>(Obj)) {
7771 auto *PrivArgAA = A.getAAFor<AAPrivatizablePtr>(
7772 *this, IRPosition::argument(*Arg), DepClassTy::REQUIRED);
7773 if (PrivArgAA && PrivArgAA->isAssumedPrivatizablePtr())
7774 return PrivArgAA->getPrivatizableType();
7775 }
7776
7777 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Underlying object neither valid "
7778 "alloca nor privatizable argument: "
7779 << *Obj << "!\n");
7780 return nullptr;
7781 }
7782
7783 /// See AbstractAttribute::trackStatistics()
7784 void trackStatistics() const override {
7785 STATS_DECLTRACK_FLOATING_ATTR(privatizable_ptr);
7786 }
7787};
7788
7789struct AAPrivatizablePtrCallSiteArgument final
7790 : public AAPrivatizablePtrFloating {
7791 AAPrivatizablePtrCallSiteArgument(const IRPosition &IRP, Attributor &A)
7792 : AAPrivatizablePtrFloating(IRP, A) {}
7793
7794 /// See AbstractAttribute::initialize(...).
7795 void initialize(Attributor &A) override {
7796 if (A.hasAttr(getIRPosition(), Attribute::ByVal))
7797 indicateOptimisticFixpoint();
7798 }
7799
7800 /// See AbstractAttribute::updateImpl(...).
7801 ChangeStatus updateImpl(Attributor &A) override {
7802 PrivatizableType = identifyPrivatizableType(A);
7803 if (!PrivatizableType)
7804 return ChangeStatus::UNCHANGED;
7805 if (!*PrivatizableType)
7806 return indicatePessimisticFixpoint();
7807
7808 const IRPosition &IRP = getIRPosition();
7809 bool IsKnownNoCapture;
7810 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
7811 A, this, IRP, DepClassTy::REQUIRED, IsKnownNoCapture);
7812 if (!IsAssumedNoCapture) {
7813 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer might be captured!\n");
7814 return indicatePessimisticFixpoint();
7815 }
7816
7817 bool IsKnownNoAlias;
7819 A, this, IRP, DepClassTy::REQUIRED, IsKnownNoAlias)) {
7820 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer might alias!\n");
7821 return indicatePessimisticFixpoint();
7822 }
7823
7824 bool IsKnown;
7825 if (!AA::isAssumedReadOnly(A, IRP, *this, IsKnown)) {
7826 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer is written!\n");
7827 return indicatePessimisticFixpoint();
7828 }
7829
7830 return ChangeStatus::UNCHANGED;
7831 }
7832
7833 /// See AbstractAttribute::trackStatistics()
7834 void trackStatistics() const override {
7835 STATS_DECLTRACK_CSARG_ATTR(privatizable_ptr);
7836 }
7837};
7838
7839struct AAPrivatizablePtrCallSiteReturned final
7840 : public AAPrivatizablePtrFloating {
7841 AAPrivatizablePtrCallSiteReturned(const IRPosition &IRP, Attributor &A)
7842 : AAPrivatizablePtrFloating(IRP, A) {}
7843
7844 /// See AbstractAttribute::initialize(...).
7845 void initialize(Attributor &A) override {
7846 // TODO: We can privatize more than arguments.
7847 indicatePessimisticFixpoint();
7848 }
7849
7850 /// See AbstractAttribute::trackStatistics()
7851 void trackStatistics() const override {
7852 STATS_DECLTRACK_CSRET_ATTR(privatizable_ptr);
7853 }
7854};
7855
7856struct AAPrivatizablePtrReturned final : public AAPrivatizablePtrFloating {
7857 AAPrivatizablePtrReturned(const IRPosition &IRP, Attributor &A)
7858 : AAPrivatizablePtrFloating(IRP, A) {}
7859
7860 /// See AbstractAttribute::initialize(...).
7861 void initialize(Attributor &A) override {
7862 // TODO: We can privatize more than arguments.
7863 indicatePessimisticFixpoint();
7864 }
7865
7866 /// See AbstractAttribute::trackStatistics()
7867 void trackStatistics() const override {
7868 STATS_DECLTRACK_FNRET_ATTR(privatizable_ptr);
7869 }
7870};
7871} // namespace
7872
7873/// -------------------- Memory Behavior Attributes ----------------------------
7874/// Includes read-none, read-only, and write-only.
7875/// ----------------------------------------------------------------------------
7876namespace {
7877struct AAMemoryBehaviorImpl : public AAMemoryBehavior {
7878 AAMemoryBehaviorImpl(const IRPosition &IRP, Attributor &A)
7879 : AAMemoryBehavior(IRP, A) {}
7880
7881 /// See AbstractAttribute::initialize(...).
7882 void initialize(Attributor &A) override {
7883 intersectAssumedBits(BEST_STATE);
7884 getKnownStateFromValue(A, getIRPosition(), getState());
7885 AAMemoryBehavior::initialize(A);
7886 }
7887
7888 /// Return the memory behavior information encoded in the IR for \p IRP.
7889 static void getKnownStateFromValue(Attributor &A, const IRPosition &IRP,
7890 BitIntegerState &State,
7891 bool IgnoreSubsumingPositions = false) {
7893 A.getAttrs(IRP, AttrKinds, Attrs, IgnoreSubsumingPositions);
7894 for (const Attribute &Attr : Attrs) {
7895 switch (Attr.getKindAsEnum()) {
7896 case Attribute::ReadNone:
7897 State.addKnownBits(NO_ACCESSES);
7898 break;
7899 case Attribute::ReadOnly:
7900 State.addKnownBits(NO_WRITES);
7901 break;
7902 case Attribute::WriteOnly:
7903 State.addKnownBits(NO_READS);
7904 break;
7905 default:
7906 llvm_unreachable("Unexpected attribute!");
7907 }
7908 }
7909
7910 if (auto *I = dyn_cast<Instruction>(&IRP.getAnchorValue())) {
7911 if (!I->mayReadFromMemory())
7912 State.addKnownBits(NO_READS);
7913 if (!I->mayWriteToMemory())
7914 State.addKnownBits(NO_WRITES);
7915 }
7916 }
7917
7918 /// See AbstractAttribute::getDeducedAttributes(...).
7919 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
7920 SmallVectorImpl<Attribute> &Attrs) const override {
7921 assert(Attrs.size() == 0);
7922 if (isAssumedReadNone())
7923 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadNone));
7924 else if (isAssumedReadOnly())
7925 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadOnly));
7926 else if (isAssumedWriteOnly())
7927 Attrs.push_back(Attribute::get(Ctx, Attribute::WriteOnly));
7928 assert(Attrs.size() <= 1);
7929 }
7930
7931 /// See AbstractAttribute::manifest(...).
7932 ChangeStatus manifest(Attributor &A) override {
7933 const IRPosition &IRP = getIRPosition();
7934
7935 if (A.hasAttr(IRP, Attribute::ReadNone,
7936 /* IgnoreSubsumingPositions */ true))
7937 return ChangeStatus::UNCHANGED;
7938
7939 // Check if we would improve the existing attributes first.
7940 SmallVector<Attribute, 4> DeducedAttrs;
7941 getDeducedAttributes(A, IRP.getAnchorValue().getContext(), DeducedAttrs);
7942 if (llvm::all_of(DeducedAttrs, [&](const Attribute &Attr) {
7943 return A.hasAttr(IRP, Attr.getKindAsEnum(),
7944 /* IgnoreSubsumingPositions */ true);
7945 }))
7946 return ChangeStatus::UNCHANGED;
7947
7948 // Clear existing attributes.
7949 A.removeAttrs(IRP, AttrKinds);
7950 // Clear conflicting writable attribute.
7951 if (isAssumedReadOnly())
7952 A.removeAttrs(IRP, Attribute::Writable);
7953
7954 // Use the generic manifest method.
7955 return IRAttribute::manifest(A);
7956 }
7957
7958 /// See AbstractState::getAsStr().
7959 const std::string getAsStr(Attributor *A) const override {
7960 if (isAssumedReadNone())
7961 return "readnone";
7962 if (isAssumedReadOnly())
7963 return "readonly";
7964 if (isAssumedWriteOnly())
7965 return "writeonly";
7966 return "may-read/write";
7967 }
7968
7969 /// The set of IR attributes AAMemoryBehavior deals with.
7970 static const Attribute::AttrKind AttrKinds[3];
7971};
7972
7973const Attribute::AttrKind AAMemoryBehaviorImpl::AttrKinds[] = {
7974 Attribute::ReadNone, Attribute::ReadOnly, Attribute::WriteOnly};
7975
7976/// Memory behavior attribute for a floating value.
7977struct AAMemoryBehaviorFloating : AAMemoryBehaviorImpl {
7978 AAMemoryBehaviorFloating(const IRPosition &IRP, Attributor &A)
7979 : AAMemoryBehaviorImpl(IRP, A) {}
7980
7981 /// See AbstractAttribute::updateImpl(...).
7982 ChangeStatus updateImpl(Attributor &A) override;
7983
7984 /// See AbstractAttribute::trackStatistics()
7985 void trackStatistics() const override {
7986 if (isAssumedReadNone())
7988 else if (isAssumedReadOnly())
7990 else if (isAssumedWriteOnly())
7992 }
7993
7994private:
7995 /// Return true if users of \p UserI might access the underlying
7996 /// variable/location described by \p U and should therefore be analyzed.
7997 bool followUsersOfUseIn(Attributor &A, const Use &U,
7998 const Instruction *UserI);
7999
8000 /// Update the state according to the effect of use \p U in \p UserI.
8001 void analyzeUseIn(Attributor &A, const Use &U, const Instruction *UserI);
8002};
8003
8004/// Memory behavior attribute for function argument.
8005struct AAMemoryBehaviorArgument : AAMemoryBehaviorFloating {
8006 AAMemoryBehaviorArgument(const IRPosition &IRP, Attributor &A)
8007 : AAMemoryBehaviorFloating(IRP, A) {}
8008
8009 /// See AbstractAttribute::initialize(...).
8010 void initialize(Attributor &A) override {
8011 intersectAssumedBits(BEST_STATE);
8012 const IRPosition &IRP = getIRPosition();
8013 // TODO: Make IgnoreSubsumingPositions a property of an IRAttribute so we
8014 // can query it when we use has/getAttr. That would allow us to reuse the
8015 // initialize of the base class here.
8016 bool HasByVal = A.hasAttr(IRP, {Attribute::ByVal},
8017 /* IgnoreSubsumingPositions */ true);
8018 getKnownStateFromValue(A, IRP, getState(),
8019 /* IgnoreSubsumingPositions */ HasByVal);
8020 }
8021
8022 ChangeStatus manifest(Attributor &A) override {
8023 // TODO: Pointer arguments are not supported on vectors of pointers yet.
8024 if (!getAssociatedValue().getType()->isPointerTy())
8025 return ChangeStatus::UNCHANGED;
8026
8027 // TODO: From readattrs.ll: "inalloca parameters are always
8028 // considered written"
8029 if (A.hasAttr(getIRPosition(),
8030 {Attribute::InAlloca, Attribute::Preallocated})) {
8031 removeKnownBits(NO_WRITES);
8032 removeAssumedBits(NO_WRITES);
8033 }
8034 A.removeAttrs(getIRPosition(), AttrKinds);
8035 return AAMemoryBehaviorFloating::manifest(A);
8036 }
8037
8038 /// See AbstractAttribute::trackStatistics()
8039 void trackStatistics() const override {
8040 if (isAssumedReadNone())
8041 STATS_DECLTRACK_ARG_ATTR(readnone)
8042 else if (isAssumedReadOnly())
8043 STATS_DECLTRACK_ARG_ATTR(readonly)
8044 else if (isAssumedWriteOnly())
8045 STATS_DECLTRACK_ARG_ATTR(writeonly)
8046 }
8047};
8048
8049struct AAMemoryBehaviorCallSiteArgument final : AAMemoryBehaviorArgument {
8050 AAMemoryBehaviorCallSiteArgument(const IRPosition &IRP, Attributor &A)
8051 : AAMemoryBehaviorArgument(IRP, A) {}
8052
8053 /// See AbstractAttribute::initialize(...).
8054 void initialize(Attributor &A) override {
8055 // If we don't have an associated attribute this is either a variadic call
8056 // or an indirect call, either way, nothing to do here.
8057 Argument *Arg = getAssociatedArgument();
8058 if (!Arg) {
8059 indicatePessimisticFixpoint();
8060 return;
8061 }
8062 if (Arg->hasByValAttr()) {
8063 addKnownBits(NO_WRITES);
8064 removeKnownBits(NO_READS);
8065 removeAssumedBits(NO_READS);
8066 }
8067 AAMemoryBehaviorArgument::initialize(A);
8068 if (getAssociatedFunction()->isDeclaration())
8069 indicatePessimisticFixpoint();
8070 }
8071
8072 /// See AbstractAttribute::updateImpl(...).
8073 ChangeStatus updateImpl(Attributor &A) override {
8074 // TODO: Once we have call site specific value information we can provide
8075 // call site specific liveness liveness information and then it makes
8076 // sense to specialize attributes for call sites arguments instead of
8077 // redirecting requests to the callee argument.
8078 Argument *Arg = getAssociatedArgument();
8079 const IRPosition &ArgPos = IRPosition::argument(*Arg);
8080 auto *ArgAA =
8081 A.getAAFor<AAMemoryBehavior>(*this, ArgPos, DepClassTy::REQUIRED);
8082 if (!ArgAA)
8083 return indicatePessimisticFixpoint();
8084 return clampStateAndIndicateChange(getState(), ArgAA->getState());
8085 }
8086
8087 /// See AbstractAttribute::trackStatistics()
8088 void trackStatistics() const override {
8089 if (isAssumedReadNone())
8091 else if (isAssumedReadOnly())
8093 else if (isAssumedWriteOnly())
8095 }
8096};
8097
8098/// Memory behavior attribute for a call site return position.
8099struct AAMemoryBehaviorCallSiteReturned final : AAMemoryBehaviorFloating {
8100 AAMemoryBehaviorCallSiteReturned(const IRPosition &IRP, Attributor &A)
8101 : AAMemoryBehaviorFloating(IRP, A) {}
8102
8103 /// See AbstractAttribute::initialize(...).
8104 void initialize(Attributor &A) override {
8105 AAMemoryBehaviorImpl::initialize(A);
8106 }
8107 /// See AbstractAttribute::manifest(...).
8108 ChangeStatus manifest(Attributor &A) override {
8109 // We do not annotate returned values.
8110 return ChangeStatus::UNCHANGED;
8111 }
8112
8113 /// See AbstractAttribute::trackStatistics()
8114 void trackStatistics() const override {}
8115};
8116
8117/// An AA to represent the memory behavior function attributes.
8118struct AAMemoryBehaviorFunction final : public AAMemoryBehaviorImpl {
8119 AAMemoryBehaviorFunction(const IRPosition &IRP, Attributor &A)
8120 : AAMemoryBehaviorImpl(IRP, A) {}
8121
8122 /// See AbstractAttribute::updateImpl(Attributor &A).
8123 ChangeStatus updateImpl(Attributor &A) override;
8124
8125 /// See AbstractAttribute::manifest(...).
8126 ChangeStatus manifest(Attributor &A) override {
8127 // TODO: It would be better to merge this with AAMemoryLocation, so that
8128 // we could determine read/write per location. This would also have the
8129 // benefit of only one place trying to manifest the memory attribute.
8130 Function &F = cast<Function>(getAnchorValue());
8132 if (isAssumedReadNone())
8133 ME = MemoryEffects::none();
8134 else if (isAssumedReadOnly())
8136 else if (isAssumedWriteOnly())
8138
8139 A.removeAttrs(getIRPosition(), AttrKinds);
8140 // Clear conflicting writable attribute.
8141 if (ME.onlyReadsMemory())
8142 for (Argument &Arg : F.args())
8143 A.removeAttrs(IRPosition::argument(Arg), Attribute::Writable);
8144 return A.manifestAttrs(getIRPosition(),
8145 Attribute::getWithMemoryEffects(F.getContext(), ME));
8146 }
8147
8148 /// See AbstractAttribute::trackStatistics()
8149 void trackStatistics() const override {
8150 if (isAssumedReadNone())
8151 STATS_DECLTRACK_FN_ATTR(readnone)
8152 else if (isAssumedReadOnly())
8153 STATS_DECLTRACK_FN_ATTR(readonly)
8154 else if (isAssumedWriteOnly())
8155 STATS_DECLTRACK_FN_ATTR(writeonly)
8156 }
8157};
8158
8159/// AAMemoryBehavior attribute for call sites.
8160struct AAMemoryBehaviorCallSite final
8161 : AACalleeToCallSite<AAMemoryBehavior, AAMemoryBehaviorImpl> {
8162 AAMemoryBehaviorCallSite(const IRPosition &IRP, Attributor &A)
8163 : AACalleeToCallSite<AAMemoryBehavior, AAMemoryBehaviorImpl>(IRP, A) {}
8164
8165 /// See AbstractAttribute::manifest(...).
8166 ChangeStatus manifest(Attributor &A) override {
8167 // TODO: Deduplicate this with AAMemoryBehaviorFunction.
8168 CallBase &CB = cast<CallBase>(getAnchorValue());
8170 if (isAssumedReadNone())
8171 ME = MemoryEffects::none();
8172 else if (isAssumedReadOnly())
8174 else if (isAssumedWriteOnly())
8176
8177 A.removeAttrs(getIRPosition(), AttrKinds);
8178 // Clear conflicting writable attribute.
8179 if (ME.onlyReadsMemory())
8180 for (Use &U : CB.args())
8181 A.removeAttrs(IRPosition::callsite_argument(CB, U.getOperandNo()),
8182 Attribute::Writable);
8183 return A.manifestAttrs(
8184 getIRPosition(), Attribute::getWithMemoryEffects(CB.getContext(), ME));
8185 }
8186
8187 /// See AbstractAttribute::trackStatistics()
8188 void trackStatistics() const override {
8189 if (isAssumedReadNone())
8190 STATS_DECLTRACK_CS_ATTR(readnone)
8191 else if (isAssumedReadOnly())
8192 STATS_DECLTRACK_CS_ATTR(readonly)
8193 else if (isAssumedWriteOnly())
8194 STATS_DECLTRACK_CS_ATTR(writeonly)
8195 }
8196};
8197
8198ChangeStatus AAMemoryBehaviorFunction::updateImpl(Attributor &A) {
8199
8200 // The current assumed state used to determine a change.
8201 auto AssumedState = getAssumed();
8202
8203 auto CheckRWInst = [&](Instruction &I) {
8204 // If the instruction has an own memory behavior state, use it to restrict
8205 // the local state. No further analysis is required as the other memory
8206 // state is as optimistic as it gets.
8207 if (const auto *CB = dyn_cast<CallBase>(&I)) {
8208 const auto *MemBehaviorAA = A.getAAFor<AAMemoryBehavior>(
8210 if (MemBehaviorAA) {
8211 intersectAssumedBits(MemBehaviorAA->getAssumed());
8212 return !isAtFixpoint();
8213 }
8214 }
8215
8216 // Remove access kind modifiers if necessary.
8217 if (I.mayReadFromMemory())
8218 removeAssumedBits(NO_READS);
8219 if (I.mayWriteToMemory())
8220 removeAssumedBits(NO_WRITES);
8221 return !isAtFixpoint();
8222 };
8223
8224 bool UsedAssumedInformation = false;
8225 if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this,
8226 UsedAssumedInformation))
8227 return indicatePessimisticFixpoint();
8228
8229 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
8231}
8232
8233ChangeStatus AAMemoryBehaviorFloating::updateImpl(Attributor &A) {
8234
8235 const IRPosition &IRP = getIRPosition();
8236 const IRPosition &FnPos = IRPosition::function_scope(IRP);
8237 AAMemoryBehavior::StateType &S = getState();
8238
8239 // First, check the function scope. We take the known information and we avoid
8240 // work if the assumed information implies the current assumed information for
8241 // this attribute. This is a valid for all but byval arguments.
8242 Argument *Arg = IRP.getAssociatedArgument();
8243 AAMemoryBehavior::base_t FnMemAssumedState =
8245 if (!Arg || !Arg->hasByValAttr()) {
8246 const auto *FnMemAA =
8247 A.getAAFor<AAMemoryBehavior>(*this, FnPos, DepClassTy::OPTIONAL);
8248 if (FnMemAA) {
8249 FnMemAssumedState = FnMemAA->getAssumed();
8250 S.addKnownBits(FnMemAA->getKnown());
8251 if ((S.getAssumed() & FnMemAA->getAssumed()) == S.getAssumed())
8253 }
8254 }
8255
8256 // The current assumed state used to determine a change.
8257 auto AssumedState = S.getAssumed();
8258
8259 // Make sure the value is not captured (except through "return"), if
8260 // it is, any information derived would be irrelevant anyway as we cannot
8261 // check the potential aliases introduced by the capture. However, no need
8262 // to fall back to anythign less optimistic than the function state.
8263 bool IsKnownNoCapture;
8264 const AANoCapture *ArgNoCaptureAA = nullptr;
8265 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
8266 A, this, IRP, DepClassTy::OPTIONAL, IsKnownNoCapture, false,
8267 &ArgNoCaptureAA);
8268
8269 if (!IsAssumedNoCapture &&
8270 (!ArgNoCaptureAA || !ArgNoCaptureAA->isAssumedNoCaptureMaybeReturned())) {
8271 S.intersectAssumedBits(FnMemAssumedState);
8272 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
8274 }
8275
8276 // Visit and expand uses until all are analyzed or a fixpoint is reached.
8277 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
8278 Instruction *UserI = cast<Instruction>(U.getUser());
8279 LLVM_DEBUG(dbgs() << "[AAMemoryBehavior] Use: " << *U << " in " << *UserI
8280 << " \n");
8281
8282 // Droppable users, e.g., llvm::assume does not actually perform any action.
8283 if (UserI->isDroppable())
8284 return true;
8285
8286 // Check if the users of UserI should also be visited.
8287 Follow = followUsersOfUseIn(A, U, UserI);
8288
8289 // If UserI might touch memory we analyze the use in detail.
8290 if (UserI->mayReadOrWriteMemory())
8291 analyzeUseIn(A, U, UserI);
8292
8293 return !isAtFixpoint();
8294 };
8295
8296 if (!A.checkForAllUses(UsePred, *this, getAssociatedValue()))
8297 return indicatePessimisticFixpoint();
8298
8299 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
8301}
8302
8303bool AAMemoryBehaviorFloating::followUsersOfUseIn(Attributor &A, const Use &U,
8304 const Instruction *UserI) {
8305 // The loaded value is unrelated to the pointer argument, no need to
8306 // follow the users of the load.
8307 if (isa<LoadInst>(UserI) || isa<ReturnInst>(UserI))
8308 return false;
8309
8310 // By default we follow all uses assuming UserI might leak information on U,
8311 // we have special handling for call sites operands though.
8312 const auto *CB = dyn_cast<CallBase>(UserI);
8313 if (!CB || !CB->isArgOperand(&U))
8314 return true;
8315
8316 // If the use is a call argument known not to be captured, the users of
8317 // the call do not need to be visited because they have to be unrelated to
8318 // the input. Note that this check is not trivial even though we disallow
8319 // general capturing of the underlying argument. The reason is that the
8320 // call might the argument "through return", which we allow and for which we
8321 // need to check call users.
8322 if (U.get()->getType()->isPointerTy()) {
8323 unsigned ArgNo = CB->getArgOperandNo(&U);
8324 bool IsKnownNoCapture;
8326 A, this, IRPosition::callsite_argument(*CB, ArgNo),
8327 DepClassTy::OPTIONAL, IsKnownNoCapture);
8328 }
8329
8330 return true;
8331}
8332
8333void AAMemoryBehaviorFloating::analyzeUseIn(Attributor &A, const Use &U,
8334 const Instruction *UserI) {
8335 assert(UserI->mayReadOrWriteMemory());
8336
8337 switch (UserI->getOpcode()) {
8338 default:
8339 // TODO: Handle all atomics and other side-effect operations we know of.
8340 break;
8341 case Instruction::Load:
8342 // Loads cause the NO_READS property to disappear.
8343 removeAssumedBits(NO_READS);
8344 return;
8345
8346 case Instruction::Store:
8347 // Stores cause the NO_WRITES property to disappear if the use is the
8348 // pointer operand. Note that while capturing was taken care of somewhere
8349 // else we need to deal with stores of the value that is not looked through.
8350 if (cast<StoreInst>(UserI)->getPointerOperand() == U.get())
8351 removeAssumedBits(NO_WRITES);
8352 else
8353 indicatePessimisticFixpoint();
8354 return;
8355
8356 case Instruction::Call:
8357 case Instruction::CallBr:
8358 case Instruction::Invoke: {
8359 // For call sites we look at the argument memory behavior attribute (this
8360 // could be recursive!) in order to restrict our own state.
8361 const auto *CB = cast<CallBase>(UserI);
8362
8363 // Give up on operand bundles.
8364 if (CB->isBundleOperand(&U)) {
8365 indicatePessimisticFixpoint();
8366 return;
8367 }
8368
8369 // Calling a function does read the function pointer, maybe write it if the
8370 // function is self-modifying.
8371 if (CB->isCallee(&U)) {
8372 removeAssumedBits(NO_READS);
8373 break;
8374 }
8375
8376 // Adjust the possible access behavior based on the information on the
8377 // argument.
8378 IRPosition Pos;
8379 if (U.get()->getType()->isPointerTy())
8381 else
8383 const auto *MemBehaviorAA =
8384 A.getAAFor<AAMemoryBehavior>(*this, Pos, DepClassTy::OPTIONAL);
8385 if (!MemBehaviorAA)
8386 break;
8387 // "assumed" has at most the same bits as the MemBehaviorAA assumed
8388 // and at least "known".
8389 intersectAssumedBits(MemBehaviorAA->getAssumed());
8390 return;
8391 }
8392 };
8393
8394 // Generally, look at the "may-properties" and adjust the assumed state if we
8395 // did not trigger special handling before.
8396 if (UserI->mayReadFromMemory())
8397 removeAssumedBits(NO_READS);
8398 if (UserI->mayWriteToMemory())
8399 removeAssumedBits(NO_WRITES);
8400}
8401} // namespace
8402
8403/// -------------------- Memory Locations Attributes ---------------------------
8404/// Includes read-none, argmemonly, inaccessiblememonly,
8405/// inaccessiblememorargmemonly
8406/// ----------------------------------------------------------------------------
8407
8410 if (0 == (MLK & AAMemoryLocation::NO_LOCATIONS))
8411 return "all memory";
8413 return "no memory";
8414 std::string S = "memory:";
8415 if (0 == (MLK & AAMemoryLocation::NO_LOCAL_MEM))
8416 S += "stack,";
8417 if (0 == (MLK & AAMemoryLocation::NO_CONST_MEM))
8418 S += "constant,";
8420 S += "internal global,";
8422 S += "external global,";
8423 if (0 == (MLK & AAMemoryLocation::NO_ARGUMENT_MEM))
8424 S += "argument,";
8426 S += "inaccessible,";
8427 if (0 == (MLK & AAMemoryLocation::NO_MALLOCED_MEM))
8428 S += "malloced,";
8429 if (0 == (MLK & AAMemoryLocation::NO_UNKOWN_MEM))
8430 S += "unknown,";
8431 S.pop_back();
8432 return S;
8433}
8434
8435namespace {
8436struct AAMemoryLocationImpl : public AAMemoryLocation {
8437
8438 AAMemoryLocationImpl(const IRPosition &IRP, Attributor &A)
8439 : AAMemoryLocation(IRP, A), Allocator(A.Allocator) {
8440 AccessKind2Accesses.fill(nullptr);
8441 }
8442
8443 ~AAMemoryLocationImpl() override {
8444 // The AccessSets are allocated via a BumpPtrAllocator, we call
8445 // the destructor manually.
8446 for (AccessSet *AS : AccessKind2Accesses)
8447 if (AS)
8448 AS->~AccessSet();
8449 }
8450
8451 /// See AbstractAttribute::initialize(...).
8452 void initialize(Attributor &A) override {
8453 intersectAssumedBits(BEST_STATE);
8454 getKnownStateFromValue(A, getIRPosition(), getState());
8455 AAMemoryLocation::initialize(A);
8456 }
8457
8458 /// Return the memory behavior information encoded in the IR for \p IRP.
8459 static void getKnownStateFromValue(Attributor &A, const IRPosition &IRP,
8460 BitIntegerState &State,
8461 bool IgnoreSubsumingPositions = false) {
8462 // For internal functions we ignore `argmemonly` and
8463 // `inaccessiblememorargmemonly` as we might break it via interprocedural
8464 // constant propagation. It is unclear if this is the best way but it is
8465 // unlikely this will cause real performance problems. If we are deriving
8466 // attributes for the anchor function we even remove the attribute in
8467 // addition to ignoring it.
8468 // TODO: A better way to handle this would be to add ~NO_GLOBAL_MEM /
8469 // MemoryEffects::Other as a possible location.
8470 bool UseArgMemOnly = true;
8471 Function *AnchorFn = IRP.getAnchorScope();
8472 if (AnchorFn && A.isRunOn(*AnchorFn))
8473 UseArgMemOnly = !AnchorFn->hasLocalLinkage();
8474
8476 A.getAttrs(IRP, {Attribute::Memory}, Attrs, IgnoreSubsumingPositions);
8477 for (const Attribute &Attr : Attrs) {
8478 // TODO: We can map MemoryEffects to Attributor locations more precisely.
8479 MemoryEffects ME = Attr.getMemoryEffects();
8480 if (ME.doesNotAccessMemory()) {
8481 State.addKnownBits(NO_LOCAL_MEM | NO_CONST_MEM);
8482 continue;
8483 }
8484 if (ME.onlyAccessesInaccessibleMem()) {
8485 State.addKnownBits(inverseLocation(NO_INACCESSIBLE_MEM, true, true));
8486 continue;
8487 }
8488 if (ME.onlyAccessesArgPointees()) {
8489 if (UseArgMemOnly)
8490 State.addKnownBits(inverseLocation(NO_ARGUMENT_MEM, true, true));
8491 else {
8492 // Remove location information, only keep read/write info.
8493 ME = MemoryEffects(ME.getModRef());
8494 A.manifestAttrs(IRP,
8495 Attribute::getWithMemoryEffects(
8496 IRP.getAnchorValue().getContext(), ME),
8497 /*ForceReplace*/ true);
8498 }
8499 continue;
8500 }
8502 if (UseArgMemOnly)
8503 State.addKnownBits(inverseLocation(
8504 NO_INACCESSIBLE_MEM | NO_ARGUMENT_MEM, true, true));
8505 else {
8506 // Remove location information, only keep read/write info.
8507 ME = MemoryEffects(ME.getModRef());
8508 A.manifestAttrs(IRP,
8509 Attribute::getWithMemoryEffects(
8510 IRP.getAnchorValue().getContext(), ME),
8511 /*ForceReplace*/ true);
8512 }
8513 continue;
8514 }
8515 }
8516 }
8517
8518 /// See AbstractAttribute::getDeducedAttributes(...).
8519 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
8520 SmallVectorImpl<Attribute> &Attrs) const override {
8521 // TODO: We can map Attributor locations to MemoryEffects more precisely.
8522 assert(Attrs.size() == 0);
8523 if (getIRPosition().getPositionKind() == IRPosition::IRP_FUNCTION) {
8524 if (isAssumedReadNone())
8525 Attrs.push_back(
8526 Attribute::getWithMemoryEffects(Ctx, MemoryEffects::none()));
8527 else if (isAssumedInaccessibleMemOnly())
8528 Attrs.push_back(Attribute::getWithMemoryEffects(
8530 else if (isAssumedArgMemOnly())
8531 Attrs.push_back(
8532 Attribute::getWithMemoryEffects(Ctx, MemoryEffects::argMemOnly()));
8533 else if (isAssumedInaccessibleOrArgMemOnly())
8534 Attrs.push_back(Attribute::getWithMemoryEffects(
8536 }
8537 assert(Attrs.size() <= 1);
8538 }
8539
8540 /// See AbstractAttribute::manifest(...).
8541 ChangeStatus manifest(Attributor &A) override {
8542 // TODO: If AAMemoryLocation and AAMemoryBehavior are merged, we could
8543 // provide per-location modref information here.
8544 const IRPosition &IRP = getIRPosition();
8545
8546 SmallVector<Attribute, 1> DeducedAttrs;
8547 getDeducedAttributes(A, IRP.getAnchorValue().getContext(), DeducedAttrs);
8548 if (DeducedAttrs.size() != 1)
8549 return ChangeStatus::UNCHANGED;
8550 MemoryEffects ME = DeducedAttrs[0].getMemoryEffects();
8551
8552 return A.manifestAttrs(IRP, Attribute::getWithMemoryEffects(
8553 IRP.getAnchorValue().getContext(), ME));
8554 }
8555
8556 /// See AAMemoryLocation::checkForAllAccessesToMemoryKind(...).
8557 bool checkForAllAccessesToMemoryKind(
8558 function_ref<bool(const Instruction *, const Value *, AccessKind,
8559 MemoryLocationsKind)>
8560 Pred,
8561 MemoryLocationsKind RequestedMLK) const override {
8562 if (!isValidState())
8563 return false;
8564
8565 MemoryLocationsKind AssumedMLK = getAssumedNotAccessedLocation();
8566 if (AssumedMLK == NO_LOCATIONS)
8567 return true;
8568
8569 unsigned Idx = 0;
8570 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS;
8571 CurMLK *= 2, ++Idx) {
8572 if (CurMLK & RequestedMLK)
8573 continue;
8574
8575 if (const AccessSet *Accesses = AccessKind2Accesses[Idx])
8576 for (const AccessInfo &AI : *Accesses)
8577 if (!Pred(AI.I, AI.Ptr, AI.Kind, CurMLK))
8578 return false;
8579 }
8580
8581 return true;
8582 }
8583
8584 ChangeStatus indicatePessimisticFixpoint() override {
8585 // If we give up and indicate a pessimistic fixpoint this instruction will
8586 // become an access for all potential access kinds:
8587 // TODO: Add pointers for argmemonly and globals to improve the results of
8588 // checkForAllAccessesToMemoryKind.
8589 bool Changed = false;
8590 MemoryLocationsKind KnownMLK = getKnown();
8591 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
8592 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS; CurMLK *= 2)
8593 if (!(CurMLK & KnownMLK))
8594 updateStateAndAccessesMap(getState(), CurMLK, I, nullptr, Changed,
8595 getAccessKindFromInst(I));
8596 return AAMemoryLocation::indicatePessimisticFixpoint();
8597 }
8598
8599protected:
8600 /// Helper struct to tie together an instruction that has a read or write
8601 /// effect with the pointer it accesses (if any).
8602 struct AccessInfo {
8603
8604 /// The instruction that caused the access.
8605 const Instruction *I;
8606
8607 /// The base pointer that is accessed, or null if unknown.
8608 const Value *Ptr;
8609
8610 /// The kind of access (read/write/read+write).
8612
8613 bool operator==(const AccessInfo &RHS) const {
8614 return I == RHS.I && Ptr == RHS.Ptr && Kind == RHS.Kind;
8615 }
8616 bool operator()(const AccessInfo &LHS, const AccessInfo &RHS) const {
8617 if (LHS.I != RHS.I)
8618 return LHS.I < RHS.I;
8619 if (LHS.Ptr != RHS.Ptr)
8620 return LHS.Ptr < RHS.Ptr;
8621 if (LHS.Kind != RHS.Kind)
8622 return LHS.Kind < RHS.Kind;
8623 return false;
8624 }
8625 };
8626
8627 /// Mapping from *single* memory location kinds, e.g., LOCAL_MEM with the
8628 /// value of NO_LOCAL_MEM, to the accesses encountered for this memory kind.
8629 using AccessSet = SmallSet<AccessInfo, 2, AccessInfo>;
8630 std::array<AccessSet *, llvm::ConstantLog2<VALID_STATE>()>
8631 AccessKind2Accesses;
8632
8633 /// Categorize the pointer arguments of CB that might access memory in
8634 /// AccessedLoc and update the state and access map accordingly.
8635 void
8636 categorizeArgumentPointerLocations(Attributor &A, CallBase &CB,
8637 AAMemoryLocation::StateType &AccessedLocs,
8638 bool &Changed);
8639
8640 /// Return the kind(s) of location that may be accessed by \p V.
8642 categorizeAccessedLocations(Attributor &A, Instruction &I, bool &Changed);
8643
8644 /// Return the access kind as determined by \p I.
8645 AccessKind getAccessKindFromInst(const Instruction *I) {
8646 AccessKind AK = READ_WRITE;
8647 if (I) {
8648 AK = I->mayReadFromMemory() ? READ : NONE;
8649 AK = AccessKind(AK | (I->mayWriteToMemory() ? WRITE : NONE));
8650 }
8651 return AK;
8652 }
8653
8654 /// Update the state \p State and the AccessKind2Accesses given that \p I is
8655 /// an access of kind \p AK to a \p MLK memory location with the access
8656 /// pointer \p Ptr.
8657 void updateStateAndAccessesMap(AAMemoryLocation::StateType &State,
8658 MemoryLocationsKind MLK, const Instruction *I,
8659 const Value *Ptr, bool &Changed,
8660 AccessKind AK = READ_WRITE) {
8661
8662 assert(isPowerOf2_32(MLK) && "Expected a single location set!");
8663 auto *&Accesses = AccessKind2Accesses[llvm::Log2_32(MLK)];
8664 if (!Accesses)
8665 Accesses = new (Allocator) AccessSet();
8666 Changed |= Accesses->insert(AccessInfo{I, Ptr, AK}).second;
8667 if (MLK == NO_UNKOWN_MEM)
8668 MLK = NO_LOCATIONS;
8669 State.removeAssumedBits(MLK);
8670 }
8671
8672 /// Determine the underlying locations kinds for \p Ptr, e.g., globals or
8673 /// arguments, and update the state and access map accordingly.
8674 void categorizePtrValue(Attributor &A, const Instruction &I, const Value &Ptr,
8675 AAMemoryLocation::StateType &State, bool &Changed,
8676 unsigned AccessAS = 0);
8677
8678 /// Used to allocate access sets.
8680};
8681
8682void AAMemoryLocationImpl::categorizePtrValue(
8683 Attributor &A, const Instruction &I, const Value &Ptr,
8684 AAMemoryLocation::StateType &State, bool &Changed, unsigned AccessAS) {
8685 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize pointer locations for "
8686 << Ptr << " ["
8687 << getMemoryLocationsAsStr(State.getAssumed()) << "]\n");
8688
8689 auto Pred = [&](Value &Obj) {
8690 unsigned ObjectAS = Obj.getType()->getPointerAddressSpace();
8691 // TODO: recognize the TBAA used for constant accesses.
8692 MemoryLocationsKind MLK = NO_LOCATIONS;
8693
8694 // Filter accesses to constant (GPU) memory if we have an AS at the access
8695 // site or the object is known to actually have the associated AS.
8696 if (AA::isGPU(A.getModule())) {
8697 if (AA::isGPUConstantAddressSpace(A.getModule(), AccessAS) ||
8698 (AA::isGPUConstantAddressSpace(A.getModule(), ObjectAS) &&
8699 isIdentifiedObject(&Obj)))
8700 return true;
8701 }
8702
8703 if (isa<UndefValue>(&Obj))
8704 return true;
8705 if (isa<Argument>(&Obj)) {
8706 // TODO: For now we do not treat byval arguments as local copies performed
8707 // on the call edge, though, we should. To make that happen we need to
8708 // teach various passes, e.g., DSE, about the copy effect of a byval. That
8709 // would also allow us to mark functions only accessing byval arguments as
8710 // readnone again, arguably their accesses have no effect outside of the
8711 // function, like accesses to allocas.
8712 MLK = NO_ARGUMENT_MEM;
8713 } else if (auto *GV = dyn_cast<GlobalValue>(&Obj)) {
8714 // Reading constant memory is not treated as a read "effect" by the
8715 // function attr pass so we won't neither. Constants defined by TBAA are
8716 // similar. (We know we do not write it because it is constant.)
8717 if (auto *GVar = dyn_cast<GlobalVariable>(GV))
8718 if (GVar->isConstant())
8719 return true;
8720
8721 if (GV->hasLocalLinkage())
8722 MLK = NO_GLOBAL_INTERNAL_MEM;
8723 else
8724 MLK = NO_GLOBAL_EXTERNAL_MEM;
8725 } else if (isa<ConstantPointerNull>(&Obj) &&
8726 (!NullPointerIsDefined(getAssociatedFunction(), AccessAS) ||
8727 !NullPointerIsDefined(getAssociatedFunction(), ObjectAS))) {
8728 return true;
8729 } else if (isa<AllocaInst>(&Obj)) {
8730 MLK = NO_LOCAL_MEM;
8731 } else if (const auto *CB = dyn_cast<CallBase>(&Obj)) {
8732 bool IsKnownNoAlias;
8735 IsKnownNoAlias))
8736 MLK = NO_MALLOCED_MEM;
8737 else
8738 MLK = NO_UNKOWN_MEM;
8739 } else {
8740 MLK = NO_UNKOWN_MEM;
8741 }
8742
8743 assert(MLK != NO_LOCATIONS && "No location specified!");
8744 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Ptr value can be categorized: "
8745 << Obj << " -> " << getMemoryLocationsAsStr(MLK) << "\n");
8746 updateStateAndAccessesMap(State, MLK, &I, &Obj, Changed,
8747 getAccessKindFromInst(&I));
8748
8749 return true;
8750 };
8751
8752 const auto *AA = A.getAAFor<AAUnderlyingObjects>(
8754 if (!AA || !AA->forallUnderlyingObjects(Pred, AA::Intraprocedural)) {
8755 LLVM_DEBUG(
8756 dbgs() << "[AAMemoryLocation] Pointer locations not categorized\n");
8757 updateStateAndAccessesMap(State, NO_UNKOWN_MEM, &I, nullptr, Changed,
8758 getAccessKindFromInst(&I));
8759 return;
8760 }
8761
8762 LLVM_DEBUG(
8763 dbgs() << "[AAMemoryLocation] Accessed locations with pointer locations: "
8764 << getMemoryLocationsAsStr(State.getAssumed()) << "\n");
8765}
8766
8767void AAMemoryLocationImpl::categorizeArgumentPointerLocations(
8768 Attributor &A, CallBase &CB, AAMemoryLocation::StateType &AccessedLocs,
8769 bool &Changed) {
8770 for (unsigned ArgNo = 0, E = CB.arg_size(); ArgNo < E; ++ArgNo) {
8771
8772 // Skip non-pointer arguments.
8773 const Value *ArgOp = CB.getArgOperand(ArgNo);
8774 if (!ArgOp->getType()->isPtrOrPtrVectorTy())
8775 continue;
8776
8777 // Skip readnone arguments.
8778 const IRPosition &ArgOpIRP = IRPosition::callsite_argument(CB, ArgNo);
8779 const auto *ArgOpMemLocationAA =
8780 A.getAAFor<AAMemoryBehavior>(*this, ArgOpIRP, DepClassTy::OPTIONAL);
8781
8782 if (ArgOpMemLocationAA && ArgOpMemLocationAA->isAssumedReadNone())
8783 continue;
8784
8785 // Categorize potentially accessed pointer arguments as if there was an
8786 // access instruction with them as pointer.
8787 categorizePtrValue(A, CB, *ArgOp, AccessedLocs, Changed);
8788 }
8789}
8790
8792AAMemoryLocationImpl::categorizeAccessedLocations(Attributor &A, Instruction &I,
8793 bool &Changed) {
8794 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize accessed locations for "
8795 << I << "\n");
8796
8797 AAMemoryLocation::StateType AccessedLocs;
8798 AccessedLocs.intersectAssumedBits(NO_LOCATIONS);
8799
8800 if (auto *CB = dyn_cast<CallBase>(&I)) {
8801
8802 // First check if we assume any memory is access is visible.
8803 const auto *CBMemLocationAA = A.getAAFor<AAMemoryLocation>(
8805 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize call site: " << I
8806 << " [" << CBMemLocationAA << "]\n");
8807 if (!CBMemLocationAA) {
8808 updateStateAndAccessesMap(AccessedLocs, NO_UNKOWN_MEM, &I, nullptr,
8809 Changed, getAccessKindFromInst(&I));
8810 return NO_UNKOWN_MEM;
8811 }
8812
8813 if (CBMemLocationAA->isAssumedReadNone())
8814 return NO_LOCATIONS;
8815
8816 if (CBMemLocationAA->isAssumedInaccessibleMemOnly()) {
8817 updateStateAndAccessesMap(AccessedLocs, NO_INACCESSIBLE_MEM, &I, nullptr,
8818 Changed, getAccessKindFromInst(&I));
8819 return AccessedLocs.getAssumed();
8820 }
8821
8822 uint32_t CBAssumedNotAccessedLocs =
8823 CBMemLocationAA->getAssumedNotAccessedLocation();
8824
8825 // Set the argmemonly and global bit as we handle them separately below.
8826 uint32_t CBAssumedNotAccessedLocsNoArgMem =
8827 CBAssumedNotAccessedLocs | NO_ARGUMENT_MEM | NO_GLOBAL_MEM;
8828
8829 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS; CurMLK *= 2) {
8830 if (CBAssumedNotAccessedLocsNoArgMem & CurMLK)
8831 continue;
8832 updateStateAndAccessesMap(AccessedLocs, CurMLK, &I, nullptr, Changed,
8833 getAccessKindFromInst(&I));
8834 }
8835
8836 // Now handle global memory if it might be accessed. This is slightly tricky
8837 // as NO_GLOBAL_MEM has multiple bits set.
8838 bool HasGlobalAccesses = ((~CBAssumedNotAccessedLocs) & NO_GLOBAL_MEM);
8839 if (HasGlobalAccesses) {
8840 auto AccessPred = [&](const Instruction *, const Value *Ptr,
8841 AccessKind Kind, MemoryLocationsKind MLK) {
8842 updateStateAndAccessesMap(AccessedLocs, MLK, &I, Ptr, Changed,
8843 getAccessKindFromInst(&I));
8844 return true;
8845 };
8846 if (!CBMemLocationAA->checkForAllAccessesToMemoryKind(
8847 AccessPred, inverseLocation(NO_GLOBAL_MEM, false, false)))
8848 return AccessedLocs.getWorstState();
8849 }
8850
8851 LLVM_DEBUG(
8852 dbgs() << "[AAMemoryLocation] Accessed state before argument handling: "
8853 << getMemoryLocationsAsStr(AccessedLocs.getAssumed()) << "\n");
8854
8855 // Now handle argument memory if it might be accessed.
8856 bool HasArgAccesses = ((~CBAssumedNotAccessedLocs) & NO_ARGUMENT_MEM);
8857 if (HasArgAccesses)
8858 categorizeArgumentPointerLocations(A, *CB, AccessedLocs, Changed);
8859
8860 LLVM_DEBUG(
8861 dbgs() << "[AAMemoryLocation] Accessed state after argument handling: "
8862 << getMemoryLocationsAsStr(AccessedLocs.getAssumed()) << "\n");
8863
8864 return AccessedLocs.getAssumed();
8865 }
8866
8867 if (const Value *Ptr = getPointerOperand(&I, /* AllowVolatile */ true)) {
8868 LLVM_DEBUG(
8869 dbgs() << "[AAMemoryLocation] Categorize memory access with pointer: "
8870 << I << " [" << *Ptr << "]\n");
8871 categorizePtrValue(A, I, *Ptr, AccessedLocs, Changed,
8872 Ptr->getType()->getPointerAddressSpace());
8873 return AccessedLocs.getAssumed();
8874 }
8875
8876 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Failed to categorize instruction: "
8877 << I << "\n");
8878 updateStateAndAccessesMap(AccessedLocs, NO_UNKOWN_MEM, &I, nullptr, Changed,
8879 getAccessKindFromInst(&I));
8880 return AccessedLocs.getAssumed();
8881}
8882
8883/// An AA to represent the memory behavior function attributes.
8884struct AAMemoryLocationFunction final : public AAMemoryLocationImpl {
8885 AAMemoryLocationFunction(const IRPosition &IRP, Attributor &A)
8886 : AAMemoryLocationImpl(IRP, A) {}
8887
8888 /// See AbstractAttribute::updateImpl(Attributor &A).
8889 ChangeStatus updateImpl(Attributor &A) override {
8890
8891 const auto *MemBehaviorAA =
8892 A.getAAFor<AAMemoryBehavior>(*this, getIRPosition(), DepClassTy::NONE);
8893 if (MemBehaviorAA && MemBehaviorAA->isAssumedReadNone()) {
8894 if (MemBehaviorAA->isKnownReadNone())
8895 return indicateOptimisticFixpoint();
8897 "AAMemoryLocation was not read-none but AAMemoryBehavior was!");
8898 A.recordDependence(*MemBehaviorAA, *this, DepClassTy::OPTIONAL);
8899 return ChangeStatus::UNCHANGED;
8900 }
8901
8902 // The current assumed state used to determine a change.
8903 auto AssumedState = getAssumed();
8904 bool Changed = false;
8905
8906 auto CheckRWInst = [&](Instruction &I) {
8907 MemoryLocationsKind MLK = categorizeAccessedLocations(A, I, Changed);
8908 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Accessed locations for " << I
8909 << ": " << getMemoryLocationsAsStr(MLK) << "\n");
8910 removeAssumedBits(inverseLocation(MLK, false, false));
8911 // Stop once only the valid bit set in the *not assumed location*, thus
8912 // once we don't actually exclude any memory locations in the state.
8913 return getAssumedNotAccessedLocation() != VALID_STATE;
8914 };
8915
8916 bool UsedAssumedInformation = false;
8917 if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this,
8918 UsedAssumedInformation))
8919 return indicatePessimisticFixpoint();
8920
8921 Changed |= AssumedState != getAssumed();
8922 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
8923 }
8924
8925 /// See AbstractAttribute::trackStatistics()
8926 void trackStatistics() const override {
8927 if (isAssumedReadNone())
8928 STATS_DECLTRACK_FN_ATTR(readnone)
8929 else if (isAssumedArgMemOnly())
8930 STATS_DECLTRACK_FN_ATTR(argmemonly)
8931 else if (isAssumedInaccessibleMemOnly())
8932 STATS_DECLTRACK_FN_ATTR(inaccessiblememonly)
8933 else if (isAssumedInaccessibleOrArgMemOnly())
8934 STATS_DECLTRACK_FN_ATTR(inaccessiblememorargmemonly)
8935 }
8936};
8937
8938/// AAMemoryLocation attribute for call sites.
8939struct AAMemoryLocationCallSite final : AAMemoryLocationImpl {
8940 AAMemoryLocationCallSite(const IRPosition &IRP, Attributor &A)
8941 : AAMemoryLocationImpl(IRP, A) {}
8942
8943 /// See AbstractAttribute::updateImpl(...).
8944 ChangeStatus updateImpl(Attributor &A) override {
8945 // TODO: Once we have call site specific value information we can provide
8946 // call site specific liveness liveness information and then it makes
8947 // sense to specialize attributes for call sites arguments instead of
8948 // redirecting requests to the callee argument.
8949 Function *F = getAssociatedFunction();
8950 const IRPosition &FnPos = IRPosition::function(*F);
8951 auto *FnAA =
8952 A.getAAFor<AAMemoryLocation>(*this, FnPos, DepClassTy::REQUIRED);
8953 if (!FnAA)
8954 return indicatePessimisticFixpoint();
8955 bool Changed = false;
8956 auto AccessPred = [&](const Instruction *I, const Value *Ptr,
8957 AccessKind Kind, MemoryLocationsKind MLK) {
8958 updateStateAndAccessesMap(getState(), MLK, I, Ptr, Changed,
8959 getAccessKindFromInst(I));
8960 return true;
8961 };
8962 if (!FnAA->checkForAllAccessesToMemoryKind(AccessPred, ALL_LOCATIONS))
8963 return indicatePessimisticFixpoint();
8964 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
8965 }
8966
8967 /// See AbstractAttribute::trackStatistics()
8968 void trackStatistics() const override {
8969 if (isAssumedReadNone())
8970 STATS_DECLTRACK_CS_ATTR(readnone)
8971 }
8972};
8973} // namespace
8974
8975/// ------------------ denormal-fp-math Attribute -------------------------
8976
8977namespace {
8978struct AADenormalFPMathImpl : public AADenormalFPMath {
8979 AADenormalFPMathImpl(const IRPosition &IRP, Attributor &A)
8980 : AADenormalFPMath(IRP, A) {}
8981
8982 const std::string getAsStr(Attributor *A) const override {
8983 std::string Str("AADenormalFPMath[");
8984 raw_string_ostream OS(Str);
8985
8986 DenormalState Known = getKnown();
8987 if (Known.Mode.isValid())
8988 OS << "denormal-fp-math=" << Known.Mode;
8989 else
8990 OS << "invalid";
8991
8992 if (Known.ModeF32.isValid())
8993 OS << " denormal-fp-math-f32=" << Known.ModeF32;
8994 OS << ']';
8995 return Str;
8996 }
8997};
8998
8999struct AADenormalFPMathFunction final : AADenormalFPMathImpl {
9000 AADenormalFPMathFunction(const IRPosition &IRP, Attributor &A)
9001 : AADenormalFPMathImpl(IRP, A) {}
9002
9003 void initialize(Attributor &A) override {
9004 const Function *F = getAnchorScope();
9005 DenormalFPEnv DenormEnv = F->getDenormalFPEnv();
9006
9007 Known = DenormalState{DenormEnv.DefaultMode, DenormEnv.F32Mode};
9008 if (isModeFixed())
9009 indicateFixpoint();
9010 }
9011
9012 ChangeStatus updateImpl(Attributor &A) override {
9013 ChangeStatus Change = ChangeStatus::UNCHANGED;
9014
9015 auto CheckCallSite = [=, &Change, &A](AbstractCallSite CS) {
9016 Function *Caller = CS.getInstruction()->getFunction();
9017 LLVM_DEBUG(dbgs() << "[AADenormalFPMath] Call " << Caller->getName()
9018 << "->" << getAssociatedFunction()->getName() << '\n');
9019
9020 const auto *CallerInfo = A.getAAFor<AADenormalFPMath>(
9021 *this, IRPosition::function(*Caller), DepClassTy::REQUIRED);
9022 if (!CallerInfo)
9023 return false;
9024
9025 Change = Change | clampStateAndIndicateChange(this->getState(),
9026 CallerInfo->getState());
9027 return true;
9028 };
9029
9030 bool AllCallSitesKnown = true;
9031 if (!A.checkForAllCallSites(CheckCallSite, *this, true, AllCallSitesKnown))
9032 return indicatePessimisticFixpoint();
9033
9034 if (Change == ChangeStatus::CHANGED && isModeFixed())
9035 indicateFixpoint();
9036 return Change;
9037 }
9038
9039 ChangeStatus manifest(Attributor &A) override {
9040 LLVMContext &Ctx = getAssociatedFunction()->getContext();
9041
9042 SmallVector<Attribute, 2> AttrToAdd;
9044
9045 // TODO: Change to use DenormalFPEnv everywhere.
9046 DenormalFPEnv KnownEnv(Known.Mode, Known.ModeF32);
9047
9048 if (KnownEnv == DenormalFPEnv::getDefault()) {
9049 AttrToRemove.push_back(Attribute::DenormalFPEnv);
9050 } else {
9051 AttrToAdd.push_back(Attribute::get(
9052 Ctx, Attribute::DenormalFPEnv,
9053 DenormalFPEnv(Known.Mode, Known.ModeF32).toIntValue()));
9054 }
9055
9056 auto &IRP = getIRPosition();
9057
9058 // TODO: There should be a combined add and remove API.
9059 return A.removeAttrs(IRP, AttrToRemove) |
9060 A.manifestAttrs(IRP, AttrToAdd, /*ForceReplace=*/true);
9061 }
9062
9063 void trackStatistics() const override {
9064 STATS_DECLTRACK_FN_ATTR(denormal_fpenv)
9065 }
9066};
9067} // namespace
9068
9069/// ------------------ Value Constant Range Attribute -------------------------
9070
9071namespace {
9072struct AAValueConstantRangeImpl : AAValueConstantRange {
9073 using StateType = IntegerRangeState;
9074 AAValueConstantRangeImpl(const IRPosition &IRP, Attributor &A)
9075 : AAValueConstantRange(IRP, A) {}
9076
9077 /// See AbstractAttribute::initialize(..).
9078 void initialize(Attributor &A) override {
9079 if (A.hasSimplificationCallback(getIRPosition())) {
9080 indicatePessimisticFixpoint();
9081 return;
9082 }
9083
9084 // Intersect a range given by SCEV.
9085 intersectKnown(getConstantRangeFromSCEV(A, getCtxI()));
9086
9087 // Intersect a range given by LVI.
9088 intersectKnown(getConstantRangeFromLVI(A, getCtxI()));
9089 }
9090
9091 /// See AbstractAttribute::getAsStr().
9092 const std::string getAsStr(Attributor *A) const override {
9093 std::string Str;
9094 llvm::raw_string_ostream OS(Str);
9095 OS << "range(" << getBitWidth() << ")<";
9096 getKnown().print(OS);
9097 OS << " / ";
9098 getAssumed().print(OS);
9099 OS << ">";
9100 return Str;
9101 }
9102
9103 /// Helper function to get a SCEV expr for the associated value at program
9104 /// point \p I.
9105 const SCEV *getSCEV(Attributor &A, const Instruction *I = nullptr) const {
9106 if (!getAnchorScope())
9107 return nullptr;
9108
9109 ScalarEvolution *SE =
9110 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(
9111 *getAnchorScope());
9112
9113 LoopInfo *LI = A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(
9114 *getAnchorScope());
9115
9116 if (!SE || !LI)
9117 return nullptr;
9118
9119 const SCEV *S = SE->getSCEV(&getAssociatedValue());
9120 if (!I)
9121 return S;
9122
9123 return SE->getSCEVAtScope(S, LI->getLoopFor(I->getParent()));
9124 }
9125
9126 /// Helper function to get a range from SCEV for the associated value at
9127 /// program point \p I.
9128 ConstantRange getConstantRangeFromSCEV(Attributor &A,
9129 const Instruction *I = nullptr) const {
9130 if (!getAnchorScope())
9131 return getWorstState(getBitWidth());
9132
9133 ScalarEvolution *SE =
9134 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(
9135 *getAnchorScope());
9136
9137 const SCEV *S = getSCEV(A, I);
9138 if (!SE || !S)
9139 return getWorstState(getBitWidth());
9140
9141 return SE->getUnsignedRange(S);
9142 }
9143
9144 /// Helper function to get a range from LVI for the associated value at
9145 /// program point \p I.
9146 ConstantRange
9147 getConstantRangeFromLVI(Attributor &A,
9148 const Instruction *CtxI = nullptr) const {
9149 if (!getAnchorScope())
9150 return getWorstState(getBitWidth());
9151
9152 LazyValueInfo *LVI =
9153 A.getInfoCache().getAnalysisResultForFunction<LazyValueAnalysis>(
9154 *getAnchorScope());
9155
9156 if (!LVI || !CtxI)
9157 return getWorstState(getBitWidth());
9158 return LVI->getConstantRange(&getAssociatedValue(),
9159 const_cast<Instruction *>(CtxI),
9160 /*UndefAllowed*/ false);
9161 }
9162
9163 /// Return true if \p CtxI is valid for querying outside analyses.
9164 /// This basically makes sure we do not ask intra-procedural analysis
9165 /// about a context in the wrong function or a context that violates
9166 /// dominance assumptions they might have. The \p AllowAACtxI flag indicates
9167 /// if the original context of this AA is OK or should be considered invalid.
9168 bool isValidCtxInstructionForOutsideAnalysis(Attributor &A,
9169 const Instruction *CtxI,
9170 bool AllowAACtxI) const {
9171 if (!CtxI || (!AllowAACtxI && CtxI == getCtxI()))
9172 return false;
9173
9174 // Our context might be in a different function, neither intra-procedural
9175 // analysis (ScalarEvolution nor LazyValueInfo) can handle that.
9176 if (!AA::isValidInScope(getAssociatedValue(), CtxI->getFunction()))
9177 return false;
9178
9179 // If the context is not dominated by the value there are paths to the
9180 // context that do not define the value. This cannot be handled by
9181 // LazyValueInfo so we need to bail.
9182 if (auto *I = dyn_cast<Instruction>(&getAssociatedValue())) {
9183 InformationCache &InfoCache = A.getInfoCache();
9184 const DominatorTree *DT =
9185 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(
9186 *I->getFunction());
9187 return DT && DT->dominates(I, CtxI);
9188 }
9189
9190 return true;
9191 }
9192
9193 /// See AAValueConstantRange::getKnownConstantRange(..).
9194 ConstantRange
9195 getKnownConstantRange(Attributor &A,
9196 const Instruction *CtxI = nullptr) const override {
9197 if (!isValidCtxInstructionForOutsideAnalysis(A, CtxI,
9198 /* AllowAACtxI */ false))
9199 return getKnown();
9200
9201 ConstantRange LVIR = getConstantRangeFromLVI(A, CtxI);
9202 ConstantRange SCEVR = getConstantRangeFromSCEV(A, CtxI);
9203 return getKnown().intersectWith(SCEVR).intersectWith(LVIR);
9204 }
9205
9206 /// See AAValueConstantRange::getAssumedConstantRange(..).
9207 ConstantRange
9208 getAssumedConstantRange(Attributor &A,
9209 const Instruction *CtxI = nullptr) const override {
9210 // TODO: Make SCEV use Attributor assumption.
9211 // We may be able to bound a variable range via assumptions in
9212 // Attributor. ex.) If x is assumed to be in [1, 3] and y is known to
9213 // evolve to x^2 + x, then we can say that y is in [2, 12].
9214 if (!isValidCtxInstructionForOutsideAnalysis(A, CtxI,
9215 /* AllowAACtxI */ false))
9216 return getAssumed();
9217
9218 ConstantRange LVIR = getConstantRangeFromLVI(A, CtxI);
9219 ConstantRange SCEVR = getConstantRangeFromSCEV(A, CtxI);
9220 return getAssumed().intersectWith(SCEVR).intersectWith(LVIR);
9221 }
9222
9223 /// Helper function to create MDNode for range metadata.
9224 static MDNode *
9225 getMDNodeForConstantRange(Type *Ty, LLVMContext &Ctx,
9226 const ConstantRange &AssumedConstantRange) {
9227 Metadata *LowAndHigh[] = {ConstantAsMetadata::get(ConstantInt::get(
9228 Ty, AssumedConstantRange.getLower())),
9229 ConstantAsMetadata::get(ConstantInt::get(
9230 Ty, AssumedConstantRange.getUpper()))};
9231 return MDNode::get(Ctx, LowAndHigh);
9232 }
9233
9234 /// Return true if \p Assumed is included in ranges from instruction \p I.
9235 static bool isBetterRange(const ConstantRange &Assumed,
9236 const Instruction &I) {
9237 if (Assumed.isFullSet())
9238 return false;
9239
9240 std::optional<ConstantRange> Known;
9241
9242 if (const auto *CB = dyn_cast<CallBase>(&I)) {
9243 Known = CB->getRange();
9244 } else if (MDNode *KnownRanges = I.getMetadata(LLVMContext::MD_range)) {
9245 // If multiple ranges are annotated in IR, we give up to annotate assumed
9246 // range for now.
9247
9248 // TODO: If there exists a known range which containts assumed range, we
9249 // can say assumed range is better.
9250 if (KnownRanges->getNumOperands() > 2)
9251 return false;
9252
9253 ConstantInt *Lower =
9254 mdconst::extract<ConstantInt>(KnownRanges->getOperand(0));
9255 ConstantInt *Upper =
9256 mdconst::extract<ConstantInt>(KnownRanges->getOperand(1));
9257
9258 Known.emplace(Lower->getValue(), Upper->getValue());
9259 }
9260 return !Known || (*Known != Assumed && Known->contains(Assumed));
9261 }
9262
9263 /// Helper function to set range metadata.
9264 static bool
9265 setRangeMetadataIfisBetterRange(Instruction *I,
9266 const ConstantRange &AssumedConstantRange) {
9267 if (isBetterRange(AssumedConstantRange, *I)) {
9268 I->setMetadata(LLVMContext::MD_range,
9269 getMDNodeForConstantRange(I->getType(), I->getContext(),
9270 AssumedConstantRange));
9271 return true;
9272 }
9273 return false;
9274 }
9275 /// Helper function to set range return attribute.
9276 static bool
9277 setRangeRetAttrIfisBetterRange(Attributor &A, const IRPosition &IRP,
9278 Instruction *I,
9279 const ConstantRange &AssumedConstantRange) {
9280 if (isBetterRange(AssumedConstantRange, *I)) {
9281 A.manifestAttrs(IRP,
9282 Attribute::get(I->getContext(), Attribute::Range,
9283 AssumedConstantRange),
9284 /*ForceReplace*/ true);
9285 return true;
9286 }
9287 return false;
9288 }
9289
9290 /// See AbstractAttribute::manifest()
9291 ChangeStatus manifest(Attributor &A) override {
9292 ChangeStatus Changed = ChangeStatus::UNCHANGED;
9293 ConstantRange AssumedConstantRange = getAssumedConstantRange(A);
9294 assert(!AssumedConstantRange.isFullSet() && "Invalid state");
9295
9296 auto &V = getAssociatedValue();
9297 if (!AssumedConstantRange.isEmptySet() &&
9298 !AssumedConstantRange.isSingleElement()) {
9299 if (Instruction *I = dyn_cast<Instruction>(&V)) {
9300 assert(I == getCtxI() && "Should not annotate an instruction which is "
9301 "not the context instruction");
9302 if (isa<LoadInst>(I))
9303 if (setRangeMetadataIfisBetterRange(I, AssumedConstantRange))
9304 Changed = ChangeStatus::CHANGED;
9305 if (isa<CallInst>(I))
9306 if (setRangeRetAttrIfisBetterRange(A, getIRPosition(), I,
9307 AssumedConstantRange))
9308 Changed = ChangeStatus::CHANGED;
9309 }
9310 }
9311
9312 return Changed;
9313 }
9314};
9315
9316struct AAValueConstantRangeArgument final
9317 : AAArgumentFromCallSiteArguments<
9318 AAValueConstantRange, AAValueConstantRangeImpl, IntegerRangeState,
9319 true /* BridgeCallBaseContext */> {
9320 using Base = AAArgumentFromCallSiteArguments<
9321 AAValueConstantRange, AAValueConstantRangeImpl, IntegerRangeState,
9322 true /* BridgeCallBaseContext */>;
9323 AAValueConstantRangeArgument(const IRPosition &IRP, Attributor &A)
9324 : Base(IRP, A) {}
9325
9326 /// See AbstractAttribute::trackStatistics()
9327 void trackStatistics() const override {
9328 STATS_DECLTRACK_ARG_ATTR(value_range)
9329 }
9330};
9331
9332struct AAValueConstantRangeReturned
9333 : AAReturnedFromReturnedValues<AAValueConstantRange,
9334 AAValueConstantRangeImpl,
9335 AAValueConstantRangeImpl::StateType,
9336 /* PropagateCallBaseContext */ true> {
9337 using Base =
9338 AAReturnedFromReturnedValues<AAValueConstantRange,
9339 AAValueConstantRangeImpl,
9340 AAValueConstantRangeImpl::StateType,
9341 /* PropagateCallBaseContext */ true>;
9342 AAValueConstantRangeReturned(const IRPosition &IRP, Attributor &A)
9343 : Base(IRP, A) {}
9344
9345 /// See AbstractAttribute::initialize(...).
9346 void initialize(Attributor &A) override {
9347 if (!A.isFunctionIPOAmendable(*getAssociatedFunction()))
9348 indicatePessimisticFixpoint();
9349 }
9350
9351 /// See AbstractAttribute::trackStatistics()
9352 void trackStatistics() const override {
9353 STATS_DECLTRACK_FNRET_ATTR(value_range)
9354 }
9355};
9356
9357struct AAValueConstantRangeFloating : AAValueConstantRangeImpl {
9358 AAValueConstantRangeFloating(const IRPosition &IRP, Attributor &A)
9359 : AAValueConstantRangeImpl(IRP, A) {}
9360
9361 /// See AbstractAttribute::initialize(...).
9362 void initialize(Attributor &A) override {
9363 AAValueConstantRangeImpl::initialize(A);
9364 if (isAtFixpoint())
9365 return;
9366
9367 Value &V = getAssociatedValue();
9368
9369 if (auto *C = dyn_cast<ConstantInt>(&V)) {
9370 unionAssumed(ConstantRange(C->getValue()));
9371 indicateOptimisticFixpoint();
9372 return;
9373 }
9374
9375 if (isa<UndefValue>(&V)) {
9376 // Collapse the undef state to 0.
9377 unionAssumed(ConstantRange(APInt(getBitWidth(), 0)));
9378 indicateOptimisticFixpoint();
9379 return;
9380 }
9381
9382 if (isa<CallBase>(&V))
9383 return;
9384
9385 if (isa<BinaryOperator>(&V) || isa<CmpInst>(&V) || isa<CastInst>(&V))
9386 return;
9387
9388 // If it is a load instruction with range metadata, use it.
9389 if (LoadInst *LI = dyn_cast<LoadInst>(&V))
9390 if (auto *RangeMD = LI->getMetadata(LLVMContext::MD_range)) {
9391 intersectKnown(getConstantRangeFromMetadata(*RangeMD));
9392 return;
9393 }
9394
9395 // We can work with PHI and select instruction as we traverse their operands
9396 // during update.
9397 if (isa<SelectInst>(V) || isa<PHINode>(V))
9398 return;
9399
9400 // Otherwise we give up.
9401 indicatePessimisticFixpoint();
9402
9403 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] We give up: "
9404 << getAssociatedValue() << "\n");
9405 }
9406
9407 bool calculateBinaryOperator(
9408 Attributor &A, BinaryOperator *BinOp, IntegerRangeState &T,
9409 const Instruction *CtxI,
9410 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) {
9411 Value *LHS = BinOp->getOperand(0);
9412 Value *RHS = BinOp->getOperand(1);
9413
9414 // Simplify the operands first.
9415 bool UsedAssumedInformation = false;
9416 const auto &SimplifiedLHS = A.getAssumedSimplified(
9417 IRPosition::value(*LHS, getCallBaseContext()), *this,
9418 UsedAssumedInformation, AA::Interprocedural);
9419 if (!SimplifiedLHS.has_value())
9420 return true;
9421 if (!*SimplifiedLHS)
9422 return false;
9423 LHS = *SimplifiedLHS;
9424
9425 const auto &SimplifiedRHS = A.getAssumedSimplified(
9426 IRPosition::value(*RHS, getCallBaseContext()), *this,
9427 UsedAssumedInformation, AA::Interprocedural);
9428 if (!SimplifiedRHS.has_value())
9429 return true;
9430 if (!*SimplifiedRHS)
9431 return false;
9432 RHS = *SimplifiedRHS;
9433
9434 // TODO: Allow non integers as well.
9435 if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy())
9436 return false;
9437
9438 auto *LHSAA = A.getAAFor<AAValueConstantRange>(
9439 *this, IRPosition::value(*LHS, getCallBaseContext()),
9440 DepClassTy::REQUIRED);
9441 if (!LHSAA)
9442 return false;
9443 QuerriedAAs.push_back(LHSAA);
9444 auto LHSAARange = LHSAA->getAssumedConstantRange(A, CtxI);
9445
9446 auto *RHSAA = A.getAAFor<AAValueConstantRange>(
9447 *this, IRPosition::value(*RHS, getCallBaseContext()),
9448 DepClassTy::REQUIRED);
9449 if (!RHSAA)
9450 return false;
9451 QuerriedAAs.push_back(RHSAA);
9452 auto RHSAARange = RHSAA->getAssumedConstantRange(A, CtxI);
9453
9454 auto AssumedRange = LHSAARange.binaryOp(BinOp->getOpcode(), RHSAARange);
9455
9456 T.unionAssumed(AssumedRange);
9457
9458 // TODO: Track a known state too.
9459
9460 return T.isValidState();
9461 }
9462
9463 bool calculateCastInst(
9464 Attributor &A, CastInst *CastI, IntegerRangeState &T,
9465 const Instruction *CtxI,
9466 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) {
9467 assert(CastI->getNumOperands() == 1 && "Expected cast to be unary!");
9468 // TODO: Allow non integers as well.
9469 Value *OpV = CastI->getOperand(0);
9470
9471 // Simplify the operand first.
9472 bool UsedAssumedInformation = false;
9473 const auto &SimplifiedOpV = A.getAssumedSimplified(
9474 IRPosition::value(*OpV, getCallBaseContext()), *this,
9475 UsedAssumedInformation, AA::Interprocedural);
9476 if (!SimplifiedOpV.has_value())
9477 return true;
9478 if (!*SimplifiedOpV)
9479 return false;
9480 OpV = *SimplifiedOpV;
9481
9482 if (!OpV->getType()->isIntegerTy())
9483 return false;
9484
9485 auto *OpAA = A.getAAFor<AAValueConstantRange>(
9486 *this, IRPosition::value(*OpV, getCallBaseContext()),
9487 DepClassTy::REQUIRED);
9488 if (!OpAA)
9489 return false;
9490 QuerriedAAs.push_back(OpAA);
9491 T.unionAssumed(OpAA->getAssumed().castOp(CastI->getOpcode(),
9492 getState().getBitWidth()));
9493 return T.isValidState();
9494 }
9495
9496 bool
9497 calculateCmpInst(Attributor &A, CmpInst *CmpI, IntegerRangeState &T,
9498 const Instruction *CtxI,
9499 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) {
9500 Value *LHS = CmpI->getOperand(0);
9501 Value *RHS = CmpI->getOperand(1);
9502
9503 // Simplify the operands first.
9504 bool UsedAssumedInformation = false;
9505 const auto &SimplifiedLHS = A.getAssumedSimplified(
9506 IRPosition::value(*LHS, getCallBaseContext()), *this,
9507 UsedAssumedInformation, AA::Interprocedural);
9508 if (!SimplifiedLHS.has_value())
9509 return true;
9510 if (!*SimplifiedLHS)
9511 return false;
9512 LHS = *SimplifiedLHS;
9513
9514 const auto &SimplifiedRHS = A.getAssumedSimplified(
9515 IRPosition::value(*RHS, getCallBaseContext()), *this,
9516 UsedAssumedInformation, AA::Interprocedural);
9517 if (!SimplifiedRHS.has_value())
9518 return true;
9519 if (!*SimplifiedRHS)
9520 return false;
9521 RHS = *SimplifiedRHS;
9522
9523 // TODO: Allow non integers as well.
9524 if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy())
9525 return false;
9526
9527 auto *LHSAA = A.getAAFor<AAValueConstantRange>(
9528 *this, IRPosition::value(*LHS, getCallBaseContext()),
9529 DepClassTy::REQUIRED);
9530 if (!LHSAA)
9531 return false;
9532 QuerriedAAs.push_back(LHSAA);
9533 auto *RHSAA = A.getAAFor<AAValueConstantRange>(
9534 *this, IRPosition::value(*RHS, getCallBaseContext()),
9535 DepClassTy::REQUIRED);
9536 if (!RHSAA)
9537 return false;
9538 QuerriedAAs.push_back(RHSAA);
9539 auto LHSAARange = LHSAA->getAssumedConstantRange(A, CtxI);
9540 auto RHSAARange = RHSAA->getAssumedConstantRange(A, CtxI);
9541
9542 // If one of them is empty set, we can't decide.
9543 if (LHSAARange.isEmptySet() || RHSAARange.isEmptySet())
9544 return true;
9545
9546 bool MustTrue = false, MustFalse = false;
9547
9548 auto AllowedRegion =
9550
9551 if (AllowedRegion.intersectWith(LHSAARange).isEmptySet())
9552 MustFalse = true;
9553
9554 if (LHSAARange.icmp(CmpI->getPredicate(), RHSAARange))
9555 MustTrue = true;
9556
9557 assert((!MustTrue || !MustFalse) &&
9558 "Either MustTrue or MustFalse should be false!");
9559
9560 if (MustTrue)
9561 T.unionAssumed(ConstantRange(APInt(/* numBits */ 1, /* val */ 1)));
9562 else if (MustFalse)
9563 T.unionAssumed(ConstantRange(APInt(/* numBits */ 1, /* val */ 0)));
9564 else
9565 T.unionAssumed(ConstantRange(/* BitWidth */ 1, /* isFullSet */ true));
9566
9567 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] " << *CmpI << " after "
9568 << (MustTrue ? "true" : (MustFalse ? "false" : "unknown"))
9569 << ": " << T << "\n\t" << *LHSAA << "\t<op>\n\t"
9570 << *RHSAA);
9571
9572 // TODO: Track a known state too.
9573 return T.isValidState();
9574 }
9575
9576 /// See AbstractAttribute::updateImpl(...).
9577 ChangeStatus updateImpl(Attributor &A) override {
9578
9579 IntegerRangeState T(getBitWidth());
9580 auto VisitValueCB = [&](Value &V, const Instruction *CtxI) -> bool {
9582 if (!I || isa<CallBase>(I)) {
9583
9584 // Simplify the operand first.
9585 bool UsedAssumedInformation = false;
9586 const auto &SimplifiedOpV = A.getAssumedSimplified(
9587 IRPosition::value(V, getCallBaseContext()), *this,
9588 UsedAssumedInformation, AA::Interprocedural);
9589 if (!SimplifiedOpV.has_value())
9590 return true;
9591 if (!*SimplifiedOpV)
9592 return false;
9593 Value *VPtr = *SimplifiedOpV;
9594
9595 // If the value is not instruction, we query AA to Attributor.
9596 const auto *AA = A.getAAFor<AAValueConstantRange>(
9597 *this, IRPosition::value(*VPtr, getCallBaseContext()),
9598 DepClassTy::REQUIRED);
9599
9600 // Clamp operator is not used to utilize a program point CtxI.
9601 if (AA)
9602 T.unionAssumed(AA->getAssumedConstantRange(A, CtxI));
9603 else
9604 return false;
9605
9606 return T.isValidState();
9607 }
9608
9610 if (auto *BinOp = dyn_cast<BinaryOperator>(I)) {
9611 if (!calculateBinaryOperator(A, BinOp, T, CtxI, QuerriedAAs))
9612 return false;
9613 } else if (auto *CmpI = dyn_cast<CmpInst>(I)) {
9614 if (!calculateCmpInst(A, CmpI, T, CtxI, QuerriedAAs))
9615 return false;
9616 } else if (auto *CastI = dyn_cast<CastInst>(I)) {
9617 if (!calculateCastInst(A, CastI, T, CtxI, QuerriedAAs))
9618 return false;
9619 } else {
9620 // Give up with other instructions.
9621 // TODO: Add other instructions
9622
9623 T.indicatePessimisticFixpoint();
9624 return false;
9625 }
9626
9627 // Catch circular reasoning in a pessimistic way for now.
9628 // TODO: Check how the range evolves and if we stripped anything, see also
9629 // AADereferenceable or AAAlign for similar situations.
9630 for (const AAValueConstantRange *QueriedAA : QuerriedAAs) {
9631 if (QueriedAA != this)
9632 continue;
9633 // If we are in a stady state we do not need to worry.
9634 if (T.getAssumed() == getState().getAssumed())
9635 continue;
9636 T.indicatePessimisticFixpoint();
9637 }
9638
9639 return T.isValidState();
9640 };
9641
9642 if (!VisitValueCB(getAssociatedValue(), getCtxI()))
9643 return indicatePessimisticFixpoint();
9644
9645 // Ensure that long def-use chains can't cause circular reasoning either by
9646 // introducing a cutoff below.
9647 if (clampStateAndIndicateChange(getState(), T) == ChangeStatus::UNCHANGED)
9648 return ChangeStatus::UNCHANGED;
9649 if (++NumChanges > MaxNumChanges) {
9650 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] performed " << NumChanges
9651 << " but only " << MaxNumChanges
9652 << " are allowed to avoid cyclic reasoning.");
9653 return indicatePessimisticFixpoint();
9654 }
9655 return ChangeStatus::CHANGED;
9656 }
9657
9658 /// See AbstractAttribute::trackStatistics()
9659 void trackStatistics() const override {
9661 }
9662
9663 /// Tracker to bail after too many widening steps of the constant range.
9664 int NumChanges = 0;
9665
9666 /// Upper bound for the number of allowed changes (=widening steps) for the
9667 /// constant range before we give up.
9668 static constexpr int MaxNumChanges = 5;
9669};
9670
9671struct AAValueConstantRangeFunction : AAValueConstantRangeImpl {
9672 AAValueConstantRangeFunction(const IRPosition &IRP, Attributor &A)
9673 : AAValueConstantRangeImpl(IRP, A) {}
9674
9675 /// See AbstractAttribute::initialize(...).
9676 ChangeStatus updateImpl(Attributor &A) override {
9677 llvm_unreachable("AAValueConstantRange(Function|CallSite)::updateImpl will "
9678 "not be called");
9679 }
9680
9681 /// See AbstractAttribute::trackStatistics()
9682 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(value_range) }
9683};
9684
9685struct AAValueConstantRangeCallSite : AAValueConstantRangeFunction {
9686 AAValueConstantRangeCallSite(const IRPosition &IRP, Attributor &A)
9687 : AAValueConstantRangeFunction(IRP, A) {}
9688
9689 /// See AbstractAttribute::trackStatistics()
9690 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(value_range) }
9691};
9692
9693struct AAValueConstantRangeCallSiteReturned
9694 : AACalleeToCallSite<AAValueConstantRange, AAValueConstantRangeImpl,
9695 AAValueConstantRangeImpl::StateType,
9696 /* IntroduceCallBaseContext */ true> {
9697 AAValueConstantRangeCallSiteReturned(const IRPosition &IRP, Attributor &A)
9698 : AACalleeToCallSite<AAValueConstantRange, AAValueConstantRangeImpl,
9699 AAValueConstantRangeImpl::StateType,
9700 /* IntroduceCallBaseContext */ true>(IRP, A) {}
9701
9702 /// See AbstractAttribute::initialize(...).
9703 void initialize(Attributor &A) override {
9704 // If it is a call instruction with range attribute, use the range.
9705 if (CallInst *CI = dyn_cast<CallInst>(&getAssociatedValue())) {
9706 if (std::optional<ConstantRange> Range = CI->getRange())
9707 intersectKnown(*Range);
9708 }
9709
9710 AAValueConstantRangeImpl::initialize(A);
9711 }
9712
9713 /// See AbstractAttribute::trackStatistics()
9714 void trackStatistics() const override {
9715 STATS_DECLTRACK_CSRET_ATTR(value_range)
9716 }
9717};
9718struct AAValueConstantRangeCallSiteArgument : AAValueConstantRangeFloating {
9719 AAValueConstantRangeCallSiteArgument(const IRPosition &IRP, Attributor &A)
9720 : AAValueConstantRangeFloating(IRP, A) {}
9721
9722 /// See AbstractAttribute::manifest()
9723 ChangeStatus manifest(Attributor &A) override {
9724 return ChangeStatus::UNCHANGED;
9725 }
9726
9727 /// See AbstractAttribute::trackStatistics()
9728 void trackStatistics() const override {
9729 STATS_DECLTRACK_CSARG_ATTR(value_range)
9730 }
9731};
9732} // namespace
9733
9734/// ------------------ Potential Values Attribute -------------------------
9735
9736namespace {
9737struct AAPotentialConstantValuesImpl : AAPotentialConstantValues {
9738 using StateType = PotentialConstantIntValuesState;
9739
9740 AAPotentialConstantValuesImpl(const IRPosition &IRP, Attributor &A)
9741 : AAPotentialConstantValues(IRP, A) {}
9742
9743 /// See AbstractAttribute::initialize(..).
9744 void initialize(Attributor &A) override {
9745 if (A.hasSimplificationCallback(getIRPosition()))
9746 indicatePessimisticFixpoint();
9747 else
9748 AAPotentialConstantValues::initialize(A);
9749 }
9750
9751 bool fillSetWithConstantValues(Attributor &A, const IRPosition &IRP, SetTy &S,
9752 bool &ContainsUndef, bool ForSelf) {
9754 bool UsedAssumedInformation = false;
9755 if (!A.getAssumedSimplifiedValues(IRP, *this, Values, AA::Interprocedural,
9756 UsedAssumedInformation)) {
9757 // Avoid recursion when the caller is computing constant values for this
9758 // IRP itself.
9759 if (ForSelf)
9760 return false;
9761 if (!IRP.getAssociatedType()->isIntegerTy())
9762 return false;
9763 auto *PotentialValuesAA = A.getAAFor<AAPotentialConstantValues>(
9764 *this, IRP, DepClassTy::REQUIRED);
9765 if (!PotentialValuesAA || !PotentialValuesAA->getState().isValidState())
9766 return false;
9767 ContainsUndef = PotentialValuesAA->getState().undefIsContained();
9768 S = PotentialValuesAA->getState().getAssumedSet();
9769 return true;
9770 }
9771
9772 // Copy all the constant values, except UndefValue. ContainsUndef is true
9773 // iff Values contains only UndefValue instances. If there are other known
9774 // constants, then UndefValue is dropped.
9775 ContainsUndef = false;
9776 for (auto &It : Values) {
9777 if (isa<UndefValue>(It.getValue())) {
9778 ContainsUndef = true;
9779 continue;
9780 }
9781 auto *CI = dyn_cast<ConstantInt>(It.getValue());
9782 if (!CI)
9783 return false;
9784 S.insert(CI->getValue());
9785 }
9786 ContainsUndef &= S.empty();
9787
9788 return true;
9789 }
9790
9791 /// See AbstractAttribute::getAsStr().
9792 const std::string getAsStr(Attributor *A) const override {
9793 std::string Str;
9794 llvm::raw_string_ostream OS(Str);
9795 OS << getState();
9796 return Str;
9797 }
9798
9799 /// See AbstractAttribute::updateImpl(...).
9800 ChangeStatus updateImpl(Attributor &A) override {
9801 return indicatePessimisticFixpoint();
9802 }
9803};
9804
9805struct AAPotentialConstantValuesArgument final
9806 : AAArgumentFromCallSiteArguments<AAPotentialConstantValues,
9807 AAPotentialConstantValuesImpl,
9808 PotentialConstantIntValuesState> {
9809 using Base = AAArgumentFromCallSiteArguments<AAPotentialConstantValues,
9810 AAPotentialConstantValuesImpl,
9812 AAPotentialConstantValuesArgument(const IRPosition &IRP, Attributor &A)
9813 : Base(IRP, A) {}
9814
9815 /// See AbstractAttribute::trackStatistics()
9816 void trackStatistics() const override {
9817 STATS_DECLTRACK_ARG_ATTR(potential_values)
9818 }
9819};
9820
9821struct AAPotentialConstantValuesReturned
9822 : AAReturnedFromReturnedValues<AAPotentialConstantValues,
9823 AAPotentialConstantValuesImpl> {
9824 using Base = AAReturnedFromReturnedValues<AAPotentialConstantValues,
9825 AAPotentialConstantValuesImpl>;
9826 AAPotentialConstantValuesReturned(const IRPosition &IRP, Attributor &A)
9827 : Base(IRP, A) {}
9828
9829 void initialize(Attributor &A) override {
9830 if (!A.isFunctionIPOAmendable(*getAssociatedFunction()))
9831 indicatePessimisticFixpoint();
9832 Base::initialize(A);
9833 }
9834
9835 /// See AbstractAttribute::trackStatistics()
9836 void trackStatistics() const override {
9837 STATS_DECLTRACK_FNRET_ATTR(potential_values)
9838 }
9839};
9840
9841struct AAPotentialConstantValuesFloating : AAPotentialConstantValuesImpl {
9842 AAPotentialConstantValuesFloating(const IRPosition &IRP, Attributor &A)
9843 : AAPotentialConstantValuesImpl(IRP, A) {}
9844
9845 /// See AbstractAttribute::initialize(..).
9846 void initialize(Attributor &A) override {
9847 AAPotentialConstantValuesImpl::initialize(A);
9848 if (isAtFixpoint())
9849 return;
9850
9851 Value &V = getAssociatedValue();
9852
9853 if (auto *C = dyn_cast<ConstantInt>(&V)) {
9854 unionAssumed(C->getValue());
9855 indicateOptimisticFixpoint();
9856 return;
9857 }
9858
9859 if (isa<UndefValue>(&V)) {
9860 unionAssumedWithUndef();
9861 indicateOptimisticFixpoint();
9862 return;
9863 }
9864
9865 if (isa<BinaryOperator>(&V) || isa<ICmpInst>(&V) || isa<CastInst>(&V))
9866 return;
9867
9868 if (isa<SelectInst>(V) || isa<PHINode>(V) || isa<LoadInst>(V))
9869 return;
9870
9871 indicatePessimisticFixpoint();
9872
9873 LLVM_DEBUG(dbgs() << "[AAPotentialConstantValues] We give up: "
9874 << getAssociatedValue() << "\n");
9875 }
9876
9877 static bool calculateICmpInst(const ICmpInst *ICI, const APInt &LHS,
9878 const APInt &RHS) {
9879 return ICmpInst::compare(LHS, RHS, ICI->getPredicate());
9880 }
9881
9882 static APInt calculateCastInst(const CastInst *CI, const APInt &Src,
9883 uint32_t ResultBitWidth) {
9884 Instruction::CastOps CastOp = CI->getOpcode();
9885 switch (CastOp) {
9886 default:
9887 llvm_unreachable("unsupported or not integer cast");
9888 case Instruction::Trunc:
9889 return Src.trunc(ResultBitWidth);
9890 case Instruction::SExt:
9891 return Src.sext(ResultBitWidth);
9892 case Instruction::ZExt:
9893 return Src.zext(ResultBitWidth);
9894 case Instruction::BitCast:
9895 return Src;
9896 }
9897 }
9898
9899 static APInt calculateBinaryOperator(const BinaryOperator *BinOp,
9900 const APInt &LHS, const APInt &RHS,
9901 bool &SkipOperation, bool &Unsupported) {
9902 Instruction::BinaryOps BinOpcode = BinOp->getOpcode();
9903 // Unsupported is set to true when the binary operator is not supported.
9904 // SkipOperation is set to true when UB occur with the given operand pair
9905 // (LHS, RHS).
9906 // TODO: we should look at nsw and nuw keywords to handle operations
9907 // that create poison or undef value.
9908 switch (BinOpcode) {
9909 default:
9910 Unsupported = true;
9911 return LHS;
9912 case Instruction::Add:
9913 return LHS + RHS;
9914 case Instruction::Sub:
9915 return LHS - RHS;
9916 case Instruction::Mul:
9917 return LHS * RHS;
9918 case Instruction::UDiv:
9919 if (RHS.isZero()) {
9920 SkipOperation = true;
9921 return LHS;
9922 }
9923 return LHS.udiv(RHS);
9924 case Instruction::SDiv:
9925 if (RHS.isZero()) {
9926 SkipOperation = true;
9927 return LHS;
9928 }
9929 return LHS.sdiv(RHS);
9930 case Instruction::URem:
9931 if (RHS.isZero()) {
9932 SkipOperation = true;
9933 return LHS;
9934 }
9935 return LHS.urem(RHS);
9936 case Instruction::SRem:
9937 if (RHS.isZero()) {
9938 SkipOperation = true;
9939 return LHS;
9940 }
9941 return LHS.srem(RHS);
9942 case Instruction::Shl:
9943 return LHS.shl(RHS);
9944 case Instruction::LShr:
9945 return LHS.lshr(RHS);
9946 case Instruction::AShr:
9947 return LHS.ashr(RHS);
9948 case Instruction::And:
9949 return LHS & RHS;
9950 case Instruction::Or:
9951 return LHS | RHS;
9952 case Instruction::Xor:
9953 return LHS ^ RHS;
9954 }
9955 }
9956
9957 bool calculateBinaryOperatorAndTakeUnion(const BinaryOperator *BinOp,
9958 const APInt &LHS, const APInt &RHS) {
9959 bool SkipOperation = false;
9960 bool Unsupported = false;
9961 APInt Result =
9962 calculateBinaryOperator(BinOp, LHS, RHS, SkipOperation, Unsupported);
9963 if (Unsupported)
9964 return false;
9965 // If SkipOperation is true, we can ignore this operand pair (L, R).
9966 if (!SkipOperation)
9967 unionAssumed(Result);
9968 return isValidState();
9969 }
9970
9971 ChangeStatus updateWithICmpInst(Attributor &A, ICmpInst *ICI) {
9972 auto AssumedBefore = getAssumed();
9973 Value *LHS = ICI->getOperand(0);
9974 Value *RHS = ICI->getOperand(1);
9975
9976 bool LHSContainsUndef = false, RHSContainsUndef = false;
9977 SetTy LHSAAPVS, RHSAAPVS;
9978 if (!fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS,
9979 LHSContainsUndef, /* ForSelf */ false) ||
9980 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS,
9981 RHSContainsUndef, /* ForSelf */ false))
9982 return indicatePessimisticFixpoint();
9983
9984 // TODO: make use of undef flag to limit potential values aggressively.
9985 bool MaybeTrue = false, MaybeFalse = false;
9986 const APInt Zero(RHS->getType()->getIntegerBitWidth(), 0);
9987 if (LHSContainsUndef && RHSContainsUndef) {
9988 // The result of any comparison between undefs can be soundly replaced
9989 // with undef.
9990 unionAssumedWithUndef();
9991 } else if (LHSContainsUndef) {
9992 for (const APInt &R : RHSAAPVS) {
9993 bool CmpResult = calculateICmpInst(ICI, Zero, R);
9994 MaybeTrue |= CmpResult;
9995 MaybeFalse |= !CmpResult;
9996 if (MaybeTrue & MaybeFalse)
9997 return indicatePessimisticFixpoint();
9998 }
9999 } else if (RHSContainsUndef) {
10000 for (const APInt &L : LHSAAPVS) {
10001 bool CmpResult = calculateICmpInst(ICI, L, Zero);
10002 MaybeTrue |= CmpResult;
10003 MaybeFalse |= !CmpResult;
10004 if (MaybeTrue & MaybeFalse)
10005 return indicatePessimisticFixpoint();
10006 }
10007 } else {
10008 for (const APInt &L : LHSAAPVS) {
10009 for (const APInt &R : RHSAAPVS) {
10010 bool CmpResult = calculateICmpInst(ICI, L, R);
10011 MaybeTrue |= CmpResult;
10012 MaybeFalse |= !CmpResult;
10013 if (MaybeTrue & MaybeFalse)
10014 return indicatePessimisticFixpoint();
10015 }
10016 }
10017 }
10018 if (MaybeTrue)
10019 unionAssumed(APInt(/* numBits */ 1, /* val */ 1));
10020 if (MaybeFalse)
10021 unionAssumed(APInt(/* numBits */ 1, /* val */ 0));
10022 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10023 : ChangeStatus::CHANGED;
10024 }
10025
10026 ChangeStatus updateWithSelectInst(Attributor &A, SelectInst *SI) {
10027 auto AssumedBefore = getAssumed();
10028 Value *LHS = SI->getTrueValue();
10029 Value *RHS = SI->getFalseValue();
10030
10031 bool UsedAssumedInformation = false;
10032 std::optional<Constant *> C = A.getAssumedConstant(
10033 *SI->getCondition(), *this, UsedAssumedInformation);
10034
10035 // Check if we only need one operand.
10036 bool OnlyLeft = false, OnlyRight = false;
10037 if (C && *C && (*C)->isOneValue())
10038 OnlyLeft = true;
10039 else if (C && *C && (*C)->isNullValue())
10040 OnlyRight = true;
10041
10042 bool LHSContainsUndef = false, RHSContainsUndef = false;
10043 SetTy LHSAAPVS, RHSAAPVS;
10044 if (!OnlyRight &&
10045 !fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS,
10046 LHSContainsUndef, /* ForSelf */ false))
10047 return indicatePessimisticFixpoint();
10048
10049 if (!OnlyLeft &&
10050 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS,
10051 RHSContainsUndef, /* ForSelf */ false))
10052 return indicatePessimisticFixpoint();
10053
10054 if (OnlyLeft || OnlyRight) {
10055 // select (true/false), lhs, rhs
10056 auto *OpAA = OnlyLeft ? &LHSAAPVS : &RHSAAPVS;
10057 auto Undef = OnlyLeft ? LHSContainsUndef : RHSContainsUndef;
10058
10059 if (Undef)
10060 unionAssumedWithUndef();
10061 else {
10062 for (const auto &It : *OpAA)
10063 unionAssumed(It);
10064 }
10065
10066 } else if (LHSContainsUndef && RHSContainsUndef) {
10067 // select i1 *, undef , undef => undef
10068 unionAssumedWithUndef();
10069 } else {
10070 for (const auto &It : LHSAAPVS)
10071 unionAssumed(It);
10072 for (const auto &It : RHSAAPVS)
10073 unionAssumed(It);
10074 }
10075 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10076 : ChangeStatus::CHANGED;
10077 }
10078
10079 ChangeStatus updateWithCastInst(Attributor &A, CastInst *CI) {
10080 auto AssumedBefore = getAssumed();
10081 if (!CI->isIntegerCast())
10082 return indicatePessimisticFixpoint();
10083 assert(CI->getNumOperands() == 1 && "Expected cast to be unary!");
10084 uint32_t ResultBitWidth = CI->getDestTy()->getIntegerBitWidth();
10085 Value *Src = CI->getOperand(0);
10086
10087 bool SrcContainsUndef = false;
10088 SetTy SrcPVS;
10089 if (!fillSetWithConstantValues(A, IRPosition::value(*Src), SrcPVS,
10090 SrcContainsUndef, /* ForSelf */ false))
10091 return indicatePessimisticFixpoint();
10092
10093 if (SrcContainsUndef)
10094 unionAssumedWithUndef();
10095 else {
10096 for (const APInt &S : SrcPVS) {
10097 APInt T = calculateCastInst(CI, S, ResultBitWidth);
10098 unionAssumed(T);
10099 }
10100 }
10101 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10102 : ChangeStatus::CHANGED;
10103 }
10104
10105 ChangeStatus updateWithBinaryOperator(Attributor &A, BinaryOperator *BinOp) {
10106 auto AssumedBefore = getAssumed();
10107 Value *LHS = BinOp->getOperand(0);
10108 Value *RHS = BinOp->getOperand(1);
10109
10110 bool LHSContainsUndef = false, RHSContainsUndef = false;
10111 SetTy LHSAAPVS, RHSAAPVS;
10112 if (!fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS,
10113 LHSContainsUndef, /* ForSelf */ false) ||
10114 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS,
10115 RHSContainsUndef, /* ForSelf */ false))
10116 return indicatePessimisticFixpoint();
10117
10118 const APInt Zero = APInt(LHS->getType()->getIntegerBitWidth(), 0);
10119
10120 // TODO: make use of undef flag to limit potential values aggressively.
10121 if (LHSContainsUndef && RHSContainsUndef) {
10122 if (!calculateBinaryOperatorAndTakeUnion(BinOp, Zero, Zero))
10123 return indicatePessimisticFixpoint();
10124 } else if (LHSContainsUndef) {
10125 for (const APInt &R : RHSAAPVS) {
10126 if (!calculateBinaryOperatorAndTakeUnion(BinOp, Zero, R))
10127 return indicatePessimisticFixpoint();
10128 }
10129 } else if (RHSContainsUndef) {
10130 for (const APInt &L : LHSAAPVS) {
10131 if (!calculateBinaryOperatorAndTakeUnion(BinOp, L, Zero))
10132 return indicatePessimisticFixpoint();
10133 }
10134 } else {
10135 for (const APInt &L : LHSAAPVS) {
10136 for (const APInt &R : RHSAAPVS) {
10137 if (!calculateBinaryOperatorAndTakeUnion(BinOp, L, R))
10138 return indicatePessimisticFixpoint();
10139 }
10140 }
10141 }
10142 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10143 : ChangeStatus::CHANGED;
10144 }
10145
10146 ChangeStatus updateWithInstruction(Attributor &A, Instruction *Inst) {
10147 auto AssumedBefore = getAssumed();
10148 SetTy Incoming;
10149 bool ContainsUndef;
10150 if (!fillSetWithConstantValues(A, IRPosition::value(*Inst), Incoming,
10151 ContainsUndef, /* ForSelf */ true))
10152 return indicatePessimisticFixpoint();
10153 if (ContainsUndef) {
10154 unionAssumedWithUndef();
10155 } else {
10156 for (const auto &It : Incoming)
10157 unionAssumed(It);
10158 }
10159 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10160 : ChangeStatus::CHANGED;
10161 }
10162
10163 /// See AbstractAttribute::updateImpl(...).
10164 ChangeStatus updateImpl(Attributor &A) override {
10165 Value &V = getAssociatedValue();
10167
10168 if (auto *ICI = dyn_cast<ICmpInst>(I))
10169 return updateWithICmpInst(A, ICI);
10170
10171 if (auto *SI = dyn_cast<SelectInst>(I))
10172 return updateWithSelectInst(A, SI);
10173
10174 if (auto *CI = dyn_cast<CastInst>(I))
10175 return updateWithCastInst(A, CI);
10176
10177 if (auto *BinOp = dyn_cast<BinaryOperator>(I))
10178 return updateWithBinaryOperator(A, BinOp);
10179
10180 if (isa<PHINode>(I) || isa<LoadInst>(I))
10181 return updateWithInstruction(A, I);
10182
10183 return indicatePessimisticFixpoint();
10184 }
10185
10186 /// See AbstractAttribute::trackStatistics()
10187 void trackStatistics() const override {
10188 STATS_DECLTRACK_FLOATING_ATTR(potential_values)
10189 }
10190};
10191
10192struct AAPotentialConstantValuesFunction : AAPotentialConstantValuesImpl {
10193 AAPotentialConstantValuesFunction(const IRPosition &IRP, Attributor &A)
10194 : AAPotentialConstantValuesImpl(IRP, A) {}
10195
10196 /// See AbstractAttribute::initialize(...).
10197 ChangeStatus updateImpl(Attributor &A) override {
10199 "AAPotentialConstantValues(Function|CallSite)::updateImpl will "
10200 "not be called");
10201 }
10202
10203 /// See AbstractAttribute::trackStatistics()
10204 void trackStatistics() const override {
10205 STATS_DECLTRACK_FN_ATTR(potential_values)
10206 }
10207};
10208
10209struct AAPotentialConstantValuesCallSite : AAPotentialConstantValuesFunction {
10210 AAPotentialConstantValuesCallSite(const IRPosition &IRP, Attributor &A)
10211 : AAPotentialConstantValuesFunction(IRP, A) {}
10212
10213 /// See AbstractAttribute::trackStatistics()
10214 void trackStatistics() const override {
10215 STATS_DECLTRACK_CS_ATTR(potential_values)
10216 }
10217};
10218
10219struct AAPotentialConstantValuesCallSiteReturned
10220 : AACalleeToCallSite<AAPotentialConstantValues,
10221 AAPotentialConstantValuesImpl> {
10222 AAPotentialConstantValuesCallSiteReturned(const IRPosition &IRP,
10223 Attributor &A)
10224 : AACalleeToCallSite<AAPotentialConstantValues,
10225 AAPotentialConstantValuesImpl>(IRP, A) {}
10226
10227 /// See AbstractAttribute::trackStatistics()
10228 void trackStatistics() const override {
10229 STATS_DECLTRACK_CSRET_ATTR(potential_values)
10230 }
10231};
10232
10233struct AAPotentialConstantValuesCallSiteArgument
10234 : AAPotentialConstantValuesFloating {
10235 AAPotentialConstantValuesCallSiteArgument(const IRPosition &IRP,
10236 Attributor &A)
10237 : AAPotentialConstantValuesFloating(IRP, A) {}
10238
10239 /// See AbstractAttribute::initialize(..).
10240 void initialize(Attributor &A) override {
10241 AAPotentialConstantValuesImpl::initialize(A);
10242 if (isAtFixpoint())
10243 return;
10244
10245 Value &V = getAssociatedValue();
10246
10247 if (auto *C = dyn_cast<ConstantInt>(&V)) {
10248 unionAssumed(C->getValue());
10249 indicateOptimisticFixpoint();
10250 return;
10251 }
10252
10253 if (isa<UndefValue>(&V)) {
10254 unionAssumedWithUndef();
10255 indicateOptimisticFixpoint();
10256 return;
10257 }
10258 }
10259
10260 /// See AbstractAttribute::updateImpl(...).
10261 ChangeStatus updateImpl(Attributor &A) override {
10262 Value &V = getAssociatedValue();
10263 auto AssumedBefore = getAssumed();
10264 auto *AA = A.getAAFor<AAPotentialConstantValues>(
10265 *this, IRPosition::value(V), DepClassTy::REQUIRED);
10266 if (!AA)
10267 return indicatePessimisticFixpoint();
10268 const auto &S = AA->getAssumed();
10269 unionAssumed(S);
10270 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10271 : ChangeStatus::CHANGED;
10272 }
10273
10274 /// See AbstractAttribute::trackStatistics()
10275 void trackStatistics() const override {
10276 STATS_DECLTRACK_CSARG_ATTR(potential_values)
10277 }
10278};
10279} // namespace
10280
10281/// ------------------------ NoUndef Attribute ---------------------------------
10283 Attribute::AttrKind ImpliedAttributeKind,
10284 bool IgnoreSubsumingPositions) {
10285 assert(ImpliedAttributeKind == Attribute::NoUndef &&
10286 "Unexpected attribute kind");
10287 if (A.hasAttr(IRP, {Attribute::NoUndef}, IgnoreSubsumingPositions,
10288 Attribute::NoUndef))
10289 return true;
10290
10291 Value &Val = IRP.getAssociatedValue();
10294 LLVMContext &Ctx = Val.getContext();
10295 A.manifestAttrs(IRP, Attribute::get(Ctx, Attribute::NoUndef));
10296 return true;
10297 }
10298
10299 return false;
10300}
10301
10302namespace {
10303struct AANoUndefImpl : AANoUndef {
10304 AANoUndefImpl(const IRPosition &IRP, Attributor &A) : AANoUndef(IRP, A) {}
10305
10306 /// See AbstractAttribute::initialize(...).
10307 void initialize(Attributor &A) override {
10308 Value &V = getAssociatedValue();
10309 if (isa<UndefValue>(V))
10310 indicatePessimisticFixpoint();
10311 assert(!isImpliedByIR(A, getIRPosition(), Attribute::NoUndef));
10312 }
10313
10314 /// See followUsesInMBEC
10315 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
10316 AANoUndef::StateType &State) {
10317 const Value *UseV = U->get();
10318 const DominatorTree *DT = nullptr;
10319 AssumptionCache *AC = nullptr;
10320 InformationCache &InfoCache = A.getInfoCache();
10321 if (Function *F = getAnchorScope()) {
10322 DT = InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F);
10323 AC = InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F);
10324 }
10325 State.setKnown(isGuaranteedNotToBeUndefOrPoison(UseV, AC, I, DT));
10326 bool TrackUse = false;
10327 // Track use for instructions which must produce undef or poison bits when
10328 // at least one operand contains such bits.
10330 TrackUse = true;
10331 return TrackUse;
10332 }
10333
10334 /// See AbstractAttribute::getAsStr().
10335 const std::string getAsStr(Attributor *A) const override {
10336 return getAssumed() ? "noundef" : "may-undef-or-poison";
10337 }
10338
10339 ChangeStatus manifest(Attributor &A) override {
10340 // We don't manifest noundef attribute for dead positions because the
10341 // associated values with dead positions would be replaced with undef
10342 // values.
10343 bool UsedAssumedInformation = false;
10344 if (A.isAssumedDead(getIRPosition(), nullptr, nullptr,
10345 UsedAssumedInformation))
10346 return ChangeStatus::UNCHANGED;
10347 // A position whose simplified value does not have any value is
10348 // considered to be dead. We don't manifest noundef in such positions for
10349 // the same reason above.
10350 if (!A.getAssumedSimplified(getIRPosition(), *this, UsedAssumedInformation,
10352 .has_value())
10353 return ChangeStatus::UNCHANGED;
10354 return AANoUndef::manifest(A);
10355 }
10356};
10357
10358struct AANoUndefFloating : public AANoUndefImpl {
10359 AANoUndefFloating(const IRPosition &IRP, Attributor &A)
10360 : AANoUndefImpl(IRP, A) {}
10361
10362 /// See AbstractAttribute::initialize(...).
10363 void initialize(Attributor &A) override {
10364 AANoUndefImpl::initialize(A);
10365 if (!getState().isAtFixpoint() && getAnchorScope() &&
10366 !getAnchorScope()->isDeclaration())
10367 if (Instruction *CtxI = getCtxI())
10368 followUsesInMBEC(*this, A, getState(), *CtxI);
10369 }
10370
10371 /// See AbstractAttribute::updateImpl(...).
10372 ChangeStatus updateImpl(Attributor &A) override {
10373 auto VisitValueCB = [&](const IRPosition &IRP) -> bool {
10374 bool IsKnownNoUndef;
10376 A, this, IRP, DepClassTy::REQUIRED, IsKnownNoUndef);
10377 };
10378
10379 bool Stripped;
10380 bool UsedAssumedInformation = false;
10381 Value *AssociatedValue = &getAssociatedValue();
10383 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
10384 AA::AnyScope, UsedAssumedInformation))
10385 Stripped = false;
10386 else
10387 Stripped =
10388 Values.size() != 1 || Values.front().getValue() != AssociatedValue;
10389
10390 if (!Stripped) {
10391 // If we haven't stripped anything we might still be able to use a
10392 // different AA, but only if the IRP changes. Effectively when we
10393 // interpret this not as a call site value but as a floating/argument
10394 // value.
10395 const IRPosition AVIRP = IRPosition::value(*AssociatedValue);
10396 if (AVIRP == getIRPosition() || !VisitValueCB(AVIRP))
10397 return indicatePessimisticFixpoint();
10398 return ChangeStatus::UNCHANGED;
10399 }
10400
10401 for (const auto &VAC : Values)
10402 if (!VisitValueCB(IRPosition::value(*VAC.getValue())))
10403 return indicatePessimisticFixpoint();
10404
10405 return ChangeStatus::UNCHANGED;
10406 }
10407
10408 /// See AbstractAttribute::trackStatistics()
10409 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noundef) }
10410};
10411
10412struct AANoUndefReturned final
10413 : AAReturnedFromReturnedValues<AANoUndef, AANoUndefImpl> {
10414 AANoUndefReturned(const IRPosition &IRP, Attributor &A)
10415 : AAReturnedFromReturnedValues<AANoUndef, AANoUndefImpl>(IRP, A) {}
10416
10417 /// See AbstractAttribute::trackStatistics()
10418 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noundef) }
10419};
10420
10421struct AANoUndefArgument final
10422 : AAArgumentFromCallSiteArguments<AANoUndef, AANoUndefImpl> {
10423 AANoUndefArgument(const IRPosition &IRP, Attributor &A)
10424 : AAArgumentFromCallSiteArguments<AANoUndef, AANoUndefImpl>(IRP, A) {}
10425
10426 /// See AbstractAttribute::trackStatistics()
10427 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noundef) }
10428};
10429
10430struct AANoUndefCallSiteArgument final : AANoUndefFloating {
10431 AANoUndefCallSiteArgument(const IRPosition &IRP, Attributor &A)
10432 : AANoUndefFloating(IRP, A) {}
10433
10434 /// See AbstractAttribute::trackStatistics()
10435 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(noundef) }
10436};
10437
10438struct AANoUndefCallSiteReturned final
10439 : AACalleeToCallSite<AANoUndef, AANoUndefImpl> {
10440 AANoUndefCallSiteReturned(const IRPosition &IRP, Attributor &A)
10441 : AACalleeToCallSite<AANoUndef, AANoUndefImpl>(IRP, A) {}
10442
10443 /// See AbstractAttribute::trackStatistics()
10444 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(noundef) }
10445};
10446
10447/// ------------------------ NoFPClass Attribute -------------------------------
10448
10449struct AANoFPClassImpl : AANoFPClass {
10450 AANoFPClassImpl(const IRPosition &IRP, Attributor &A) : AANoFPClass(IRP, A) {}
10451
10452 void initialize(Attributor &A) override {
10453 const IRPosition &IRP = getIRPosition();
10454
10455 Value &V = IRP.getAssociatedValue();
10456 if (isa<UndefValue>(V)) {
10457 indicateOptimisticFixpoint();
10458 return;
10459 }
10460
10462 A.getAttrs(getIRPosition(), {Attribute::NoFPClass}, Attrs, false);
10463 for (const auto &Attr : Attrs) {
10464 addKnownBits(Attr.getNoFPClass());
10465 }
10466
10467 Instruction *CtxI = getCtxI();
10468
10469 if (getPositionKind() != IRPosition::IRP_RETURNED) {
10470 const DataLayout &DL = A.getDataLayout();
10471 InformationCache &InfoCache = A.getInfoCache();
10472
10473 const DominatorTree *DT = nullptr;
10474 AssumptionCache *AC = nullptr;
10475 const TargetLibraryInfo *TLI = nullptr;
10476 Function *F = getAnchorScope();
10477 if (F) {
10478 TLI = InfoCache.getTargetLibraryInfoForFunction(*F);
10479 if (!F->isDeclaration()) {
10480 DT =
10481 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F);
10482 AC = InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F);
10483 }
10484 }
10485
10486 SimplifyQuery Q(DL, TLI, DT, AC, CtxI);
10487
10488 KnownFPClass KnownFPClass = computeKnownFPClass(&V, fcAllFlags, Q);
10489 addKnownBits(~KnownFPClass.KnownFPClasses);
10490 }
10491
10492 if (CtxI)
10493 followUsesInMBEC(*this, A, getState(), *CtxI);
10494 }
10495
10496 /// See followUsesInMBEC
10497 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
10498 AANoFPClass::StateType &State) {
10499 // TODO: Determine what instructions can be looked through.
10500 auto *CB = dyn_cast<CallBase>(I);
10501 if (!CB)
10502 return false;
10503
10504 if (!CB->isArgOperand(U))
10505 return false;
10506
10507 unsigned ArgNo = CB->getArgOperandNo(U);
10508 IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo);
10509 if (auto *NoFPAA = A.getAAFor<AANoFPClass>(*this, IRP, DepClassTy::NONE))
10510 State.addKnownBits(NoFPAA->getState().getKnown());
10511 return false;
10512 }
10513
10514 const std::string getAsStr(Attributor *A) const override {
10515 std::string Result = "nofpclass";
10516 raw_string_ostream OS(Result);
10517 OS << getKnownNoFPClass() << '/' << getAssumedNoFPClass();
10518 return Result;
10519 }
10520
10521 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
10522 SmallVectorImpl<Attribute> &Attrs) const override {
10523 Attrs.emplace_back(Attribute::getWithNoFPClass(Ctx, getAssumedNoFPClass()));
10524 }
10525};
10526
10527struct AANoFPClassFloating : public AANoFPClassImpl {
10528 AANoFPClassFloating(const IRPosition &IRP, Attributor &A)
10529 : AANoFPClassImpl(IRP, A) {}
10530
10531 /// See AbstractAttribute::updateImpl(...).
10532 ChangeStatus updateImpl(Attributor &A) override {
10534 bool UsedAssumedInformation = false;
10535 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
10536 AA::AnyScope, UsedAssumedInformation)) {
10537 Values.push_back({getAssociatedValue(), getCtxI()});
10538 }
10539
10540 StateType T;
10541 auto VisitValueCB = [&](Value &V, const Instruction *CtxI) -> bool {
10542 const auto *AA = A.getAAFor<AANoFPClass>(*this, IRPosition::value(V),
10543 DepClassTy::REQUIRED);
10544 if (!AA || this == AA) {
10545 T.indicatePessimisticFixpoint();
10546 } else {
10547 const AANoFPClass::StateType &S =
10548 static_cast<const AANoFPClass::StateType &>(AA->getState());
10549 T ^= S;
10550 }
10551 return T.isValidState();
10552 };
10553
10554 for (const auto &VAC : Values)
10555 if (!VisitValueCB(*VAC.getValue(), VAC.getCtxI()))
10556 return indicatePessimisticFixpoint();
10557
10558 return clampStateAndIndicateChange(getState(), T);
10559 }
10560
10561 /// See AbstractAttribute::trackStatistics()
10562 void trackStatistics() const override {
10564 }
10565};
10566
10567struct AANoFPClassReturned final
10568 : AAReturnedFromReturnedValues<AANoFPClass, AANoFPClassImpl,
10569 AANoFPClassImpl::StateType, false,
10570 Attribute::None, false> {
10571 AANoFPClassReturned(const IRPosition &IRP, Attributor &A)
10572 : AAReturnedFromReturnedValues<AANoFPClass, AANoFPClassImpl,
10573 AANoFPClassImpl::StateType, false,
10574 Attribute::None, false>(IRP, A) {}
10575
10576 /// See AbstractAttribute::trackStatistics()
10577 void trackStatistics() const override {
10579 }
10580};
10581
10582struct AANoFPClassArgument final
10583 : AAArgumentFromCallSiteArguments<AANoFPClass, AANoFPClassImpl> {
10584 AANoFPClassArgument(const IRPosition &IRP, Attributor &A)
10585 : AAArgumentFromCallSiteArguments<AANoFPClass, AANoFPClassImpl>(IRP, A) {}
10586
10587 /// See AbstractAttribute::trackStatistics()
10588 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nofpclass) }
10589};
10590
10591struct AANoFPClassCallSiteArgument final : AANoFPClassFloating {
10592 AANoFPClassCallSiteArgument(const IRPosition &IRP, Attributor &A)
10593 : AANoFPClassFloating(IRP, A) {}
10594
10595 /// See AbstractAttribute::trackStatistics()
10596 void trackStatistics() const override {
10598 }
10599};
10600
10601struct AANoFPClassCallSiteReturned final
10602 : AACalleeToCallSite<AANoFPClass, AANoFPClassImpl> {
10603 AANoFPClassCallSiteReturned(const IRPosition &IRP, Attributor &A)
10604 : AACalleeToCallSite<AANoFPClass, AANoFPClassImpl>(IRP, A) {}
10605
10606 /// See AbstractAttribute::trackStatistics()
10607 void trackStatistics() const override {
10609 }
10610};
10611
10612struct AACallEdgesImpl : public AACallEdges {
10613 AACallEdgesImpl(const IRPosition &IRP, Attributor &A) : AACallEdges(IRP, A) {}
10614
10615 const SetVector<Function *> &getOptimisticEdges() const override {
10616 return CalledFunctions;
10617 }
10618
10619 bool hasUnknownCallee() const override { return HasUnknownCallee; }
10620
10621 bool hasNonAsmUnknownCallee() const override {
10622 return HasUnknownCalleeNonAsm;
10623 }
10624
10625 const std::string getAsStr(Attributor *A) const override {
10626 return "CallEdges[" + std::to_string(HasUnknownCallee) + "," +
10627 std::to_string(CalledFunctions.size()) + "]";
10628 }
10629
10630 void trackStatistics() const override {}
10631
10632protected:
10633 void addCalledFunction(Function *Fn, ChangeStatus &Change) {
10634 if (CalledFunctions.insert(Fn)) {
10635 Change = ChangeStatus::CHANGED;
10636 LLVM_DEBUG(dbgs() << "[AACallEdges] New call edge: " << Fn->getName()
10637 << "\n");
10638 }
10639 }
10640
10641 void setHasUnknownCallee(bool NonAsm, ChangeStatus &Change) {
10642 if (!HasUnknownCallee)
10643 Change = ChangeStatus::CHANGED;
10644 if (NonAsm && !HasUnknownCalleeNonAsm)
10645 Change = ChangeStatus::CHANGED;
10646 HasUnknownCalleeNonAsm |= NonAsm;
10647 HasUnknownCallee = true;
10648 }
10649
10650private:
10651 /// Optimistic set of functions that might be called by this position.
10652 SetVector<Function *> CalledFunctions;
10653
10654 /// Is there any call with a unknown callee.
10655 bool HasUnknownCallee = false;
10656
10657 /// Is there any call with a unknown callee, excluding any inline asm.
10658 bool HasUnknownCalleeNonAsm = false;
10659};
10660
10661struct AACallEdgesCallSite : public AACallEdgesImpl {
10662 AACallEdgesCallSite(const IRPosition &IRP, Attributor &A)
10663 : AACallEdgesImpl(IRP, A) {}
10664 /// See AbstractAttribute::updateImpl(...).
10665 ChangeStatus updateImpl(Attributor &A) override {
10666 ChangeStatus Change = ChangeStatus::UNCHANGED;
10667
10668 auto VisitValue = [&](Value &V, const Instruction *CtxI) -> bool {
10669 if (Function *Fn = dyn_cast<Function>(&V)) {
10670 addCalledFunction(Fn, Change);
10671 } else {
10672 LLVM_DEBUG(dbgs() << "[AACallEdges] Unrecognized value: " << V << "\n");
10673 setHasUnknownCallee(true, Change);
10674 }
10675
10676 // Explore all values.
10677 return true;
10678 };
10679
10681 // Process any value that we might call.
10682 auto ProcessCalledOperand = [&](Value *V, Instruction *CtxI) {
10683 if (isa<Constant>(V)) {
10684 VisitValue(*V, CtxI);
10685 return;
10686 }
10687
10688 bool UsedAssumedInformation = false;
10689 Values.clear();
10690 if (!A.getAssumedSimplifiedValues(IRPosition::value(*V), *this, Values,
10691 AA::AnyScope, UsedAssumedInformation)) {
10692 Values.push_back({*V, CtxI});
10693 }
10694 for (auto &VAC : Values)
10695 VisitValue(*VAC.getValue(), VAC.getCtxI());
10696 };
10697
10698 CallBase *CB = cast<CallBase>(getCtxI());
10699
10700 if (auto *IA = dyn_cast<InlineAsm>(CB->getCalledOperand())) {
10701 if (IA->hasSideEffects() &&
10702 !hasAssumption(*CB->getCaller(), "ompx_no_call_asm") &&
10703 !hasAssumption(*CB, "ompx_no_call_asm")) {
10704 setHasUnknownCallee(false, Change);
10705 }
10706 return Change;
10707 }
10708
10709 if (CB->isIndirectCall())
10710 if (auto *IndirectCallAA = A.getAAFor<AAIndirectCallInfo>(
10711 *this, getIRPosition(), DepClassTy::OPTIONAL))
10712 if (IndirectCallAA->foreachCallee(
10713 [&](Function *Fn) { return VisitValue(*Fn, CB); }))
10714 return Change;
10715
10716 // The most simple case.
10717 ProcessCalledOperand(CB->getCalledOperand(), CB);
10718
10719 // Process callback functions.
10720 SmallVector<const Use *, 4u> CallbackUses;
10721 AbstractCallSite::getCallbackUses(*CB, CallbackUses);
10722 for (const Use *U : CallbackUses)
10723 ProcessCalledOperand(U->get(), CB);
10724
10725 return Change;
10726 }
10727};
10728
10729struct AACallEdgesFunction : public AACallEdgesImpl {
10730 AACallEdgesFunction(const IRPosition &IRP, Attributor &A)
10731 : AACallEdgesImpl(IRP, A) {}
10732
10733 /// See AbstractAttribute::updateImpl(...).
10734 ChangeStatus updateImpl(Attributor &A) override {
10735 ChangeStatus Change = ChangeStatus::UNCHANGED;
10736
10737 auto ProcessCallInst = [&](Instruction &Inst) {
10738 CallBase &CB = cast<CallBase>(Inst);
10739
10740 auto *CBEdges = A.getAAFor<AACallEdges>(
10741 *this, IRPosition::callsite_function(CB), DepClassTy::REQUIRED);
10742 if (!CBEdges)
10743 return false;
10744 if (CBEdges->hasNonAsmUnknownCallee())
10745 setHasUnknownCallee(true, Change);
10746 if (CBEdges->hasUnknownCallee())
10747 setHasUnknownCallee(false, Change);
10748
10749 for (Function *F : CBEdges->getOptimisticEdges())
10750 addCalledFunction(F, Change);
10751
10752 return true;
10753 };
10754
10755 // Visit all callable instructions.
10756 bool UsedAssumedInformation = false;
10757 if (!A.checkForAllCallLikeInstructions(ProcessCallInst, *this,
10758 UsedAssumedInformation,
10759 /* CheckBBLivenessOnly */ true)) {
10760 // If we haven't looked at all call like instructions, assume that there
10761 // are unknown callees.
10762 setHasUnknownCallee(true, Change);
10763 }
10764
10765 return Change;
10766 }
10767};
10768
10769/// -------------------AAInterFnReachability Attribute--------------------------
10770
10771struct AAInterFnReachabilityFunction
10772 : public CachedReachabilityAA<AAInterFnReachability, Function> {
10773 using Base = CachedReachabilityAA<AAInterFnReachability, Function>;
10774 AAInterFnReachabilityFunction(const IRPosition &IRP, Attributor &A)
10775 : Base(IRP, A) {}
10776
10777 bool instructionCanReach(
10778 Attributor &A, const Instruction &From, const Function &To,
10779 const AA::InstExclusionSetTy *ExclusionSet) const override {
10780 assert(From.getFunction() == getAnchorScope() && "Queried the wrong AA!");
10781 auto *NonConstThis = const_cast<AAInterFnReachabilityFunction *>(this);
10782
10783 RQITy StackRQI(A, From, To, ExclusionSet, false);
10784 RQITy::Reachable Result;
10785 if (!NonConstThis->checkQueryCache(A, StackRQI, Result))
10786 return NonConstThis->isReachableImpl(A, StackRQI,
10787 /*IsTemporaryRQI=*/true);
10788 return Result == RQITy::Reachable::Yes;
10789 }
10790
10791 bool isReachableImpl(Attributor &A, RQITy &RQI,
10792 bool IsTemporaryRQI) override {
10793 const Instruction *EntryI =
10794 &RQI.From->getFunction()->getEntryBlock().front();
10795 if (EntryI != RQI.From &&
10796 !instructionCanReach(A, *EntryI, *RQI.To, nullptr))
10797 return rememberResult(A, RQITy::Reachable::No, RQI, false,
10798 IsTemporaryRQI);
10799
10800 auto CheckReachableCallBase = [&](CallBase *CB) {
10801 auto *CBEdges = A.getAAFor<AACallEdges>(
10802 *this, IRPosition::callsite_function(*CB), DepClassTy::OPTIONAL);
10803 if (!CBEdges || !CBEdges->getState().isValidState())
10804 return false;
10805 // TODO Check To backwards in this case.
10806 if (CBEdges->hasUnknownCallee())
10807 return false;
10808
10809 for (Function *Fn : CBEdges->getOptimisticEdges()) {
10810 if (Fn == RQI.To)
10811 return false;
10812
10813 if (Fn->isDeclaration()) {
10814 if (Fn->hasFnAttribute(Attribute::NoCallback))
10815 continue;
10816 // TODO Check To backwards in this case.
10817 return false;
10818 }
10819
10820 if (Fn == getAnchorScope()) {
10821 if (EntryI == RQI.From)
10822 continue;
10823 return false;
10824 }
10825
10826 const AAInterFnReachability *InterFnReachability =
10827 A.getAAFor<AAInterFnReachability>(*this, IRPosition::function(*Fn),
10828 DepClassTy::OPTIONAL);
10829
10830 const Instruction &FnFirstInst = Fn->getEntryBlock().front();
10831 if (!InterFnReachability ||
10832 InterFnReachability->instructionCanReach(A, FnFirstInst, *RQI.To,
10833 RQI.ExclusionSet))
10834 return false;
10835 }
10836 return true;
10837 };
10838
10839 const auto *IntraFnReachability = A.getAAFor<AAIntraFnReachability>(
10840 *this, IRPosition::function(*RQI.From->getFunction()),
10841 DepClassTy::OPTIONAL);
10842
10843 // Determine call like instructions that we can reach from the inst.
10844 auto CheckCallBase = [&](Instruction &CBInst) {
10845 // There are usually less nodes in the call graph, check inter function
10846 // reachability first.
10847 if (CheckReachableCallBase(cast<CallBase>(&CBInst)))
10848 return true;
10849 return IntraFnReachability && !IntraFnReachability->isAssumedReachable(
10850 A, *RQI.From, CBInst, RQI.ExclusionSet);
10851 };
10852
10853 bool UsedExclusionSet = /* conservative */ true;
10854 bool UsedAssumedInformation = false;
10855 if (!A.checkForAllCallLikeInstructions(CheckCallBase, *this,
10856 UsedAssumedInformation,
10857 /* CheckBBLivenessOnly */ true))
10858 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
10859 IsTemporaryRQI);
10860
10861 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
10862 IsTemporaryRQI);
10863 }
10864
10865 void trackStatistics() const override {}
10866};
10867} // namespace
10868
10869template <typename AAType>
10870static std::optional<Constant *>
10872 const IRPosition &IRP, Type &Ty) {
10873 if (!Ty.isIntegerTy())
10874 return nullptr;
10875
10876 // This will also pass the call base context.
10877 const auto *AA = A.getAAFor<AAType>(QueryingAA, IRP, DepClassTy::NONE);
10878 if (!AA)
10879 return nullptr;
10880
10881 std::optional<Constant *> COpt = AA->getAssumedConstant(A);
10882
10883 if (!COpt.has_value()) {
10884 A.recordDependence(*AA, QueryingAA, DepClassTy::OPTIONAL);
10885 return std::nullopt;
10886 }
10887 if (auto *C = *COpt) {
10888 A.recordDependence(*AA, QueryingAA, DepClassTy::OPTIONAL);
10889 return C;
10890 }
10891 return nullptr;
10892}
10893
10895 Attributor &A, const AbstractAttribute &AA, const IRPosition &IRP,
10897 Type &Ty = *IRP.getAssociatedType();
10898 std::optional<Value *> V;
10899 for (auto &It : Values) {
10900 V = AA::combineOptionalValuesInAAValueLatice(V, It.getValue(), &Ty);
10901 if (V.has_value() && !*V)
10902 break;
10903 }
10904 if (!V.has_value())
10905 return UndefValue::get(&Ty);
10906 return *V;
10907}
10908
10909namespace {
10910struct AAPotentialValuesImpl : AAPotentialValues {
10911 using StateType = PotentialLLVMValuesState;
10912
10913 AAPotentialValuesImpl(const IRPosition &IRP, Attributor &A)
10914 : AAPotentialValues(IRP, A) {}
10915
10916 /// See AbstractAttribute::initialize(..).
10917 void initialize(Attributor &A) override {
10918 if (A.hasSimplificationCallback(getIRPosition())) {
10919 indicatePessimisticFixpoint();
10920 return;
10921 }
10922 Value *Stripped = getAssociatedValue().stripPointerCasts();
10923 if (isa<Constant>(Stripped) && !isa<ConstantExpr>(Stripped)) {
10924 addValue(A, getState(), *Stripped, getCtxI(), AA::AnyScope,
10925 getAnchorScope());
10926 indicateOptimisticFixpoint();
10927 return;
10928 }
10929 AAPotentialValues::initialize(A);
10930 }
10931
10932 /// See AbstractAttribute::getAsStr().
10933 const std::string getAsStr(Attributor *A) const override {
10934 std::string Str;
10935 llvm::raw_string_ostream OS(Str);
10936 OS << getState();
10937 return Str;
10938 }
10939
10940 template <typename AAType>
10941 static std::optional<Value *> askOtherAA(Attributor &A,
10942 const AbstractAttribute &AA,
10943 const IRPosition &IRP, Type &Ty) {
10945 return &IRP.getAssociatedValue();
10946 std::optional<Constant *> C = askForAssumedConstant<AAType>(A, AA, IRP, Ty);
10947 if (!C)
10948 return std::nullopt;
10949 if (*C)
10950 if (auto *CC = AA::getWithType(**C, Ty))
10951 return CC;
10952 return nullptr;
10953 }
10954
10955 virtual void addValue(Attributor &A, StateType &State, Value &V,
10956 const Instruction *CtxI, AA::ValueScope S,
10957 Function *AnchorScope) const {
10958
10959 IRPosition ValIRP = IRPosition::value(V);
10960 if (auto *CB = dyn_cast_or_null<CallBase>(CtxI)) {
10961 for (const auto &U : CB->args()) {
10962 if (U.get() != &V)
10963 continue;
10964 ValIRP = IRPosition::callsite_argument(*CB, CB->getArgOperandNo(&U));
10965 break;
10966 }
10967 }
10968
10969 Value *VPtr = &V;
10970 if (ValIRP.getAssociatedType()->isIntegerTy()) {
10971 Type &Ty = *getAssociatedType();
10972 std::optional<Value *> SimpleV =
10973 askOtherAA<AAValueConstantRange>(A, *this, ValIRP, Ty);
10974 if (SimpleV.has_value() && !*SimpleV) {
10975 auto *PotentialConstantsAA = A.getAAFor<AAPotentialConstantValues>(
10976 *this, ValIRP, DepClassTy::OPTIONAL);
10977 if (PotentialConstantsAA && PotentialConstantsAA->isValidState()) {
10978 for (const auto &It : PotentialConstantsAA->getAssumedSet())
10979 State.unionAssumed({{*ConstantInt::get(&Ty, It), nullptr}, S});
10980 if (PotentialConstantsAA->undefIsContained())
10981 State.unionAssumed({{*UndefValue::get(&Ty), nullptr}, S});
10982 return;
10983 }
10984 }
10985 if (!SimpleV.has_value())
10986 return;
10987
10988 if (*SimpleV)
10989 VPtr = *SimpleV;
10990 }
10991
10992 if (isa<ConstantInt>(VPtr))
10993 CtxI = nullptr;
10994 if (!AA::isValidInScope(*VPtr, AnchorScope))
10996
10997 State.unionAssumed({{*VPtr, CtxI}, S});
10998 }
10999
11000 /// Helper struct to tie a value+context pair together with the scope for
11001 /// which this is the simplified version.
11002 struct ItemInfo {
11003 AA::ValueAndContext I;
11005
11006 bool operator==(const ItemInfo &II) const {
11007 return II.I == I && II.S == S;
11008 };
11009 bool operator<(const ItemInfo &II) const {
11010 return std::tie(I, S) < std::tie(II.I, II.S);
11011 };
11012 };
11013
11014 bool recurseForValue(Attributor &A, const IRPosition &IRP, AA::ValueScope S) {
11015 SmallMapVector<AA::ValueAndContext, int, 8> ValueScopeMap;
11016 for (auto CS : {AA::Intraprocedural, AA::Interprocedural}) {
11017 if (!(CS & S))
11018 continue;
11019
11020 bool UsedAssumedInformation = false;
11022 if (!A.getAssumedSimplifiedValues(IRP, this, Values, CS,
11023 UsedAssumedInformation))
11024 return false;
11025
11026 for (auto &It : Values)
11027 ValueScopeMap[It] += CS;
11028 }
11029 for (auto &It : ValueScopeMap)
11030 addValue(A, getState(), *It.first.getValue(), It.first.getCtxI(),
11031 AA::ValueScope(It.second), getAnchorScope());
11032
11033 return true;
11034 }
11035
11036 void giveUpOnIntraprocedural(Attributor &A) {
11037 auto NewS = StateType::getBestState(getState());
11038 for (const auto &It : getAssumedSet()) {
11039 if (It.second == AA::Intraprocedural)
11040 continue;
11041 addValue(A, NewS, *It.first.getValue(), It.first.getCtxI(),
11042 AA::Interprocedural, getAnchorScope());
11043 }
11044 assert(!undefIsContained() && "Undef should be an explicit value!");
11045 addValue(A, NewS, getAssociatedValue(), getCtxI(), AA::Intraprocedural,
11046 getAnchorScope());
11047 getState() = NewS;
11048 }
11049
11050 /// See AbstractState::indicatePessimisticFixpoint(...).
11051 ChangeStatus indicatePessimisticFixpoint() override {
11052 getState() = StateType::getBestState(getState());
11053 getState().unionAssumed({{getAssociatedValue(), getCtxI()}, AA::AnyScope});
11054 AAPotentialValues::indicateOptimisticFixpoint();
11055 return ChangeStatus::CHANGED;
11056 }
11057
11058 /// See AbstractAttribute::updateImpl(...).
11059 ChangeStatus updateImpl(Attributor &A) override {
11060 return indicatePessimisticFixpoint();
11061 }
11062
11063 /// See AbstractAttribute::manifest(...).
11064 ChangeStatus manifest(Attributor &A) override {
11067 Values.clear();
11068 if (!getAssumedSimplifiedValues(A, Values, S))
11069 continue;
11070 Value &OldV = getAssociatedValue();
11071 if (isa<UndefValue>(OldV))
11072 continue;
11073 Value *NewV = getSingleValue(A, *this, getIRPosition(), Values);
11074 if (!NewV || NewV == &OldV)
11075 continue;
11076 if (getCtxI() &&
11077 !AA::isValidAtPosition({*NewV, *getCtxI()}, A.getInfoCache()))
11078 continue;
11079 if (A.changeAfterManifest(getIRPosition(), *NewV))
11080 return ChangeStatus::CHANGED;
11081 }
11082 return ChangeStatus::UNCHANGED;
11083 }
11084
11085 bool getAssumedSimplifiedValues(
11086 Attributor &A, SmallVectorImpl<AA::ValueAndContext> &Values,
11087 AA::ValueScope S, bool RecurseForSelectAndPHI = false) const override {
11088 if (!isValidState())
11089 return false;
11090 bool UsedAssumedInformation = false;
11091 for (const auto &It : getAssumedSet())
11092 if (It.second & S) {
11093 if (RecurseForSelectAndPHI && (isa<PHINode>(It.first.getValue()) ||
11094 isa<SelectInst>(It.first.getValue()))) {
11095 if (A.getAssumedSimplifiedValues(
11096 IRPosition::inst(*cast<Instruction>(It.first.getValue())),
11097 this, Values, S, UsedAssumedInformation))
11098 continue;
11099 }
11100 Values.push_back(It.first);
11101 }
11102 assert(!undefIsContained() && "Undef should be an explicit value!");
11103 return true;
11104 }
11105};
11106
11107struct AAPotentialValuesFloating : AAPotentialValuesImpl {
11108 AAPotentialValuesFloating(const IRPosition &IRP, Attributor &A)
11109 : AAPotentialValuesImpl(IRP, A) {}
11110
11111 /// See AbstractAttribute::updateImpl(...).
11112 ChangeStatus updateImpl(Attributor &A) override {
11113 auto AssumedBefore = getAssumed();
11114
11115 genericValueTraversal(A, &getAssociatedValue());
11116
11117 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
11118 : ChangeStatus::CHANGED;
11119 }
11120
11121 /// Helper struct to remember which AAIsDead instances we actually used.
11122 struct LivenessInfo {
11123 const AAIsDead *LivenessAA = nullptr;
11124 bool AnyDead = false;
11125 };
11126
11127 /// Check if \p Cmp is a comparison we can simplify.
11128 ///
11129 /// We handle multiple cases, one in which at least one operand is an
11130 /// (assumed) nullptr. If so, try to simplify it using AANonNull on the other
11131 /// operand. Return true if successful, in that case Worklist will be updated.
11132 bool handleCmp(Attributor &A, Value &Cmp, Value *LHS, Value *RHS,
11133 CmpInst::Predicate Pred, ItemInfo II,
11134 SmallVectorImpl<ItemInfo> &Worklist) {
11135
11136 // Simplify the operands first.
11137 bool UsedAssumedInformation = false;
11138 SmallVector<AA::ValueAndContext> LHSValues, RHSValues;
11139 auto GetSimplifiedValues = [&](Value &V,
11141 if (!A.getAssumedSimplifiedValues(
11142 IRPosition::value(V, getCallBaseContext()), this, Values,
11143 AA::Intraprocedural, UsedAssumedInformation)) {
11144 Values.clear();
11145 Values.push_back(AA::ValueAndContext{V, II.I.getCtxI()});
11146 }
11147 return Values.empty();
11148 };
11149 if (GetSimplifiedValues(*LHS, LHSValues))
11150 return true;
11151 if (GetSimplifiedValues(*RHS, RHSValues))
11152 return true;
11153
11154 LLVMContext &Ctx = LHS->getContext();
11155
11156 InformationCache &InfoCache = A.getInfoCache();
11157 Instruction *CmpI = dyn_cast<Instruction>(&Cmp);
11158 Function *F = CmpI ? CmpI->getFunction() : nullptr;
11159 const auto *DT =
11160 F ? InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F)
11161 : nullptr;
11162 const auto *TLI =
11163 F ? A.getInfoCache().getTargetLibraryInfoForFunction(*F) : nullptr;
11164 auto *AC =
11165 F ? InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F)
11166 : nullptr;
11167
11168 const DataLayout &DL = A.getDataLayout();
11169 SimplifyQuery Q(DL, TLI, DT, AC, CmpI);
11170
11171 auto CheckPair = [&](Value &LHSV, Value &RHSV) {
11172 if (isa<UndefValue>(LHSV) || isa<UndefValue>(RHSV)) {
11173 addValue(A, getState(), *UndefValue::get(Cmp.getType()),
11174 /* CtxI */ nullptr, II.S, getAnchorScope());
11175 return true;
11176 }
11177
11178 // Handle the trivial case first in which we don't even need to think
11179 // about null or non-null.
11180 if (&LHSV == &RHSV &&
11182 Constant *NewV = ConstantInt::get(Type::getInt1Ty(Ctx),
11184 addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S,
11185 getAnchorScope());
11186 return true;
11187 }
11188
11189 auto *TypedLHS = AA::getWithType(LHSV, *LHS->getType());
11190 auto *TypedRHS = AA::getWithType(RHSV, *RHS->getType());
11191 if (TypedLHS && TypedRHS) {
11192 Value *NewV = simplifyCmpInst(Pred, TypedLHS, TypedRHS, Q);
11193 if (NewV && NewV != &Cmp) {
11194 addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S,
11195 getAnchorScope());
11196 return true;
11197 }
11198 }
11199
11200 // From now on we only handle equalities (==, !=).
11201 if (!CmpInst::isEquality(Pred))
11202 return false;
11203
11204 bool LHSIsNull = isa<ConstantPointerNull>(LHSV);
11205 bool RHSIsNull = isa<ConstantPointerNull>(RHSV);
11206 if (!LHSIsNull && !RHSIsNull)
11207 return false;
11208
11209 // Left is the nullptr ==/!= non-nullptr case. We'll use AANonNull on the
11210 // non-nullptr operand and if we assume it's non-null we can conclude the
11211 // result of the comparison.
11212 assert((LHSIsNull || RHSIsNull) &&
11213 "Expected nullptr versus non-nullptr comparison at this point");
11214
11215 // The index is the operand that we assume is not null.
11216 unsigned PtrIdx = LHSIsNull;
11217 bool IsKnownNonNull;
11218 bool IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>(
11219 A, this, IRPosition::value(*(PtrIdx ? &RHSV : &LHSV)),
11220 DepClassTy::REQUIRED, IsKnownNonNull);
11221 if (!IsAssumedNonNull)
11222 return false;
11223
11224 // The new value depends on the predicate, true for != and false for ==.
11225 Constant *NewV =
11226 ConstantInt::get(Type::getInt1Ty(Ctx), Pred == CmpInst::ICMP_NE);
11227 addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S,
11228 getAnchorScope());
11229 return true;
11230 };
11231
11232 for (auto &LHSValue : LHSValues)
11233 for (auto &RHSValue : RHSValues)
11234 if (!CheckPair(*LHSValue.getValue(), *RHSValue.getValue()))
11235 return false;
11236 return true;
11237 }
11238
11239 bool handleSelectInst(Attributor &A, SelectInst &SI, ItemInfo II,
11240 SmallVectorImpl<ItemInfo> &Worklist) {
11241 const Instruction *CtxI = II.I.getCtxI();
11242 bool UsedAssumedInformation = false;
11243
11244 std::optional<Constant *> C =
11245 A.getAssumedConstant(*SI.getCondition(), *this, UsedAssumedInformation);
11246 bool NoValueYet = !C.has_value();
11247 if (NoValueYet || isa_and_nonnull<UndefValue>(*C))
11248 return true;
11249 if (auto *CI = dyn_cast_or_null<ConstantInt>(*C)) {
11250 if (CI->isZero())
11251 Worklist.push_back({{*SI.getFalseValue(), CtxI}, II.S});
11252 else
11253 Worklist.push_back({{*SI.getTrueValue(), CtxI}, II.S});
11254 } else if (&SI == &getAssociatedValue()) {
11255 // We could not simplify the condition, assume both values.
11256 Worklist.push_back({{*SI.getTrueValue(), CtxI}, II.S});
11257 Worklist.push_back({{*SI.getFalseValue(), CtxI}, II.S});
11258 } else {
11259 std::optional<Value *> SimpleV = A.getAssumedSimplified(
11260 IRPosition::inst(SI), *this, UsedAssumedInformation, II.S);
11261 if (!SimpleV.has_value())
11262 return true;
11263 if (*SimpleV) {
11264 addValue(A, getState(), **SimpleV, CtxI, II.S, getAnchorScope());
11265 return true;
11266 }
11267 return false;
11268 }
11269 return true;
11270 }
11271
11272 bool handleLoadInst(Attributor &A, LoadInst &LI, ItemInfo II,
11273 SmallVectorImpl<ItemInfo> &Worklist) {
11274 SmallSetVector<Value *, 4> PotentialCopies;
11275 SmallSetVector<Instruction *, 4> PotentialValueOrigins;
11276 bool UsedAssumedInformation = false;
11277 if (!AA::getPotentiallyLoadedValues(A, LI, PotentialCopies,
11278 PotentialValueOrigins, *this,
11279 UsedAssumedInformation,
11280 /* OnlyExact */ true)) {
11281 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Failed to get potentially "
11282 "loaded values for load instruction "
11283 << LI << "\n");
11284 return false;
11285 }
11286
11287 // Do not simplify loads that are only used in llvm.assume if we cannot also
11288 // remove all stores that may feed into the load. The reason is that the
11289 // assume is probably worth something as long as the stores are around.
11290 InformationCache &InfoCache = A.getInfoCache();
11291 if (InfoCache.isOnlyUsedByAssume(LI)) {
11292 if (!llvm::all_of(PotentialValueOrigins, [&](Instruction *I) {
11293 if (!I || isa<AssumeInst>(I))
11294 return true;
11295 if (auto *SI = dyn_cast<StoreInst>(I))
11296 return A.isAssumedDead(SI->getOperandUse(0), this,
11297 /* LivenessAA */ nullptr,
11298 UsedAssumedInformation,
11299 /* CheckBBLivenessOnly */ false);
11300 return A.isAssumedDead(*I, this, /* LivenessAA */ nullptr,
11301 UsedAssumedInformation,
11302 /* CheckBBLivenessOnly */ false);
11303 })) {
11304 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Load is onl used by assumes "
11305 "and we cannot delete all the stores: "
11306 << LI << "\n");
11307 return false;
11308 }
11309 }
11310
11311 // Values have to be dynamically unique or we loose the fact that a
11312 // single llvm::Value might represent two runtime values (e.g.,
11313 // stack locations in different recursive calls).
11314 const Instruction *CtxI = II.I.getCtxI();
11315 bool ScopeIsLocal = (II.S & AA::Intraprocedural);
11316 bool AllLocal = ScopeIsLocal;
11317 bool DynamicallyUnique = llvm::all_of(PotentialCopies, [&](Value *PC) {
11318 AllLocal &= AA::isValidInScope(*PC, getAnchorScope());
11319 return AA::isDynamicallyUnique(A, *this, *PC);
11320 });
11321 if (!DynamicallyUnique) {
11322 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Not all potentially loaded "
11323 "values are dynamically unique: "
11324 << LI << "\n");
11325 return false;
11326 }
11327
11328 for (auto *PotentialCopy : PotentialCopies) {
11329 if (AllLocal) {
11330 Worklist.push_back({{*PotentialCopy, CtxI}, II.S});
11331 } else {
11332 Worklist.push_back({{*PotentialCopy, CtxI}, AA::Interprocedural});
11333 }
11334 }
11335 if (!AllLocal && ScopeIsLocal)
11336 addValue(A, getState(), LI, CtxI, AA::Intraprocedural, getAnchorScope());
11337 return true;
11338 }
11339
11340 bool handlePHINode(
11341 Attributor &A, PHINode &PHI, ItemInfo II,
11342 SmallVectorImpl<ItemInfo> &Worklist,
11343 SmallMapVector<const Function *, LivenessInfo, 4> &LivenessAAs) {
11344 auto GetLivenessInfo = [&](const Function &F) -> LivenessInfo & {
11345 LivenessInfo &LI = LivenessAAs[&F];
11346 if (!LI.LivenessAA)
11347 LI.LivenessAA = A.getAAFor<AAIsDead>(*this, IRPosition::function(F),
11348 DepClassTy::NONE);
11349 return LI;
11350 };
11351
11352 if (&PHI == &getAssociatedValue()) {
11353 LivenessInfo &LI = GetLivenessInfo(*PHI.getFunction());
11354 const auto *CI =
11355 A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>(
11356 *PHI.getFunction());
11357
11358 Cycle *C = nullptr;
11359 bool CyclePHI = mayBeInCycle(CI, &PHI, /* HeaderOnly */ true, &C);
11360 for (unsigned u = 0, e = PHI.getNumIncomingValues(); u < e; u++) {
11361 BasicBlock *IncomingBB = PHI.getIncomingBlock(u);
11362 if (LI.LivenessAA &&
11363 LI.LivenessAA->isEdgeDead(IncomingBB, PHI.getParent())) {
11364 LI.AnyDead = true;
11365 continue;
11366 }
11367 Value *V = PHI.getIncomingValue(u);
11368 if (V == &PHI)
11369 continue;
11370
11371 // If the incoming value is not the PHI but an instruction in the same
11372 // cycle we might have multiple versions of it flying around.
11373 if (CyclePHI && isa<Instruction>(V) &&
11374 (!C || C->contains(cast<Instruction>(V)->getParent())))
11375 return false;
11376
11377 Worklist.push_back({{*V, IncomingBB->getTerminator()}, II.S});
11378 }
11379 return true;
11380 }
11381
11382 bool UsedAssumedInformation = false;
11383 std::optional<Value *> SimpleV = A.getAssumedSimplified(
11384 IRPosition::inst(PHI), *this, UsedAssumedInformation, II.S);
11385 if (!SimpleV.has_value())
11386 return true;
11387 if (!(*SimpleV))
11388 return false;
11389 addValue(A, getState(), **SimpleV, &PHI, II.S, getAnchorScope());
11390 return true;
11391 }
11392
11393 /// Use the generic, non-optimistic InstSimplfy functionality if we managed to
11394 /// simplify any operand of the instruction \p I. Return true if successful,
11395 /// in that case Worklist will be updated.
11396 bool handleGenericInst(Attributor &A, Instruction &I, ItemInfo II,
11397 SmallVectorImpl<ItemInfo> &Worklist) {
11398 bool SomeSimplified = false;
11399 bool UsedAssumedInformation = false;
11400
11401 SmallVector<Value *, 8> NewOps(I.getNumOperands());
11402 int Idx = 0;
11403 for (Value *Op : I.operands()) {
11404 const auto &SimplifiedOp = A.getAssumedSimplified(
11405 IRPosition::value(*Op, getCallBaseContext()), *this,
11406 UsedAssumedInformation, AA::Intraprocedural);
11407 // If we are not sure about any operand we are not sure about the entire
11408 // instruction, we'll wait.
11409 if (!SimplifiedOp.has_value())
11410 return true;
11411
11412 if (*SimplifiedOp)
11413 NewOps[Idx] = *SimplifiedOp;
11414 else
11415 NewOps[Idx] = Op;
11416
11417 SomeSimplified |= (NewOps[Idx] != Op);
11418 ++Idx;
11419 }
11420
11421 // We won't bother with the InstSimplify interface if we didn't simplify any
11422 // operand ourselves.
11423 if (!SomeSimplified)
11424 return false;
11425
11426 InformationCache &InfoCache = A.getInfoCache();
11427 Function *F = I.getFunction();
11428 const auto *DT =
11429 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F);
11430 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
11431 auto *AC = InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F);
11432
11433 const DataLayout &DL = I.getDataLayout();
11434 SimplifyQuery Q(DL, TLI, DT, AC, &I);
11435 Value *NewV = simplifyInstructionWithOperands(&I, NewOps, Q);
11436 if (!NewV || NewV == &I)
11437 return false;
11438
11439 LLVM_DEBUG(dbgs() << "Generic inst " << I << " assumed simplified to "
11440 << *NewV << "\n");
11441 Worklist.push_back({{*NewV, II.I.getCtxI()}, II.S});
11442 return true;
11443 }
11444
11446 Attributor &A, Instruction &I, ItemInfo II,
11447 SmallVectorImpl<ItemInfo> &Worklist,
11448 SmallMapVector<const Function *, LivenessInfo, 4> &LivenessAAs) {
11449 if (auto *CI = dyn_cast<CmpInst>(&I))
11450 return handleCmp(A, *CI, CI->getOperand(0), CI->getOperand(1),
11451 CI->getPredicate(), II, Worklist);
11452
11453 switch (I.getOpcode()) {
11454 case Instruction::Select:
11455 return handleSelectInst(A, cast<SelectInst>(I), II, Worklist);
11456 case Instruction::PHI:
11457 return handlePHINode(A, cast<PHINode>(I), II, Worklist, LivenessAAs);
11458 case Instruction::Load:
11459 return handleLoadInst(A, cast<LoadInst>(I), II, Worklist);
11460 default:
11461 return handleGenericInst(A, I, II, Worklist);
11462 };
11463 return false;
11464 }
11465
11466 void genericValueTraversal(Attributor &A, Value *InitialV) {
11467 SmallMapVector<const Function *, LivenessInfo, 4> LivenessAAs;
11468
11469 SmallSet<ItemInfo, 16> Visited;
11471 Worklist.push_back({{*InitialV, getCtxI()}, AA::AnyScope});
11472
11473 int Iteration = 0;
11474 do {
11475 ItemInfo II = Worklist.pop_back_val();
11476 Value *V = II.I.getValue();
11477 assert(V);
11478 const Instruction *CtxI = II.I.getCtxI();
11479 AA::ValueScope S = II.S;
11480
11481 // Check if we should process the current value. To prevent endless
11482 // recursion keep a record of the values we followed!
11483 if (!Visited.insert(II).second)
11484 continue;
11485
11486 // Make sure we limit the compile time for complex expressions.
11487 if (Iteration++ >= MaxPotentialValuesIterations) {
11488 LLVM_DEBUG(dbgs() << "Generic value traversal reached iteration limit: "
11489 << Iteration << "!\n");
11490 addValue(A, getState(), *V, CtxI, S, getAnchorScope());
11491 continue;
11492 }
11493
11494 // Explicitly look through calls with a "returned" attribute if we do
11495 // not have a pointer as stripPointerCasts only works on them.
11496 Value *NewV = nullptr;
11497 if (V->getType()->isPointerTy()) {
11498 NewV = AA::getWithType(*V->stripPointerCasts(), *V->getType());
11499 } else {
11500 if (auto *CB = dyn_cast<CallBase>(V))
11501 if (auto *Callee =
11503 for (Argument &Arg : Callee->args())
11504 if (Arg.hasReturnedAttr()) {
11505 NewV = CB->getArgOperand(Arg.getArgNo());
11506 break;
11507 }
11508 }
11509 }
11510 if (NewV && NewV != V) {
11511 Worklist.push_back({{*NewV, CtxI}, S});
11512 continue;
11513 }
11514
11515 if (auto *I = dyn_cast<Instruction>(V)) {
11516 if (simplifyInstruction(A, *I, II, Worklist, LivenessAAs))
11517 continue;
11518 }
11519
11520 if (V != InitialV || isa<Argument>(V))
11521 if (recurseForValue(A, IRPosition::value(*V), II.S))
11522 continue;
11523
11524 // If we haven't stripped anything we give up.
11525 if (V == InitialV && CtxI == getCtxI()) {
11526 indicatePessimisticFixpoint();
11527 return;
11528 }
11529
11530 addValue(A, getState(), *V, CtxI, S, getAnchorScope());
11531 } while (!Worklist.empty());
11532
11533 // If we actually used liveness information so we have to record a
11534 // dependence.
11535 for (auto &It : LivenessAAs)
11536 if (It.second.AnyDead)
11537 A.recordDependence(*It.second.LivenessAA, *this, DepClassTy::OPTIONAL);
11538 }
11539
11540 /// See AbstractAttribute::trackStatistics()
11541 void trackStatistics() const override {
11542 STATS_DECLTRACK_FLOATING_ATTR(potential_values)
11543 }
11544};
11545
11546struct AAPotentialValuesArgument final : AAPotentialValuesImpl {
11547 using Base = AAPotentialValuesImpl;
11548 AAPotentialValuesArgument(const IRPosition &IRP, Attributor &A)
11549 : Base(IRP, A) {}
11550
11551 /// See AbstractAttribute::initialize(..).
11552 void initialize(Attributor &A) override {
11553 auto &Arg = cast<Argument>(getAssociatedValue());
11555 indicatePessimisticFixpoint();
11556 }
11557
11558 /// See AbstractAttribute::updateImpl(...).
11559 ChangeStatus updateImpl(Attributor &A) override {
11560 auto AssumedBefore = getAssumed();
11561
11562 unsigned ArgNo = getCalleeArgNo();
11563
11564 bool UsedAssumedInformation = false;
11566 auto CallSitePred = [&](AbstractCallSite ACS) {
11567 const auto CSArgIRP = IRPosition::callsite_argument(ACS, ArgNo);
11568 if (CSArgIRP.getPositionKind() == IRP_INVALID)
11569 return false;
11570
11571 if (!A.getAssumedSimplifiedValues(CSArgIRP, this, Values,
11573 UsedAssumedInformation))
11574 return false;
11575
11576 return isValidState();
11577 };
11578
11579 if (!A.checkForAllCallSites(CallSitePred, *this,
11580 /* RequireAllCallSites */ true,
11581 UsedAssumedInformation))
11582 return indicatePessimisticFixpoint();
11583
11584 Function *Fn = getAssociatedFunction();
11585 bool AnyNonLocal = false;
11586 for (auto &It : Values) {
11587 if (isa<Constant>(It.getValue())) {
11588 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::AnyScope,
11589 getAnchorScope());
11590 continue;
11591 }
11592 if (!AA::isDynamicallyUnique(A, *this, *It.getValue()))
11593 return indicatePessimisticFixpoint();
11594
11595 if (auto *Arg = dyn_cast<Argument>(It.getValue()))
11596 if (Arg->getParent() == Fn) {
11597 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::AnyScope,
11598 getAnchorScope());
11599 continue;
11600 }
11601 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::Interprocedural,
11602 getAnchorScope());
11603 AnyNonLocal = true;
11604 }
11605 assert(!undefIsContained() && "Undef should be an explicit value!");
11606 if (AnyNonLocal)
11607 giveUpOnIntraprocedural(A);
11608
11609 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
11610 : ChangeStatus::CHANGED;
11611 }
11612
11613 /// See AbstractAttribute::trackStatistics()
11614 void trackStatistics() const override {
11615 STATS_DECLTRACK_ARG_ATTR(potential_values)
11616 }
11617};
11618
11619struct AAPotentialValuesReturned : public AAPotentialValuesFloating {
11620 using Base = AAPotentialValuesFloating;
11621 AAPotentialValuesReturned(const IRPosition &IRP, Attributor &A)
11622 : Base(IRP, A) {}
11623
11624 /// See AbstractAttribute::initialize(..).
11625 void initialize(Attributor &A) override {
11626 Function *F = getAssociatedFunction();
11627 if (!F || F->isDeclaration() || F->getReturnType()->isVoidTy()) {
11628 indicatePessimisticFixpoint();
11629 return;
11630 }
11631
11632 for (Argument &Arg : F->args())
11633 if (Arg.hasReturnedAttr()) {
11634 addValue(A, getState(), Arg, nullptr, AA::AnyScope, F);
11635 ReturnedArg = &Arg;
11636 break;
11637 }
11638 if (!A.isFunctionIPOAmendable(*F) ||
11639 A.hasSimplificationCallback(getIRPosition())) {
11640 if (!ReturnedArg)
11641 indicatePessimisticFixpoint();
11642 else
11643 indicateOptimisticFixpoint();
11644 }
11645 }
11646
11647 /// See AbstractAttribute::updateImpl(...).
11648 ChangeStatus updateImpl(Attributor &A) override {
11649 auto AssumedBefore = getAssumed();
11650 bool UsedAssumedInformation = false;
11651
11653 Function *AnchorScope = getAnchorScope();
11654 auto HandleReturnedValue = [&](Value &V, Instruction *CtxI,
11655 bool AddValues) {
11657 Values.clear();
11658 if (!A.getAssumedSimplifiedValues(IRPosition::value(V), this, Values, S,
11659 UsedAssumedInformation,
11660 /* RecurseForSelectAndPHI */ true))
11661 return false;
11662 if (!AddValues)
11663 continue;
11664
11665 bool AllInterAreIntra = false;
11666 if (S == AA::Interprocedural)
11667 AllInterAreIntra =
11668 llvm::all_of(Values, [&](const AA::ValueAndContext &VAC) {
11669 return AA::isValidInScope(*VAC.getValue(), AnchorScope);
11670 });
11671
11672 for (const AA::ValueAndContext &VAC : Values) {
11673 addValue(A, getState(), *VAC.getValue(),
11674 VAC.getCtxI() ? VAC.getCtxI() : CtxI,
11675 AllInterAreIntra ? AA::AnyScope : S, AnchorScope);
11676 }
11677 if (AllInterAreIntra)
11678 break;
11679 }
11680 return true;
11681 };
11682
11683 if (ReturnedArg) {
11684 HandleReturnedValue(*ReturnedArg, nullptr, true);
11685 } else {
11686 auto RetInstPred = [&](Instruction &RetI) {
11687 bool AddValues = true;
11688 if (isa<PHINode>(RetI.getOperand(0)) ||
11689 isa<SelectInst>(RetI.getOperand(0))) {
11690 addValue(A, getState(), *RetI.getOperand(0), &RetI, AA::AnyScope,
11691 AnchorScope);
11692 AddValues = false;
11693 }
11694 return HandleReturnedValue(*RetI.getOperand(0), &RetI, AddValues);
11695 };
11696
11697 if (!A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret},
11698 UsedAssumedInformation,
11699 /* CheckBBLivenessOnly */ true))
11700 return indicatePessimisticFixpoint();
11701 }
11702
11703 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
11704 : ChangeStatus::CHANGED;
11705 }
11706
11707 ChangeStatus manifest(Attributor &A) override {
11708 if (ReturnedArg)
11709 return ChangeStatus::UNCHANGED;
11711 if (!getAssumedSimplifiedValues(A, Values, AA::ValueScope::Intraprocedural,
11712 /* RecurseForSelectAndPHI */ true))
11713 return ChangeStatus::UNCHANGED;
11714 Value *NewVal = getSingleValue(A, *this, getIRPosition(), Values);
11715 if (!NewVal)
11716 return ChangeStatus::UNCHANGED;
11717
11718 ChangeStatus Changed = ChangeStatus::UNCHANGED;
11719 if (auto *Arg = dyn_cast<Argument>(NewVal)) {
11720 STATS_DECLTRACK(UniqueReturnValue, FunctionReturn,
11721 "Number of function with unique return");
11722 Changed |= A.manifestAttrs(
11724 {Attribute::get(Arg->getContext(), Attribute::Returned)});
11725 STATS_DECLTRACK_ARG_ATTR(returned);
11726 }
11727
11728 auto RetInstPred = [&](Instruction &RetI) {
11729 Value *RetOp = RetI.getOperand(0);
11730 if (isa<UndefValue>(RetOp) || RetOp == NewVal)
11731 return true;
11732 if (AA::isValidAtPosition({*NewVal, RetI}, A.getInfoCache()))
11733 if (A.changeUseAfterManifest(RetI.getOperandUse(0), *NewVal))
11734 Changed = ChangeStatus::CHANGED;
11735 return true;
11736 };
11737 bool UsedAssumedInformation = false;
11738 (void)A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret},
11739 UsedAssumedInformation,
11740 /* CheckBBLivenessOnly */ true);
11741 return Changed;
11742 }
11743
11744 ChangeStatus indicatePessimisticFixpoint() override {
11745 return AAPotentialValues::indicatePessimisticFixpoint();
11746 }
11747
11748 /// See AbstractAttribute::trackStatistics()
11749 void trackStatistics() const override{
11750 STATS_DECLTRACK_FNRET_ATTR(potential_values)}
11751
11752 /// The argumented with an existing `returned` attribute.
11753 Argument *ReturnedArg = nullptr;
11754};
11755
11756struct AAPotentialValuesFunction : AAPotentialValuesImpl {
11757 AAPotentialValuesFunction(const IRPosition &IRP, Attributor &A)
11758 : AAPotentialValuesImpl(IRP, A) {}
11759
11760 /// See AbstractAttribute::updateImpl(...).
11761 ChangeStatus updateImpl(Attributor &A) override {
11762 llvm_unreachable("AAPotentialValues(Function|CallSite)::updateImpl will "
11763 "not be called");
11764 }
11765
11766 /// See AbstractAttribute::trackStatistics()
11767 void trackStatistics() const override {
11768 STATS_DECLTRACK_FN_ATTR(potential_values)
11769 }
11770};
11771
11772struct AAPotentialValuesCallSite : AAPotentialValuesFunction {
11773 AAPotentialValuesCallSite(const IRPosition &IRP, Attributor &A)
11774 : AAPotentialValuesFunction(IRP, A) {}
11775
11776 /// See AbstractAttribute::trackStatistics()
11777 void trackStatistics() const override {
11778 STATS_DECLTRACK_CS_ATTR(potential_values)
11779 }
11780};
11781
11782struct AAPotentialValuesCallSiteReturned : AAPotentialValuesImpl {
11783 AAPotentialValuesCallSiteReturned(const IRPosition &IRP, Attributor &A)
11784 : AAPotentialValuesImpl(IRP, A) {}
11785
11786 /// See AbstractAttribute::updateImpl(...).
11787 ChangeStatus updateImpl(Attributor &A) override {
11788 auto AssumedBefore = getAssumed();
11789
11790 Function *Callee = getAssociatedFunction();
11791 if (!Callee)
11792 return indicatePessimisticFixpoint();
11793
11794 bool UsedAssumedInformation = false;
11795 auto *CB = cast<CallBase>(getCtxI());
11796 if (CB->isMustTailCall() &&
11797 !A.isAssumedDead(IRPosition::inst(*CB), this, nullptr,
11798 UsedAssumedInformation))
11799 return indicatePessimisticFixpoint();
11800
11801 Function *Caller = CB->getCaller();
11802
11803 auto AddScope = [&](AA::ValueScope S) {
11805 if (!A.getAssumedSimplifiedValues(IRPosition::returned(*Callee), this,
11806 Values, S, UsedAssumedInformation))
11807 return false;
11808
11809 for (auto &It : Values) {
11810 Value *V = It.getValue();
11811 std::optional<Value *> CallerV = A.translateArgumentToCallSiteContent(
11812 V, *CB, *this, UsedAssumedInformation);
11813 if (!CallerV.has_value()) {
11814 // Nothing to do as long as no value was determined.
11815 continue;
11816 }
11817 V = *CallerV ? *CallerV : V;
11818 if (*CallerV && AA::isDynamicallyUnique(A, *this, *V)) {
11819 if (recurseForValue(A, IRPosition::value(*V), S))
11820 continue;
11821 }
11822 if (S == AA::Intraprocedural && !AA::isValidInScope(*V, Caller)) {
11823 giveUpOnIntraprocedural(A);
11824 return true;
11825 }
11826 addValue(A, getState(), *V, CB, S, getAnchorScope());
11827 }
11828 return true;
11829 };
11830 if (!AddScope(AA::Intraprocedural))
11831 return indicatePessimisticFixpoint();
11832 if (!AddScope(AA::Interprocedural))
11833 return indicatePessimisticFixpoint();
11834 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
11835 : ChangeStatus::CHANGED;
11836 }
11837
11838 ChangeStatus indicatePessimisticFixpoint() override {
11839 return AAPotentialValues::indicatePessimisticFixpoint();
11840 }
11841
11842 /// See AbstractAttribute::trackStatistics()
11843 void trackStatistics() const override {
11844 STATS_DECLTRACK_CSRET_ATTR(potential_values)
11845 }
11846};
11847
11848struct AAPotentialValuesCallSiteArgument : AAPotentialValuesFloating {
11849 AAPotentialValuesCallSiteArgument(const IRPosition &IRP, Attributor &A)
11850 : AAPotentialValuesFloating(IRP, A) {}
11851
11852 /// See AbstractAttribute::trackStatistics()
11853 void trackStatistics() const override {
11854 STATS_DECLTRACK_CSARG_ATTR(potential_values)
11855 }
11856};
11857} // namespace
11858
11859/// ---------------------- Assumption Propagation ------------------------------
11860namespace {
11861struct AAAssumptionInfoImpl : public AAAssumptionInfo {
11862 AAAssumptionInfoImpl(const IRPosition &IRP, Attributor &A,
11863 const DenseSet<StringRef> &Known)
11864 : AAAssumptionInfo(IRP, A, Known) {}
11865
11866 /// See AbstractAttribute::manifest(...).
11867 ChangeStatus manifest(Attributor &A) override {
11868 // Don't manifest a universal set if it somehow made it here.
11869 if (getKnown().isUniversal())
11870 return ChangeStatus::UNCHANGED;
11871
11872 const IRPosition &IRP = getIRPosition();
11873 SmallVector<StringRef, 0> Set(getAssumed().getSet().begin(),
11874 getAssumed().getSet().end());
11875 llvm::sort(Set);
11876 return A.manifestAttrs(IRP,
11877 Attribute::get(IRP.getAnchorValue().getContext(),
11879 llvm::join(Set, ",")),
11880 /*ForceReplace=*/true);
11881 }
11882
11883 bool hasAssumption(const StringRef Assumption) const override {
11884 return isValidState() && setContains(Assumption);
11885 }
11886
11887 /// See AbstractAttribute::getAsStr()
11888 const std::string getAsStr(Attributor *A) const override {
11889 const SetContents &Known = getKnown();
11890 const SetContents &Assumed = getAssumed();
11891
11892 SmallVector<StringRef, 0> Set(Known.getSet().begin(), Known.getSet().end());
11893 llvm::sort(Set);
11894 const std::string KnownStr = llvm::join(Set, ",");
11895
11896 std::string AssumedStr = "Universal";
11897 if (!Assumed.isUniversal()) {
11898 Set.assign(Assumed.getSet().begin(), Assumed.getSet().end());
11899 AssumedStr = llvm::join(Set, ",");
11900 }
11901 return "Known [" + KnownStr + "]," + " Assumed [" + AssumedStr + "]";
11902 }
11903};
11904
11905/// Propagates assumption information from parent functions to all of their
11906/// successors. An assumption can be propagated if the containing function
11907/// dominates the called function.
11908///
11909/// We start with a "known" set of assumptions already valid for the associated
11910/// function and an "assumed" set that initially contains all possible
11911/// assumptions. The assumed set is inter-procedurally updated by narrowing its
11912/// contents as concrete values are known. The concrete values are seeded by the
11913/// first nodes that are either entries into the call graph, or contains no
11914/// assumptions. Each node is updated as the intersection of the assumed state
11915/// with all of its predecessors.
11916struct AAAssumptionInfoFunction final : AAAssumptionInfoImpl {
11917 AAAssumptionInfoFunction(const IRPosition &IRP, Attributor &A)
11918 : AAAssumptionInfoImpl(IRP, A,
11919 getAssumptions(*IRP.getAssociatedFunction())) {}
11920
11921 /// See AbstractAttribute::updateImpl(...).
11922 ChangeStatus updateImpl(Attributor &A) override {
11923 bool Changed = false;
11924
11925 auto CallSitePred = [&](AbstractCallSite ACS) {
11926 const auto *AssumptionAA = A.getAAFor<AAAssumptionInfo>(
11927 *this, IRPosition::callsite_function(*ACS.getInstruction()),
11928 DepClassTy::REQUIRED);
11929 if (!AssumptionAA)
11930 return false;
11931 // Get the set of assumptions shared by all of this function's callers.
11932 Changed |= getIntersection(AssumptionAA->getAssumed());
11933 return !getAssumed().empty() || !getKnown().empty();
11934 };
11935
11936 bool UsedAssumedInformation = false;
11937 // Get the intersection of all assumptions held by this node's predecessors.
11938 // If we don't know all the call sites then this is either an entry into the
11939 // call graph or an empty node. This node is known to only contain its own
11940 // assumptions and can be propagated to its successors.
11941 if (!A.checkForAllCallSites(CallSitePred, *this, true,
11942 UsedAssumedInformation))
11943 return indicatePessimisticFixpoint();
11944
11945 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
11946 }
11947
11948 void trackStatistics() const override {}
11949};
11950
11951/// Assumption Info defined for call sites.
11952struct AAAssumptionInfoCallSite final : AAAssumptionInfoImpl {
11953
11954 AAAssumptionInfoCallSite(const IRPosition &IRP, Attributor &A)
11955 : AAAssumptionInfoImpl(IRP, A, getInitialAssumptions(IRP)) {}
11956
11957 /// See AbstractAttribute::initialize(...).
11958 void initialize(Attributor &A) override {
11959 const IRPosition &FnPos = IRPosition::function(*getAnchorScope());
11960 A.getAAFor<AAAssumptionInfo>(*this, FnPos, DepClassTy::REQUIRED);
11961 }
11962
11963 /// See AbstractAttribute::updateImpl(...).
11964 ChangeStatus updateImpl(Attributor &A) override {
11965 const IRPosition &FnPos = IRPosition::function(*getAnchorScope());
11966 auto *AssumptionAA =
11967 A.getAAFor<AAAssumptionInfo>(*this, FnPos, DepClassTy::REQUIRED);
11968 if (!AssumptionAA)
11969 return indicatePessimisticFixpoint();
11970 bool Changed = getIntersection(AssumptionAA->getAssumed());
11971 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
11972 }
11973
11974 /// See AbstractAttribute::trackStatistics()
11975 void trackStatistics() const override {}
11976
11977private:
11978 /// Helper to initialized the known set as all the assumptions this call and
11979 /// the callee contain.
11980 DenseSet<StringRef> getInitialAssumptions(const IRPosition &IRP) {
11981 const CallBase &CB = cast<CallBase>(IRP.getAssociatedValue());
11982 auto Assumptions = getAssumptions(CB);
11983 if (const Function *F = CB.getCaller())
11984 set_union(Assumptions, getAssumptions(*F));
11985 if (Function *F = IRP.getAssociatedFunction())
11986 set_union(Assumptions, getAssumptions(*F));
11987 return Assumptions;
11988 }
11989};
11990} // namespace
11991
11993 return static_cast<AACallGraphNode *>(const_cast<AACallEdges *>(
11994 A.getOrCreateAAFor<AACallEdges>(IRPosition::function(**I))));
11995}
11996
11998
11999/// ------------------------ UnderlyingObjects ---------------------------------
12000
12001namespace {
12002struct AAUnderlyingObjectsImpl
12003 : StateWrapper<BooleanState, AAUnderlyingObjects> {
12005 AAUnderlyingObjectsImpl(const IRPosition &IRP, Attributor &A) : BaseTy(IRP) {}
12006
12007 /// See AbstractAttribute::getAsStr().
12008 const std::string getAsStr(Attributor *A) const override {
12009 if (!isValidState())
12010 return "<invalid>";
12011 std::string Str;
12013 OS << "underlying objects: inter " << InterAssumedUnderlyingObjects.size()
12014 << " objects, intra " << IntraAssumedUnderlyingObjects.size()
12015 << " objects.\n";
12016 if (!InterAssumedUnderlyingObjects.empty()) {
12017 OS << "inter objects:\n";
12018 for (auto *Obj : InterAssumedUnderlyingObjects)
12019 OS << *Obj << '\n';
12020 }
12021 if (!IntraAssumedUnderlyingObjects.empty()) {
12022 OS << "intra objects:\n";
12023 for (auto *Obj : IntraAssumedUnderlyingObjects)
12024 OS << *Obj << '\n';
12025 }
12026 return Str;
12027 }
12028
12029 /// See AbstractAttribute::trackStatistics()
12030 void trackStatistics() const override {}
12031
12032 /// See AbstractAttribute::updateImpl(...).
12033 ChangeStatus updateImpl(Attributor &A) override {
12034 auto &Ptr = getAssociatedValue();
12035
12036 bool UsedAssumedInformation = false;
12037 auto DoUpdate = [&](SmallSetVector<Value *, 8> &UnderlyingObjects,
12039 SmallPtrSet<Value *, 8> SeenObjects;
12041
12042 if (!A.getAssumedSimplifiedValues(IRPosition::value(Ptr), *this, Values,
12043 Scope, UsedAssumedInformation))
12044 return UnderlyingObjects.insert(&Ptr);
12045
12046 bool Changed = false;
12047
12048 for (unsigned I = 0; I < Values.size(); ++I) {
12049 auto &VAC = Values[I];
12050 auto *Obj = VAC.getValue();
12051 Value *UO = getUnderlyingObject(Obj);
12052 if (!SeenObjects.insert(UO ? UO : Obj).second)
12053 continue;
12054 if (UO && UO != Obj) {
12055 if (isa<AllocaInst>(UO) || isa<GlobalValue>(UO)) {
12056 Changed |= UnderlyingObjects.insert(UO);
12057 continue;
12058 }
12059
12060 const auto *OtherAA = A.getAAFor<AAUnderlyingObjects>(
12061 *this, IRPosition::value(*UO), DepClassTy::OPTIONAL);
12062 auto Pred = [&](Value &V) {
12063 if (&V == UO)
12064 Changed |= UnderlyingObjects.insert(UO);
12065 else
12066 Values.emplace_back(V, nullptr);
12067 return true;
12068 };
12069
12070 if (!OtherAA || !OtherAA->forallUnderlyingObjects(Pred, Scope))
12072 "The forall call should not return false at this position");
12073 UsedAssumedInformation |= !OtherAA->getState().isAtFixpoint();
12074 continue;
12075 }
12076
12077 if (isa<SelectInst>(Obj)) {
12078 Changed |= handleIndirect(A, *Obj, UnderlyingObjects, Scope,
12079 UsedAssumedInformation);
12080 continue;
12081 }
12082 if (auto *PHI = dyn_cast<PHINode>(Obj)) {
12083 // Explicitly look through PHIs as we do not care about dynamically
12084 // uniqueness.
12085 for (unsigned u = 0, e = PHI->getNumIncomingValues(); u < e; u++) {
12086 Changed |=
12087 handleIndirect(A, *PHI->getIncomingValue(u), UnderlyingObjects,
12088 Scope, UsedAssumedInformation);
12089 }
12090 continue;
12091 }
12092
12093 Changed |= UnderlyingObjects.insert(Obj);
12094 }
12095
12096 return Changed;
12097 };
12098
12099 bool Changed = false;
12100 Changed |= DoUpdate(IntraAssumedUnderlyingObjects, AA::Intraprocedural);
12101 Changed |= DoUpdate(InterAssumedUnderlyingObjects, AA::Interprocedural);
12102 if (!UsedAssumedInformation)
12103 indicateOptimisticFixpoint();
12104 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
12105 }
12106
12107 bool forallUnderlyingObjects(
12108 function_ref<bool(Value &)> Pred,
12109 AA::ValueScope Scope = AA::Interprocedural) const override {
12110 if (!isValidState())
12111 return Pred(getAssociatedValue());
12112
12113 auto &AssumedUnderlyingObjects = Scope == AA::Intraprocedural
12114 ? IntraAssumedUnderlyingObjects
12115 : InterAssumedUnderlyingObjects;
12116 for (Value *Obj : AssumedUnderlyingObjects)
12117 if (!Pred(*Obj))
12118 return false;
12119
12120 return true;
12121 }
12122
12123private:
12124 /// Handle the case where the value is not the actual underlying value, such
12125 /// as a phi node or a select instruction.
12126 bool handleIndirect(Attributor &A, Value &V,
12127 SmallSetVector<Value *, 8> &UnderlyingObjects,
12128 AA::ValueScope Scope, bool &UsedAssumedInformation) {
12129 bool Changed = false;
12130 const auto *AA = A.getAAFor<AAUnderlyingObjects>(
12131 *this, IRPosition::value(V), DepClassTy::OPTIONAL);
12132 auto Pred = [&](Value &V) {
12133 Changed |= UnderlyingObjects.insert(&V);
12134 return true;
12135 };
12136 if (!AA || !AA->forallUnderlyingObjects(Pred, Scope))
12138 "The forall call should not return false at this position");
12139 UsedAssumedInformation |= !AA->getState().isAtFixpoint();
12140 return Changed;
12141 }
12142
12143 /// All the underlying objects collected so far via intra procedural scope.
12144 SmallSetVector<Value *, 8> IntraAssumedUnderlyingObjects;
12145 /// All the underlying objects collected so far via inter procedural scope.
12146 SmallSetVector<Value *, 8> InterAssumedUnderlyingObjects;
12147};
12148
12149struct AAUnderlyingObjectsFloating final : AAUnderlyingObjectsImpl {
12150 AAUnderlyingObjectsFloating(const IRPosition &IRP, Attributor &A)
12151 : AAUnderlyingObjectsImpl(IRP, A) {}
12152};
12153
12154struct AAUnderlyingObjectsArgument final : AAUnderlyingObjectsImpl {
12155 AAUnderlyingObjectsArgument(const IRPosition &IRP, Attributor &A)
12156 : AAUnderlyingObjectsImpl(IRP, A) {}
12157};
12158
12159struct AAUnderlyingObjectsCallSite final : AAUnderlyingObjectsImpl {
12160 AAUnderlyingObjectsCallSite(const IRPosition &IRP, Attributor &A)
12161 : AAUnderlyingObjectsImpl(IRP, A) {}
12162};
12163
12164struct AAUnderlyingObjectsCallSiteArgument final : AAUnderlyingObjectsImpl {
12165 AAUnderlyingObjectsCallSiteArgument(const IRPosition &IRP, Attributor &A)
12166 : AAUnderlyingObjectsImpl(IRP, A) {}
12167};
12168
12169struct AAUnderlyingObjectsReturned final : AAUnderlyingObjectsImpl {
12170 AAUnderlyingObjectsReturned(const IRPosition &IRP, Attributor &A)
12171 : AAUnderlyingObjectsImpl(IRP, A) {}
12172};
12173
12174struct AAUnderlyingObjectsCallSiteReturned final : AAUnderlyingObjectsImpl {
12175 AAUnderlyingObjectsCallSiteReturned(const IRPosition &IRP, Attributor &A)
12176 : AAUnderlyingObjectsImpl(IRP, A) {}
12177};
12178
12179struct AAUnderlyingObjectsFunction final : AAUnderlyingObjectsImpl {
12180 AAUnderlyingObjectsFunction(const IRPosition &IRP, Attributor &A)
12181 : AAUnderlyingObjectsImpl(IRP, A) {}
12182};
12183} // namespace
12184
12185/// ------------------------ Global Value Info -------------------------------
12186namespace {
12187struct AAGlobalValueInfoFloating : public AAGlobalValueInfo {
12188 AAGlobalValueInfoFloating(const IRPosition &IRP, Attributor &A)
12189 : AAGlobalValueInfo(IRP, A) {}
12190
12191 /// See AbstractAttribute::initialize(...).
12192 void initialize(Attributor &A) override {}
12193
12194 bool checkUse(Attributor &A, const Use &U, bool &Follow,
12195 SmallVectorImpl<const Value *> &Worklist) {
12196 Instruction *UInst = dyn_cast<Instruction>(U.getUser());
12197 if (!UInst) {
12198 Follow = true;
12199 return true;
12200 }
12201
12202 LLVM_DEBUG(dbgs() << "[AAGlobalValueInfo] Check use: " << *U.get() << " in "
12203 << *UInst << "\n");
12204
12205 if (auto *Cmp = dyn_cast<ICmpInst>(U.getUser())) {
12206 int Idx = &Cmp->getOperandUse(0) == &U;
12207 if (isa<Constant>(Cmp->getOperand(Idx)))
12208 return true;
12209 return U == &getAnchorValue();
12210 }
12211
12212 // Explicitly catch return instructions.
12213 if (isa<ReturnInst>(UInst)) {
12214 auto CallSitePred = [&](AbstractCallSite ACS) {
12215 Worklist.push_back(ACS.getInstruction());
12216 return true;
12217 };
12218 bool UsedAssumedInformation = false;
12219 // TODO: We should traverse the uses or add a "non-call-site" CB.
12220 if (!A.checkForAllCallSites(CallSitePred, *UInst->getFunction(),
12221 /*RequireAllCallSites=*/true, this,
12222 UsedAssumedInformation))
12223 return false;
12224 return true;
12225 }
12226
12227 // For now we only use special logic for call sites. However, the tracker
12228 // itself knows about a lot of other non-capturing cases already.
12229 auto *CB = dyn_cast<CallBase>(UInst);
12230 if (!CB)
12231 return false;
12232 // Direct calls are OK uses.
12233 if (CB->isCallee(&U))
12234 return true;
12235 // Non-argument uses are scary.
12236 if (!CB->isArgOperand(&U))
12237 return false;
12238 // TODO: Iterate callees.
12239 auto *Fn = dyn_cast<Function>(CB->getCalledOperand());
12240 if (!Fn || !A.isFunctionIPOAmendable(*Fn))
12241 return false;
12242
12243 unsigned ArgNo = CB->getArgOperandNo(&U);
12244 Worklist.push_back(Fn->getArg(ArgNo));
12245 return true;
12246 }
12247
12248 ChangeStatus updateImpl(Attributor &A) override {
12249 unsigned NumUsesBefore = Uses.size();
12250
12251 SmallPtrSet<const Value *, 8> Visited;
12253 Worklist.push_back(&getAnchorValue());
12254
12255 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
12256 Uses.insert(&U);
12257 // TODO(captures): Make this more precise.
12258 UseCaptureInfo CI = DetermineUseCaptureKind(U, /*Base=*/nullptr);
12259 if (CI.isPassthrough()) {
12260 Follow = true;
12261 return true;
12262 }
12263 return checkUse(A, U, Follow, Worklist);
12264 };
12265 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) {
12266 Uses.insert(&OldU);
12267 return true;
12268 };
12269
12270 while (!Worklist.empty()) {
12271 const Value *V = Worklist.pop_back_val();
12272 if (!Visited.insert(V).second)
12273 continue;
12274 if (!A.checkForAllUses(UsePred, *this, *V,
12275 /* CheckBBLivenessOnly */ true,
12276 DepClassTy::OPTIONAL,
12277 /* IgnoreDroppableUses */ true, EquivalentUseCB)) {
12278 return indicatePessimisticFixpoint();
12279 }
12280 }
12281
12282 return Uses.size() == NumUsesBefore ? ChangeStatus::UNCHANGED
12283 : ChangeStatus::CHANGED;
12284 }
12285
12286 bool isPotentialUse(const Use &U) const override {
12287 return !isValidState() || Uses.contains(&U);
12288 }
12289
12290 /// See AbstractAttribute::manifest(...).
12291 ChangeStatus manifest(Attributor &A) override {
12292 return ChangeStatus::UNCHANGED;
12293 }
12294
12295 /// See AbstractAttribute::getAsStr().
12296 const std::string getAsStr(Attributor *A) const override {
12297 return "[" + std::to_string(Uses.size()) + " uses]";
12298 }
12299
12300 void trackStatistics() const override {
12301 STATS_DECLTRACK_FLOATING_ATTR(GlobalValuesTracked);
12302 }
12303
12304private:
12305 /// Set of (transitive) uses of this GlobalValue.
12306 SmallPtrSet<const Use *, 8> Uses;
12307};
12308} // namespace
12309
12310/// ------------------------ Indirect Call Info -------------------------------
12311namespace {
12312struct AAIndirectCallInfoCallSite : public AAIndirectCallInfo {
12313 AAIndirectCallInfoCallSite(const IRPosition &IRP, Attributor &A)
12314 : AAIndirectCallInfo(IRP, A) {}
12315
12316 /// See AbstractAttribute::initialize(...).
12317 void initialize(Attributor &A) override {
12318 auto *MD = getCtxI()->getMetadata(LLVMContext::MD_callees);
12319 if (!MD && !A.isClosedWorldModule())
12320 return;
12321
12322 if (MD) {
12323 for (const auto &Op : MD->operands())
12324 if (Function *Callee = mdconst::dyn_extract_or_null<Function>(Op))
12325 PotentialCallees.insert(Callee);
12326 } else if (A.isClosedWorldModule()) {
12327 ArrayRef<Function *> IndirectlyCallableFunctions =
12328 A.getInfoCache().getIndirectlyCallableFunctions(A);
12329 PotentialCallees.insert_range(IndirectlyCallableFunctions);
12330 }
12331
12332 if (PotentialCallees.empty())
12333 indicateOptimisticFixpoint();
12334 }
12335
12336 ChangeStatus updateImpl(Attributor &A) override {
12337 CallBase *CB = cast<CallBase>(getCtxI());
12338 const Use &CalleeUse = CB->getCalledOperandUse();
12339 Value *FP = CB->getCalledOperand();
12340
12341 SmallSetVector<Function *, 4> AssumedCalleesNow;
12342 bool AllCalleesKnownNow = AllCalleesKnown;
12343
12344 auto CheckPotentialCalleeUse = [&](Function &PotentialCallee,
12345 bool &UsedAssumedInformation) {
12346 const auto *GIAA = A.getAAFor<AAGlobalValueInfo>(
12347 *this, IRPosition::value(PotentialCallee), DepClassTy::OPTIONAL);
12348 if (!GIAA || GIAA->isPotentialUse(CalleeUse))
12349 return true;
12350 UsedAssumedInformation = !GIAA->isAtFixpoint();
12351 return false;
12352 };
12353
12354 auto AddPotentialCallees = [&]() {
12355 for (auto *PotentialCallee : PotentialCallees) {
12356 bool UsedAssumedInformation = false;
12357 if (CheckPotentialCalleeUse(*PotentialCallee, UsedAssumedInformation))
12358 AssumedCalleesNow.insert(PotentialCallee);
12359 }
12360 };
12361
12362 // Use simplification to find potential callees, if !callees was present,
12363 // fallback to that set if necessary.
12364 bool UsedAssumedInformation = false;
12366 if (!A.getAssumedSimplifiedValues(IRPosition::value(*FP), this, Values,
12367 AA::ValueScope::AnyScope,
12368 UsedAssumedInformation)) {
12369 if (PotentialCallees.empty())
12370 return indicatePessimisticFixpoint();
12371 AddPotentialCallees();
12372 }
12373
12374 // Try to find a reason for \p Fn not to be a potential callee. If none was
12375 // found, add it to the assumed callees set.
12376 auto CheckPotentialCallee = [&](Function &Fn) {
12377 if (!PotentialCallees.empty() && !PotentialCallees.count(&Fn))
12378 return false;
12379
12380 auto &CachedResult = FilterResults[&Fn];
12381 if (CachedResult.has_value())
12382 return CachedResult.value();
12383
12384 bool UsedAssumedInformation = false;
12385 if (!CheckPotentialCalleeUse(Fn, UsedAssumedInformation)) {
12386 if (!UsedAssumedInformation)
12387 CachedResult = false;
12388 return false;
12389 }
12390
12391 int NumFnArgs = Fn.arg_size();
12392 int NumCBArgs = CB->arg_size();
12393
12394 // Check if any excess argument (which we fill up with poison) is known to
12395 // be UB on undef.
12396 for (int I = NumCBArgs; I < NumFnArgs; ++I) {
12397 bool IsKnown = false;
12399 A, this, IRPosition::argument(*Fn.getArg(I)),
12400 DepClassTy::OPTIONAL, IsKnown)) {
12401 if (IsKnown)
12402 CachedResult = false;
12403 return false;
12404 }
12405 }
12406
12407 CachedResult = true;
12408 return true;
12409 };
12410
12411 // Check simplification result, prune known UB callees, also restrict it to
12412 // the !callees set, if present.
12413 for (auto &VAC : Values) {
12414 if (isa<UndefValue>(VAC.getValue()))
12415 continue;
12417 VAC.getValue()->getType()->getPointerAddressSpace() == 0)
12418 continue;
12419 // TODO: Check for known UB, e.g., poison + noundef.
12420 if (auto *VACFn = dyn_cast<Function>(VAC.getValue())) {
12421 if (CheckPotentialCallee(*VACFn))
12422 AssumedCalleesNow.insert(VACFn);
12423 continue;
12424 }
12425 if (!PotentialCallees.empty()) {
12426 AddPotentialCallees();
12427 break;
12428 }
12429 AllCalleesKnownNow = false;
12430 }
12431
12432 if (AssumedCalleesNow == AssumedCallees &&
12433 AllCalleesKnown == AllCalleesKnownNow)
12434 return ChangeStatus::UNCHANGED;
12435
12436 std::swap(AssumedCallees, AssumedCalleesNow);
12437 AllCalleesKnown = AllCalleesKnownNow;
12438 return ChangeStatus::CHANGED;
12439 }
12440
12441 /// See AbstractAttribute::manifest(...).
12442 ChangeStatus manifest(Attributor &A) override {
12443 // If we can't specialize at all, give up now.
12444 if (!AllCalleesKnown && AssumedCallees.empty())
12445 return ChangeStatus::UNCHANGED;
12446
12447 CallBase *CB = cast<CallBase>(getCtxI());
12448 bool UsedAssumedInformation = false;
12449 if (A.isAssumedDead(*CB, this, /*LivenessAA=*/nullptr,
12450 UsedAssumedInformation))
12451 return ChangeStatus::UNCHANGED;
12452
12453 ChangeStatus Changed = ChangeStatus::UNCHANGED;
12454 Value *FP = CB->getCalledOperand();
12455 if (FP->getType()->getPointerAddressSpace())
12456 FP = new AddrSpaceCastInst(FP, PointerType::get(FP->getContext(), 0),
12457 FP->getName() + ".as0", CB->getIterator());
12458
12459 bool CBIsVoid = CB->getType()->isVoidTy();
12461 FunctionType *CSFT = CB->getFunctionType();
12462 SmallVector<Value *> CSArgs(CB->args());
12463
12464 // If we know all callees and there are none, the call site is (effectively)
12465 // dead (or UB).
12466 if (AssumedCallees.empty()) {
12467 assert(AllCalleesKnown &&
12468 "Expected all callees to be known if there are none.");
12469 A.changeToUnreachableAfterManifest(CB);
12470 return ChangeStatus::CHANGED;
12471 }
12472
12473 // Special handling for the single callee case.
12474 if (AllCalleesKnown && AssumedCallees.size() == 1) {
12475 auto *NewCallee = AssumedCallees.front();
12476 if (isLegalToPromote(*CB, NewCallee)) {
12477 promoteCall(*CB, NewCallee, nullptr);
12478 NumIndirectCallsPromoted++;
12479 return ChangeStatus::CHANGED;
12480 }
12481 Instruction *NewCall =
12482 CallInst::Create(FunctionCallee(CSFT, NewCallee), CSArgs,
12483 CB->getName(), CB->getIterator());
12484 if (!CBIsVoid)
12485 A.changeAfterManifest(IRPosition::callsite_returned(*CB), *NewCall);
12486 A.deleteAfterManifest(*CB);
12487 return ChangeStatus::CHANGED;
12488 }
12489
12490 // For each potential value we create a conditional
12491 //
12492 // ```
12493 // if (ptr == value) value(args);
12494 // else ...
12495 // ```
12496 //
12497 bool SpecializedForAnyCallees = false;
12498 bool SpecializedForAllCallees = AllCalleesKnown;
12499 ICmpInst *LastCmp = nullptr;
12500 SmallVector<Function *, 8> SkippedAssumedCallees;
12502 for (Function *NewCallee : AssumedCallees) {
12503 if (!A.shouldSpecializeCallSiteForCallee(*this, *CB, *NewCallee,
12504 AssumedCallees.size())) {
12505 SkippedAssumedCallees.push_back(NewCallee);
12506 SpecializedForAllCallees = false;
12507 continue;
12508 }
12509 SpecializedForAnyCallees = true;
12510
12511 LastCmp = new ICmpInst(IP, llvm::CmpInst::ICMP_EQ, FP, NewCallee);
12512 Instruction *ThenTI =
12513 SplitBlockAndInsertIfThen(LastCmp, IP, /* Unreachable */ false);
12514 BasicBlock *CBBB = CB->getParent();
12515 A.registerManifestAddedBasicBlock(*ThenTI->getParent());
12516 A.registerManifestAddedBasicBlock(*IP->getParent());
12517 auto *SplitTI = cast<CondBrInst>(LastCmp->getNextNode());
12518 BasicBlock *ElseBB;
12519 if (&*IP == CB) {
12520 ElseBB = BasicBlock::Create(ThenTI->getContext(), "",
12521 ThenTI->getFunction(), CBBB);
12522 A.registerManifestAddedBasicBlock(*ElseBB);
12523 IP = UncondBrInst::Create(CBBB, ElseBB)->getIterator();
12524 SplitTI->replaceUsesOfWith(CBBB, ElseBB);
12525 } else {
12526 ElseBB = IP->getParent();
12527 ThenTI->replaceUsesOfWith(ElseBB, CBBB);
12528 }
12529 CastInst *RetBC = nullptr;
12530 CallInst *NewCall = nullptr;
12531 if (isLegalToPromote(*CB, NewCallee)) {
12532 auto *CBClone = cast<CallBase>(CB->clone());
12533 CBClone->insertBefore(ThenTI->getIterator());
12534 NewCall = &cast<CallInst>(promoteCall(*CBClone, NewCallee, &RetBC));
12535 NumIndirectCallsPromoted++;
12536 } else {
12537 NewCall = CallInst::Create(FunctionCallee(CSFT, NewCallee), CSArgs,
12538 CB->getName(), ThenTI->getIterator());
12539 }
12540 NewCalls.push_back({NewCall, RetBC});
12541 }
12542
12543 auto AttachCalleeMetadata = [&](CallBase &IndirectCB) {
12544 if (!AllCalleesKnown)
12545 return ChangeStatus::UNCHANGED;
12546 MDBuilder MDB(IndirectCB.getContext());
12547 MDNode *Callees = MDB.createCallees(SkippedAssumedCallees);
12548 IndirectCB.setMetadata(LLVMContext::MD_callees, Callees);
12549 return ChangeStatus::CHANGED;
12550 };
12551
12552 if (!SpecializedForAnyCallees)
12553 return AttachCalleeMetadata(*CB);
12554
12555 // Check if we need the fallback indirect call still.
12556 if (SpecializedForAllCallees) {
12558 LastCmp->eraseFromParent();
12559 new UnreachableInst(IP->getContext(), IP);
12560 IP->eraseFromParent();
12561 } else {
12562 auto *CBClone = cast<CallInst>(CB->clone());
12563 CBClone->setName(CB->getName());
12564 CBClone->insertBefore(*IP->getParent(), IP);
12565 NewCalls.push_back({CBClone, nullptr});
12566 AttachCalleeMetadata(*CBClone);
12567 }
12568
12569 // Check if we need a PHI to merge the results.
12570 if (!CBIsVoid) {
12571 auto *PHI = PHINode::Create(CB->getType(), NewCalls.size(),
12572 CB->getName() + ".phi",
12573 CB->getParent()->getFirstInsertionPt());
12574 for (auto &It : NewCalls) {
12575 CallBase *NewCall = It.first;
12576 Instruction *CallRet = It.second ? It.second : It.first;
12577 if (CallRet->getType() == CB->getType())
12578 PHI->addIncoming(CallRet, CallRet->getParent());
12579 else if (NewCall->getType()->isVoidTy())
12580 PHI->addIncoming(PoisonValue::get(CB->getType()),
12581 NewCall->getParent());
12582 else
12583 llvm_unreachable("Call return should match or be void!");
12584 }
12585 A.changeAfterManifest(IRPosition::callsite_returned(*CB), *PHI);
12586 }
12587
12588 A.deleteAfterManifest(*CB);
12589 Changed = ChangeStatus::CHANGED;
12590
12591 return Changed;
12592 }
12593
12594 /// See AbstractAttribute::getAsStr().
12595 const std::string getAsStr(Attributor *A) const override {
12596 return std::string(AllCalleesKnown ? "eliminate" : "specialize") +
12597 " indirect call site with " + std::to_string(AssumedCallees.size()) +
12598 " functions";
12599 }
12600
12601 void trackStatistics() const override {
12602 if (AllCalleesKnown) {
12604 Eliminated, CallSites,
12605 "Number of indirect call sites eliminated via specialization")
12606 } else {
12607 STATS_DECLTRACK(Specialized, CallSites,
12608 "Number of indirect call sites specialized")
12609 }
12610 }
12611
12612 bool foreachCallee(function_ref<bool(Function *)> CB) const override {
12613 return isValidState() && AllCalleesKnown && all_of(AssumedCallees, CB);
12614 }
12615
12616private:
12617 /// Map to remember filter results.
12618 DenseMap<Function *, std::optional<bool>> FilterResults;
12619
12620 /// If the !callee metadata was present, this set will contain all potential
12621 /// callees (superset).
12622 SmallSetVector<Function *, 4> PotentialCallees;
12623
12624 /// This set contains all currently assumed calllees, which might grow over
12625 /// time.
12626 SmallSetVector<Function *, 4> AssumedCallees;
12627
12628 /// Flag to indicate if all possible callees are in the AssumedCallees set or
12629 /// if there could be others.
12630 bool AllCalleesKnown = true;
12631};
12632} // namespace
12633
12634/// --------------------- Invariant Load Pointer -------------------------------
12635namespace {
12636
12637struct AAInvariantLoadPointerImpl
12638 : public StateWrapper<BitIntegerState<uint8_t, 15>,
12639 AAInvariantLoadPointer> {
12640
12641 enum {
12642 // pointer does not alias within the bounds of the function
12643 IS_NOALIAS = 1 << 0,
12644 // pointer is not involved in any effectful instructions within the bounds
12645 // of the function
12646 IS_NOEFFECT = 1 << 1,
12647 // loads are invariant within the bounds of the function
12648 IS_LOCALLY_INVARIANT = 1 << 2,
12649 // memory lifetime is constrained within the bounds of the function
12650 IS_LOCALLY_CONSTRAINED = 1 << 3,
12651
12652 IS_BEST_STATE = IS_NOALIAS | IS_NOEFFECT | IS_LOCALLY_INVARIANT |
12653 IS_LOCALLY_CONSTRAINED,
12654 };
12655 static_assert(getBestState() == IS_BEST_STATE, "Unexpected best state");
12656
12657 using Base =
12658 StateWrapper<BitIntegerState<uint8_t, 15>, AAInvariantLoadPointer>;
12659
12660 // the BitIntegerState is optimistic about IS_NOALIAS and IS_NOEFFECT, but
12661 // pessimistic about IS_KNOWN_INVARIANT
12662 AAInvariantLoadPointerImpl(const IRPosition &IRP, Attributor &A)
12663 : Base(IRP) {}
12664
12665 bool isKnownInvariant() const final {
12666 return isKnownLocallyInvariant() && isKnown(IS_LOCALLY_CONSTRAINED);
12667 }
12668
12669 bool isKnownLocallyInvariant() const final {
12670 if (isKnown(IS_LOCALLY_INVARIANT))
12671 return true;
12672 return isKnown(IS_NOALIAS | IS_NOEFFECT);
12673 }
12674
12675 bool isAssumedInvariant() const final {
12676 return isAssumedLocallyInvariant() && isAssumed(IS_LOCALLY_CONSTRAINED);
12677 }
12678
12679 bool isAssumedLocallyInvariant() const final {
12680 if (isAssumed(IS_LOCALLY_INVARIANT))
12681 return true;
12682 return isAssumed(IS_NOALIAS | IS_NOEFFECT);
12683 }
12684
12685 ChangeStatus updateImpl(Attributor &A) override {
12686 ChangeStatus Changed = ChangeStatus::UNCHANGED;
12687
12688 Changed |= updateNoAlias(A);
12689 if (requiresNoAlias() && !isAssumed(IS_NOALIAS))
12690 return indicatePessimisticFixpoint();
12691
12692 Changed |= updateNoEffect(A);
12693
12694 Changed |= updateLocalInvariance(A);
12695
12696 return Changed;
12697 }
12698
12699 ChangeStatus manifest(Attributor &A) override {
12700 if (!isKnownInvariant())
12701 return ChangeStatus::UNCHANGED;
12702
12703 ChangeStatus Changed = ChangeStatus::UNCHANGED;
12704 const Value *Ptr = &getAssociatedValue();
12705 const auto TagInvariantLoads = [&](const Use &U, bool &) {
12706 if (U.get() != Ptr)
12707 return true;
12708 auto *I = dyn_cast<Instruction>(U.getUser());
12709 if (!I)
12710 return true;
12711
12712 // Ensure that we are only changing uses from the corresponding callgraph
12713 // SSC in the case that the AA isn't run on the entire module
12714 if (!A.isRunOn(I->getFunction()))
12715 return true;
12716
12717 if (I->hasMetadata(LLVMContext::MD_invariant_load))
12718 return true;
12719
12720 if (auto *LI = dyn_cast<LoadInst>(I)) {
12721 LI->setMetadata(LLVMContext::MD_invariant_load,
12722 MDNode::get(LI->getContext(), {}));
12723 Changed = ChangeStatus::CHANGED;
12724 }
12725 return true;
12726 };
12727
12728 (void)A.checkForAllUses(TagInvariantLoads, *this, *Ptr);
12729 return Changed;
12730 }
12731
12732 /// See AbstractAttribute::getAsStr().
12733 const std::string getAsStr(Attributor *) const override {
12734 if (isKnownInvariant())
12735 return "load-invariant pointer";
12736 return "non-invariant pointer";
12737 }
12738
12739 /// See AbstractAttribute::trackStatistics().
12740 void trackStatistics() const override {}
12741
12742private:
12743 /// Indicate that noalias is required for the pointer to be invariant.
12744 bool requiresNoAlias() const {
12745 switch (getPositionKind()) {
12746 default:
12747 // Conservatively default to require noalias.
12748 return true;
12749 case IRP_FLOAT:
12750 case IRP_RETURNED:
12751 case IRP_CALL_SITE:
12752 return false;
12753 case IRP_CALL_SITE_RETURNED: {
12754 const auto &CB = cast<CallBase>(getAnchorValue());
12756 &CB, /*MustPreserveOffset=*/false);
12757 }
12758 case IRP_ARGUMENT: {
12759 const Function *F = getAssociatedFunction();
12760 assert(F && "no associated function for argument");
12761 return !isCallableCC(F->getCallingConv());
12762 }
12763 }
12764 }
12765
12766 bool isExternal() const {
12767 const Function *F = getAssociatedFunction();
12768 if (!F)
12769 return true;
12770 return isCallableCC(F->getCallingConv()) &&
12771 getPositionKind() != IRP_CALL_SITE_RETURNED;
12772 }
12773
12774 ChangeStatus updateNoAlias(Attributor &A) {
12775 if (isKnown(IS_NOALIAS) || !isAssumed(IS_NOALIAS))
12776 return ChangeStatus::UNCHANGED;
12777
12778 // Try to use AANoAlias.
12779 if (const auto *ANoAlias = A.getOrCreateAAFor<AANoAlias>(
12780 getIRPosition(), this, DepClassTy::REQUIRED)) {
12781 if (ANoAlias->isKnownNoAlias()) {
12782 addKnownBits(IS_NOALIAS);
12783 return ChangeStatus::CHANGED;
12784 }
12785
12786 if (!ANoAlias->isAssumedNoAlias()) {
12787 removeAssumedBits(IS_NOALIAS);
12788 return ChangeStatus::CHANGED;
12789 }
12790
12791 return ChangeStatus::UNCHANGED;
12792 }
12793
12794 // Try to infer noalias from argument attribute, since it is applicable for
12795 // the duration of the function.
12796 if (const Argument *Arg = getAssociatedArgument()) {
12797 if (Arg->hasNoAliasAttr()) {
12798 addKnownBits(IS_NOALIAS);
12799 return ChangeStatus::UNCHANGED;
12800 }
12801
12802 // Noalias information is not provided, and cannot be inferred,
12803 // so we conservatively assume the pointer aliases.
12804 removeAssumedBits(IS_NOALIAS);
12805 return ChangeStatus::CHANGED;
12806 }
12807
12808 return ChangeStatus::UNCHANGED;
12809 }
12810
12811 ChangeStatus updateNoEffect(Attributor &A) {
12812 if (isKnown(IS_NOEFFECT) || !isAssumed(IS_NOEFFECT))
12813 return ChangeStatus::UNCHANGED;
12814
12815 if (!getAssociatedFunction())
12816 return indicatePessimisticFixpoint();
12817
12818 if (isa<AllocaInst>(&getAssociatedValue()))
12819 return indicatePessimisticFixpoint();
12820
12821 const auto HasNoEffectLoads = [&](const Use &U, bool &) {
12822 const auto *LI = dyn_cast<LoadInst>(U.getUser());
12823 return !LI || !LI->mayHaveSideEffects();
12824 };
12825 if (!A.checkForAllUses(HasNoEffectLoads, *this, getAssociatedValue()))
12826 return indicatePessimisticFixpoint();
12827
12828 if (const auto *AMemoryBehavior = A.getOrCreateAAFor<AAMemoryBehavior>(
12829 getIRPosition(), this, DepClassTy::REQUIRED)) {
12830 // For non-instructions, try to use AAMemoryBehavior to infer the readonly
12831 // attribute
12832 if (!AMemoryBehavior->isAssumedReadOnly())
12833 return indicatePessimisticFixpoint();
12834
12835 if (AMemoryBehavior->isKnownReadOnly()) {
12836 addKnownBits(IS_NOEFFECT);
12837 return ChangeStatus::UNCHANGED;
12838 }
12839
12840 return ChangeStatus::UNCHANGED;
12841 }
12842
12843 if (const Argument *Arg = getAssociatedArgument()) {
12844 if (Arg->onlyReadsMemory()) {
12845 addKnownBits(IS_NOEFFECT);
12846 return ChangeStatus::UNCHANGED;
12847 }
12848
12849 // Readonly information is not provided, and cannot be inferred from
12850 // AAMemoryBehavior.
12851 return indicatePessimisticFixpoint();
12852 }
12853
12854 return ChangeStatus::UNCHANGED;
12855 }
12856
12857 ChangeStatus updateLocalInvariance(Attributor &A) {
12858 if (isKnown(IS_LOCALLY_INVARIANT) || !isAssumed(IS_LOCALLY_INVARIANT))
12859 return ChangeStatus::UNCHANGED;
12860
12861 // try to infer invariance from underlying objects
12862 const auto *AUO = A.getOrCreateAAFor<AAUnderlyingObjects>(
12863 getIRPosition(), this, DepClassTy::REQUIRED);
12864 if (!AUO)
12865 return ChangeStatus::UNCHANGED;
12866
12867 bool UsedAssumedInformation = false;
12868 const auto IsLocallyInvariantLoadIfPointer = [&](const Value &V) {
12869 if (!V.getType()->isPointerTy())
12870 return true;
12871 const auto *IsInvariantLoadPointer =
12872 A.getOrCreateAAFor<AAInvariantLoadPointer>(IRPosition::value(V), this,
12873 DepClassTy::REQUIRED);
12874 // Conservatively fail if invariance cannot be inferred.
12875 if (!IsInvariantLoadPointer)
12876 return false;
12877
12878 if (IsInvariantLoadPointer->isKnownLocallyInvariant())
12879 return true;
12880 if (!IsInvariantLoadPointer->isAssumedLocallyInvariant())
12881 return false;
12882
12883 UsedAssumedInformation = true;
12884 return true;
12885 };
12886 if (!AUO->forallUnderlyingObjects(IsLocallyInvariantLoadIfPointer))
12887 return indicatePessimisticFixpoint();
12888
12889 if (const auto *CB = dyn_cast<CallBase>(&getAnchorValue())) {
12891 CB, /*MustPreserveOffset=*/false)) {
12892 for (const Value *Arg : CB->args()) {
12893 if (!IsLocallyInvariantLoadIfPointer(*Arg))
12894 return indicatePessimisticFixpoint();
12895 }
12896 }
12897 }
12898
12899 if (!UsedAssumedInformation) {
12900 // Pointer is known and not just assumed to be locally invariant.
12901 addKnownBits(IS_LOCALLY_INVARIANT);
12902 return ChangeStatus::CHANGED;
12903 }
12904
12905 return ChangeStatus::UNCHANGED;
12906 }
12907};
12908
12909struct AAInvariantLoadPointerFloating final : AAInvariantLoadPointerImpl {
12910 AAInvariantLoadPointerFloating(const IRPosition &IRP, Attributor &A)
12911 : AAInvariantLoadPointerImpl(IRP, A) {}
12912};
12913
12914struct AAInvariantLoadPointerReturned final : AAInvariantLoadPointerImpl {
12915 AAInvariantLoadPointerReturned(const IRPosition &IRP, Attributor &A)
12916 : AAInvariantLoadPointerImpl(IRP, A) {}
12917
12918 void initialize(Attributor &) override {
12919 removeAssumedBits(IS_LOCALLY_CONSTRAINED);
12920 }
12921};
12922
12923struct AAInvariantLoadPointerCallSiteReturned final
12924 : AAInvariantLoadPointerImpl {
12925 AAInvariantLoadPointerCallSiteReturned(const IRPosition &IRP, Attributor &A)
12926 : AAInvariantLoadPointerImpl(IRP, A) {}
12927
12928 void initialize(Attributor &A) override {
12929 const Function *F = getAssociatedFunction();
12930 assert(F && "no associated function for return from call");
12931
12932 if (!F->isDeclaration() && !F->isIntrinsic())
12933 return AAInvariantLoadPointerImpl::initialize(A);
12934
12935 const auto &CB = cast<CallBase>(getAnchorValue());
12937 &CB, /*MustPreserveOffset=*/false))
12938 return AAInvariantLoadPointerImpl::initialize(A);
12939
12940 if (F->onlyReadsMemory() && F->hasNoSync())
12941 return AAInvariantLoadPointerImpl::initialize(A);
12942
12943 // At this point, the function is opaque, so we conservatively assume
12944 // non-invariance.
12945 indicatePessimisticFixpoint();
12946 }
12947};
12948
12949struct AAInvariantLoadPointerArgument final : AAInvariantLoadPointerImpl {
12950 AAInvariantLoadPointerArgument(const IRPosition &IRP, Attributor &A)
12951 : AAInvariantLoadPointerImpl(IRP, A) {}
12952
12953 void initialize(Attributor &) override {
12954 const Function *F = getAssociatedFunction();
12955 assert(F && "no associated function for argument");
12956
12957 if (!isCallableCC(F->getCallingConv())) {
12958 addKnownBits(IS_LOCALLY_CONSTRAINED);
12959 return;
12960 }
12961
12962 if (!F->hasLocalLinkage())
12963 removeAssumedBits(IS_LOCALLY_CONSTRAINED);
12964 }
12965};
12966
12967struct AAInvariantLoadPointerCallSiteArgument final
12968 : AAInvariantLoadPointerImpl {
12969 AAInvariantLoadPointerCallSiteArgument(const IRPosition &IRP, Attributor &A)
12970 : AAInvariantLoadPointerImpl(IRP, A) {}
12971};
12972} // namespace
12973
12974/// ------------------------ Address Space ------------------------------------
12975namespace {
12976
12977template <typename InstType>
12978static bool makeChange(Attributor &A, InstType *MemInst, const Use &U,
12979 Value *OriginalValue, PointerType *NewPtrTy,
12980 bool UseOriginalValue) {
12981 if (U.getOperandNo() != InstType::getPointerOperandIndex())
12982 return false;
12983
12984 if (MemInst->isVolatile()) {
12985 auto *TTI = A.getInfoCache().getAnalysisResultForFunction<TargetIRAnalysis>(
12986 *MemInst->getFunction());
12987 unsigned NewAS = NewPtrTy->getPointerAddressSpace();
12988 if (!TTI || !TTI->hasVolatileVariant(MemInst, NewAS))
12989 return false;
12990 }
12991
12992 if (UseOriginalValue) {
12993 A.changeUseAfterManifest(const_cast<Use &>(U), *OriginalValue);
12994 return true;
12995 }
12996
12997 Instruction *CastInst = new AddrSpaceCastInst(OriginalValue, NewPtrTy);
12998 CastInst->insertBefore(MemInst->getIterator());
12999 A.changeUseAfterManifest(const_cast<Use &>(U), *CastInst);
13000 return true;
13001}
13002
13003struct AAAddressSpaceImpl : public AAAddressSpace {
13004 AAAddressSpaceImpl(const IRPosition &IRP, Attributor &A)
13005 : AAAddressSpace(IRP, A) {}
13006
13007 uint32_t getAddressSpace() const override {
13008 assert(isValidState() && "the AA is invalid");
13009 return AssumedAddressSpace;
13010 }
13011
13012 /// See AbstractAttribute::initialize(...).
13013 void initialize(Attributor &A) override {
13014 assert(getAssociatedType()->isPtrOrPtrVectorTy() &&
13015 "Associated value is not a pointer");
13016
13017 if (!A.getInfoCache().getFlatAddressSpace().has_value()) {
13018 indicatePessimisticFixpoint();
13019 return;
13020 }
13021
13022 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13023 unsigned AS = getAssociatedType()->getPointerAddressSpace();
13024 if (AS != FlatAS) {
13025 [[maybe_unused]] bool R = takeAddressSpace(AS);
13026 assert(R && "The take should happen");
13027 indicateOptimisticFixpoint();
13028 }
13029 }
13030
13031 ChangeStatus updateImpl(Attributor &A) override {
13032 uint32_t OldAddressSpace = AssumedAddressSpace;
13033 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13034
13035 auto CheckAddressSpace = [&](Value &Obj) {
13036 // Ignore undef.
13037 if (isa<UndefValue>(&Obj))
13038 return true;
13039
13040 // If the object already has a non-flat address space, we simply take it.
13041 unsigned ObjAS = Obj.getType()->getPointerAddressSpace();
13042 if (ObjAS != FlatAS)
13043 return takeAddressSpace(ObjAS);
13044
13045 // At this point, we know Obj is in the flat address space. For a final
13046 // attempt, we want to use getAssumedAddrSpace, but first we must get the
13047 // associated function, if possible.
13048 Function *F = nullptr;
13049 if (auto *Arg = dyn_cast<Argument>(&Obj))
13050 F = Arg->getParent();
13051 else if (auto *I = dyn_cast<Instruction>(&Obj))
13052 F = I->getFunction();
13053
13054 // Use getAssumedAddrSpace if the associated function exists.
13055 if (F) {
13056 auto *TTI =
13057 A.getInfoCache().getAnalysisResultForFunction<TargetIRAnalysis>(*F);
13058 unsigned AssumedAS = TTI->getAssumedAddrSpace(&Obj);
13059 if (AssumedAS != ~0U)
13060 return takeAddressSpace(AssumedAS);
13061 }
13062
13063 // Now we can't do anything else but to take the flat AS.
13064 return takeAddressSpace(FlatAS);
13065 };
13066
13067 auto *AUO = A.getOrCreateAAFor<AAUnderlyingObjects>(getIRPosition(), this,
13068 DepClassTy::REQUIRED);
13069 if (!AUO->forallUnderlyingObjects(CheckAddressSpace))
13070 return indicatePessimisticFixpoint();
13071
13072 return OldAddressSpace == AssumedAddressSpace ? ChangeStatus::UNCHANGED
13073 : ChangeStatus::CHANGED;
13074 }
13075
13076 /// See AbstractAttribute::manifest(...).
13077 ChangeStatus manifest(Attributor &A) override {
13078 unsigned NewAS = getAddressSpace();
13079
13080 if (NewAS == InvalidAddressSpace ||
13081 NewAS == getAssociatedType()->getPointerAddressSpace())
13082 return ChangeStatus::UNCHANGED;
13083
13084 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13085
13086 Value *AssociatedValue = &getAssociatedValue();
13087 Value *OriginalValue = peelAddrspacecast(AssociatedValue, FlatAS);
13088
13089 PointerType *NewPtrTy =
13090 PointerType::get(getAssociatedType()->getContext(), NewAS);
13091 bool UseOriginalValue =
13092 OriginalValue->getType()->getPointerAddressSpace() == NewAS;
13093
13094 bool Changed = false;
13095
13096 auto Pred = [&](const Use &U, bool &) {
13097 if (U.get() != AssociatedValue)
13098 return true;
13099 auto *Inst = dyn_cast<Instruction>(U.getUser());
13100 if (!Inst)
13101 return true;
13102 // This is a WA to make sure we only change uses from the corresponding
13103 // CGSCC if the AA is run on CGSCC instead of the entire module.
13104 if (!A.isRunOn(Inst->getFunction()))
13105 return true;
13106 if (auto *LI = dyn_cast<LoadInst>(Inst)) {
13107 Changed |=
13108 makeChange(A, LI, U, OriginalValue, NewPtrTy, UseOriginalValue);
13109 } else if (auto *SI = dyn_cast<StoreInst>(Inst)) {
13110 Changed |=
13111 makeChange(A, SI, U, OriginalValue, NewPtrTy, UseOriginalValue);
13112 } else if (auto *RMW = dyn_cast<AtomicRMWInst>(Inst)) {
13113 Changed |=
13114 makeChange(A, RMW, U, OriginalValue, NewPtrTy, UseOriginalValue);
13115 } else if (auto *CmpX = dyn_cast<AtomicCmpXchgInst>(Inst)) {
13116 Changed |=
13117 makeChange(A, CmpX, U, OriginalValue, NewPtrTy, UseOriginalValue);
13118 }
13119 return true;
13120 };
13121
13122 // It doesn't matter if we can't check all uses as we can simply
13123 // conservatively ignore those that can not be visited.
13124 (void)A.checkForAllUses(Pred, *this, getAssociatedValue(),
13125 /* CheckBBLivenessOnly */ true);
13126
13127 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
13128 }
13129
13130 /// See AbstractAttribute::getAsStr().
13131 const std::string getAsStr(Attributor *A) const override {
13132 if (!isValidState())
13133 return "addrspace(<invalid>)";
13134 return "addrspace(" +
13135 (AssumedAddressSpace == InvalidAddressSpace
13136 ? "none"
13137 : std::to_string(AssumedAddressSpace)) +
13138 ")";
13139 }
13140
13141private:
13142 uint32_t AssumedAddressSpace = InvalidAddressSpace;
13143
13144 bool takeAddressSpace(uint32_t AS) {
13145 if (AssumedAddressSpace == InvalidAddressSpace) {
13146 AssumedAddressSpace = AS;
13147 return true;
13148 }
13149 return AssumedAddressSpace == AS;
13150 }
13151
13152 static Value *peelAddrspacecast(Value *V, unsigned FlatAS) {
13153 if (auto *I = dyn_cast<AddrSpaceCastInst>(V)) {
13154 assert(I->getSrcAddressSpace() != FlatAS &&
13155 "there should not be flat AS -> non-flat AS");
13156 return I->getPointerOperand();
13157 }
13158 if (auto *C = dyn_cast<ConstantExpr>(V))
13159 if (C->getOpcode() == Instruction::AddrSpaceCast) {
13160 assert(C->getOperand(0)->getType()->getPointerAddressSpace() !=
13161 FlatAS &&
13162 "there should not be flat AS -> non-flat AS X");
13163 return C->getOperand(0);
13164 }
13165 return V;
13166 }
13167};
13168
13169struct AAAddressSpaceFloating final : AAAddressSpaceImpl {
13170 AAAddressSpaceFloating(const IRPosition &IRP, Attributor &A)
13171 : AAAddressSpaceImpl(IRP, A) {}
13172
13173 void trackStatistics() const override {
13175 }
13176};
13177
13178struct AAAddressSpaceReturned final : AAAddressSpaceImpl {
13179 AAAddressSpaceReturned(const IRPosition &IRP, Attributor &A)
13180 : AAAddressSpaceImpl(IRP, A) {}
13181
13182 /// See AbstractAttribute::initialize(...).
13183 void initialize(Attributor &A) override {
13184 // TODO: we don't rewrite function argument for now because it will need to
13185 // rewrite the function signature and all call sites.
13186 (void)indicatePessimisticFixpoint();
13187 }
13188
13189 void trackStatistics() const override {
13190 STATS_DECLTRACK_FNRET_ATTR(addrspace);
13191 }
13192};
13193
13194struct AAAddressSpaceCallSiteReturned final : AAAddressSpaceImpl {
13195 AAAddressSpaceCallSiteReturned(const IRPosition &IRP, Attributor &A)
13196 : AAAddressSpaceImpl(IRP, A) {}
13197
13198 void trackStatistics() const override {
13199 STATS_DECLTRACK_CSRET_ATTR(addrspace);
13200 }
13201};
13202
13203struct AAAddressSpaceArgument final : AAAddressSpaceImpl {
13204 AAAddressSpaceArgument(const IRPosition &IRP, Attributor &A)
13205 : AAAddressSpaceImpl(IRP, A) {}
13206
13207 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(addrspace); }
13208};
13209
13210struct AAAddressSpaceCallSiteArgument final : AAAddressSpaceImpl {
13211 AAAddressSpaceCallSiteArgument(const IRPosition &IRP, Attributor &A)
13212 : AAAddressSpaceImpl(IRP, A) {}
13213
13214 /// See AbstractAttribute::initialize(...).
13215 void initialize(Attributor &A) override {
13216 // TODO: we don't rewrite call site argument for now because it will need to
13217 // rewrite the function signature of the callee.
13218 (void)indicatePessimisticFixpoint();
13219 }
13220
13221 void trackStatistics() const override {
13222 STATS_DECLTRACK_CSARG_ATTR(addrspace);
13223 }
13224};
13225} // namespace
13226
13227/// ------------------------ No Alias Address Space ---------------------------
13228// This attribute assumes flat address space can alias all other address space
13229
13230// TODO: this is similar to AAAddressSpace, most of the code should be merged.
13231// But merging it created failing cased on gateway test that cannot be
13232// reproduced locally. So should open a separated PR to handle the merge of
13233// AANoAliasAddrSpace and AAAddressSpace attribute
13234
13235namespace {
13236struct AANoAliasAddrSpaceImpl : public AANoAliasAddrSpace {
13237 AANoAliasAddrSpaceImpl(const IRPosition &IRP, Attributor &A)
13238 : AANoAliasAddrSpace(IRP, A) {}
13239
13240 void initialize(Attributor &A) override {
13241 assert(getAssociatedType()->isPtrOrPtrVectorTy() &&
13242 "Associated value is not a pointer");
13243
13244 resetASRanges(A);
13245
13246 std::optional<unsigned> FlatAS = A.getInfoCache().getFlatAddressSpace();
13247 if (!FlatAS.has_value()) {
13248 indicatePessimisticFixpoint();
13249 return;
13250 }
13251
13252 removeAS(*FlatAS);
13253
13254 unsigned AS = getAssociatedType()->getPointerAddressSpace();
13255 if (AS != *FlatAS) {
13256 removeAS(AS);
13257 indicateOptimisticFixpoint();
13258 }
13259 }
13260
13261 ChangeStatus updateImpl(Attributor &A) override {
13262 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13263 uint32_t OldAssumed = getAssumed();
13264
13265 auto CheckAddressSpace = [&](Value &Obj) {
13266 if (isa<PoisonValue>(&Obj))
13267 return true;
13268
13269 unsigned AS = Obj.getType()->getPointerAddressSpace();
13270 if (AS == FlatAS)
13271 return false;
13272
13273 removeAS(Obj.getType()->getPointerAddressSpace());
13274 return true;
13275 };
13276
13277 const AAUnderlyingObjects *AUO = A.getOrCreateAAFor<AAUnderlyingObjects>(
13278 getIRPosition(), this, DepClassTy::REQUIRED);
13279 if (!AUO->forallUnderlyingObjects(CheckAddressSpace))
13280 return indicatePessimisticFixpoint();
13281
13282 return OldAssumed == getAssumed() ? ChangeStatus::UNCHANGED
13283 : ChangeStatus::CHANGED;
13284 }
13285
13286 /// See AbstractAttribute::manifest(...).
13287 ChangeStatus manifest(Attributor &A) override {
13288 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13289
13290 unsigned AS = getAssociatedType()->getPointerAddressSpace();
13291 if (AS != FlatAS || Map.empty())
13292 return ChangeStatus::UNCHANGED;
13293
13294 LLVMContext &Ctx = getAssociatedValue().getContext();
13295 MDNode *NoAliasASNode = nullptr;
13296 MDBuilder MDB(Ctx);
13297 // Has to use iterator to get the range info.
13298 for (RangeMap::const_iterator I = Map.begin(); I != Map.end(); I++) {
13299 if (!I.value())
13300 continue;
13301 unsigned Upper = I.stop();
13302 unsigned Lower = I.start();
13303 if (!NoAliasASNode) {
13304 NoAliasASNode = MDB.createRange(APInt(32, Lower), APInt(32, Upper + 1));
13305 continue;
13306 }
13307 MDNode *ASRange = MDB.createRange(APInt(32, Lower), APInt(32, Upper + 1));
13308 NoAliasASNode = MDNode::getMostGenericRange(NoAliasASNode, ASRange);
13309 }
13310
13311 Value *AssociatedValue = &getAssociatedValue();
13312 bool Changed = false;
13313
13314 auto AddNoAliasAttr = [&](const Use &U, bool &) {
13315 if (U.get() != AssociatedValue)
13316 return true;
13317 Instruction *Inst = dyn_cast<Instruction>(U.getUser());
13318 if (!Inst || Inst->hasMetadata(LLVMContext::MD_noalias_addrspace))
13319 return true;
13320 if (!isa<LoadInst>(Inst) && !isa<StoreInst>(Inst) &&
13322 return true;
13323 if (!A.isRunOn(Inst->getFunction()))
13324 return true;
13325 Inst->setMetadata(LLVMContext::MD_noalias_addrspace, NoAliasASNode);
13326 Changed = true;
13327 return true;
13328 };
13329 (void)A.checkForAllUses(AddNoAliasAttr, *this, *AssociatedValue,
13330 /*CheckBBLivenessOnly=*/true);
13331 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
13332 }
13333
13334 /// See AbstractAttribute::getAsStr().
13335 const std::string getAsStr(Attributor *A) const override {
13336 if (!isValidState())
13337 return "<invalid>";
13338 std::string Str;
13339 raw_string_ostream OS(Str);
13340 OS << "CanNotBeAddrSpace(";
13341 for (RangeMap::const_iterator I = Map.begin(); I != Map.end(); I++) {
13342 unsigned Upper = I.stop();
13343 unsigned Lower = I.start();
13344 OS << ' ' << '[' << Upper << ',' << Lower + 1 << ')';
13345 }
13346 OS << " )";
13347 return OS.str();
13348 }
13349
13350private:
13351 void removeAS(unsigned AS) {
13352 RangeMap::iterator I = Map.find(AS);
13353
13354 if (I != Map.end()) {
13355 unsigned Upper = I.stop();
13356 unsigned Lower = I.start();
13357 I.erase();
13358 if (Upper == Lower)
13359 return;
13360 if (AS != ~((unsigned)0) && AS + 1 <= Upper)
13361 Map.insert(AS + 1, Upper, /*what ever this variable name is=*/true);
13362 if (AS != 0 && Lower <= AS - 1)
13363 Map.insert(Lower, AS - 1, true);
13364 }
13365 }
13366
13367 void resetASRanges(Attributor &A) {
13368 Map.clear();
13369 Map.insert(0, A.getInfoCache().getMaxAddrSpace(), true);
13370 }
13371};
13372
13373struct AANoAliasAddrSpaceFloating final : AANoAliasAddrSpaceImpl {
13374 AANoAliasAddrSpaceFloating(const IRPosition &IRP, Attributor &A)
13375 : AANoAliasAddrSpaceImpl(IRP, A) {}
13376
13377 void trackStatistics() const override {
13378 STATS_DECLTRACK_FLOATING_ATTR(noaliasaddrspace);
13379 }
13380};
13381
13382struct AANoAliasAddrSpaceReturned final : AANoAliasAddrSpaceImpl {
13383 AANoAliasAddrSpaceReturned(const IRPosition &IRP, Attributor &A)
13384 : AANoAliasAddrSpaceImpl(IRP, A) {}
13385
13386 void trackStatistics() const override {
13387 STATS_DECLTRACK_FNRET_ATTR(noaliasaddrspace);
13388 }
13389};
13390
13391struct AANoAliasAddrSpaceCallSiteReturned final : AANoAliasAddrSpaceImpl {
13392 AANoAliasAddrSpaceCallSiteReturned(const IRPosition &IRP, Attributor &A)
13393 : AANoAliasAddrSpaceImpl(IRP, A) {}
13394
13395 void trackStatistics() const override {
13396 STATS_DECLTRACK_CSRET_ATTR(noaliasaddrspace);
13397 }
13398};
13399
13400struct AANoAliasAddrSpaceArgument final : AANoAliasAddrSpaceImpl {
13401 AANoAliasAddrSpaceArgument(const IRPosition &IRP, Attributor &A)
13402 : AANoAliasAddrSpaceImpl(IRP, A) {}
13403
13404 void trackStatistics() const override {
13405 STATS_DECLTRACK_ARG_ATTR(noaliasaddrspace);
13406 }
13407};
13408
13409struct AANoAliasAddrSpaceCallSiteArgument final : AANoAliasAddrSpaceImpl {
13410 AANoAliasAddrSpaceCallSiteArgument(const IRPosition &IRP, Attributor &A)
13411 : AANoAliasAddrSpaceImpl(IRP, A) {}
13412
13413 void trackStatistics() const override {
13414 STATS_DECLTRACK_CSARG_ATTR(noaliasaddrspace);
13415 }
13416};
13417} // namespace
13418/// ----------- Allocation Info ----------
13419namespace {
13420struct AAAllocationInfoImpl : public AAAllocationInfo {
13421 AAAllocationInfoImpl(const IRPosition &IRP, Attributor &A)
13422 : AAAllocationInfo(IRP, A) {}
13423
13424 std::optional<TypeSize> getAllocatedSize() const override {
13425 assert(isValidState() && "the AA is invalid");
13426 return AssumedAllocatedSize;
13427 }
13428
13429 std::optional<TypeSize> findInitialAllocationSize(Instruction *I,
13430 const DataLayout &DL) {
13431
13432 // TODO: implement case for malloc like instructions
13433 switch (I->getOpcode()) {
13434 case Instruction::Alloca: {
13435 AllocaInst *AI = cast<AllocaInst>(I);
13436 return AI->getAllocationSize(DL);
13437 }
13438 default:
13439 return std::nullopt;
13440 }
13441 }
13442
13443 ChangeStatus updateImpl(Attributor &A) override {
13444
13445 const IRPosition &IRP = getIRPosition();
13446 Instruction *I = IRP.getCtxI();
13447
13448 // TODO: update check for malloc like calls
13449 if (!isa<AllocaInst>(I))
13450 return indicatePessimisticFixpoint();
13451
13452 bool IsKnownNoCapture;
13454 A, this, IRP, DepClassTy::OPTIONAL, IsKnownNoCapture))
13455 return indicatePessimisticFixpoint();
13456
13457 const AAPointerInfo *PI =
13458 A.getOrCreateAAFor<AAPointerInfo>(IRP, *this, DepClassTy::REQUIRED);
13459
13460 if (!PI)
13461 return indicatePessimisticFixpoint();
13462
13463 if (!PI->getState().isValidState() || PI->reachesReturn())
13464 return indicatePessimisticFixpoint();
13465
13466 const DataLayout &DL = A.getDataLayout();
13467 const auto AllocationSize = findInitialAllocationSize(I, DL);
13468
13469 // If allocation size is nullopt, we give up.
13470 if (!AllocationSize)
13471 return indicatePessimisticFixpoint();
13472
13473 // For zero sized allocations, we give up.
13474 // Since we can't reduce further
13475 if (*AllocationSize == 0)
13476 return indicatePessimisticFixpoint();
13477
13478 int64_t BinSize = PI->numOffsetBins();
13479
13480 // TODO: implement for multiple bins
13481 if (BinSize > 1)
13482 return indicatePessimisticFixpoint();
13483
13484 if (BinSize == 0) {
13485 auto NewAllocationSize = std::make_optional<TypeSize>(0, false);
13486 if (!changeAllocationSize(NewAllocationSize))
13487 return ChangeStatus::UNCHANGED;
13488 return ChangeStatus::CHANGED;
13489 }
13490
13491 // TODO: refactor this to be part of multiple bin case
13492 const auto &It = PI->begin();
13493
13494 // TODO: handle if Offset is not zero
13495 if (It->first.Offset != 0)
13496 return indicatePessimisticFixpoint();
13497
13498 uint64_t SizeOfBin = It->first.Offset + It->first.Size;
13499
13500 if (SizeOfBin >= *AllocationSize)
13501 return indicatePessimisticFixpoint();
13502
13503 auto NewAllocationSize = std::make_optional<TypeSize>(SizeOfBin * 8, false);
13504
13505 if (!changeAllocationSize(NewAllocationSize))
13506 return ChangeStatus::UNCHANGED;
13507
13508 return ChangeStatus::CHANGED;
13509 }
13510
13511 /// See AbstractAttribute::manifest(...).
13512 ChangeStatus manifest(Attributor &A) override {
13513
13514 assert(isValidState() &&
13515 "Manifest should only be called if the state is valid.");
13516
13517 Instruction *I = getIRPosition().getCtxI();
13518
13519 auto FixedAllocatedSizeInBits = getAllocatedSize()->getFixedValue();
13520
13521 unsigned long NumBytesToAllocate = (FixedAllocatedSizeInBits + 7) / 8;
13522
13523 switch (I->getOpcode()) {
13524 // TODO: add case for malloc like calls
13525 case Instruction::Alloca: {
13526
13527 AllocaInst *AI = cast<AllocaInst>(I);
13528
13529 Type *CharType = Type::getInt8Ty(I->getContext());
13530
13531 auto *NumBytesToValue =
13532 ConstantInt::get(I->getContext(), APInt(32, NumBytesToAllocate));
13533
13534 BasicBlock::iterator insertPt = AI->getIterator();
13535 insertPt = std::next(insertPt);
13536 AllocaInst *NewAllocaInst =
13537 new AllocaInst(CharType, AI->getAddressSpace(), NumBytesToValue,
13538 AI->getAlign(), AI->getName(), insertPt);
13539
13540 if (A.changeAfterManifest(IRPosition::inst(*AI), *NewAllocaInst))
13541 return ChangeStatus::CHANGED;
13542
13543 break;
13544 }
13545 default:
13546 break;
13547 }
13548
13549 return ChangeStatus::UNCHANGED;
13550 }
13551
13552 /// See AbstractAttribute::getAsStr().
13553 const std::string getAsStr(Attributor *A) const override {
13554 if (!isValidState())
13555 return "allocationinfo(<invalid>)";
13556 return "allocationinfo(" +
13557 (AssumedAllocatedSize == HasNoAllocationSize
13558 ? "none"
13559 : std::to_string(AssumedAllocatedSize->getFixedValue())) +
13560 ")";
13561 }
13562
13563private:
13564 std::optional<TypeSize> AssumedAllocatedSize = HasNoAllocationSize;
13565
13566 // Maintain the computed allocation size of the object.
13567 // Returns (bool) weather the size of the allocation was modified or not.
13568 bool changeAllocationSize(std::optional<TypeSize> Size) {
13569 if (AssumedAllocatedSize == HasNoAllocationSize ||
13570 AssumedAllocatedSize != Size) {
13571 AssumedAllocatedSize = Size;
13572 return true;
13573 }
13574 return false;
13575 }
13576};
13577
13578struct AAAllocationInfoFloating : AAAllocationInfoImpl {
13579 AAAllocationInfoFloating(const IRPosition &IRP, Attributor &A)
13580 : AAAllocationInfoImpl(IRP, A) {}
13581
13582 void trackStatistics() const override {
13583 STATS_DECLTRACK_FLOATING_ATTR(allocationinfo);
13584 }
13585};
13586
13587struct AAAllocationInfoReturned : AAAllocationInfoImpl {
13588 AAAllocationInfoReturned(const IRPosition &IRP, Attributor &A)
13589 : AAAllocationInfoImpl(IRP, A) {}
13590
13591 /// See AbstractAttribute::initialize(...).
13592 void initialize(Attributor &A) override {
13593 // TODO: we don't rewrite function argument for now because it will need to
13594 // rewrite the function signature and all call sites
13595 (void)indicatePessimisticFixpoint();
13596 }
13597
13598 void trackStatistics() const override {
13599 STATS_DECLTRACK_FNRET_ATTR(allocationinfo);
13600 }
13601};
13602
13603struct AAAllocationInfoCallSiteReturned : AAAllocationInfoImpl {
13604 AAAllocationInfoCallSiteReturned(const IRPosition &IRP, Attributor &A)
13605 : AAAllocationInfoImpl(IRP, A) {}
13606
13607 void trackStatistics() const override {
13608 STATS_DECLTRACK_CSRET_ATTR(allocationinfo);
13609 }
13610};
13611
13612struct AAAllocationInfoArgument : AAAllocationInfoImpl {
13613 AAAllocationInfoArgument(const IRPosition &IRP, Attributor &A)
13614 : AAAllocationInfoImpl(IRP, A) {}
13615
13616 void trackStatistics() const override {
13617 STATS_DECLTRACK_ARG_ATTR(allocationinfo);
13618 }
13619};
13620
13621struct AAAllocationInfoCallSiteArgument : AAAllocationInfoImpl {
13622 AAAllocationInfoCallSiteArgument(const IRPosition &IRP, Attributor &A)
13623 : AAAllocationInfoImpl(IRP, A) {}
13624
13625 /// See AbstractAttribute::initialize(...).
13626 void initialize(Attributor &A) override {
13627
13628 (void)indicatePessimisticFixpoint();
13629 }
13630
13631 void trackStatistics() const override {
13632 STATS_DECLTRACK_CSARG_ATTR(allocationinfo);
13633 }
13634};
13635} // namespace
13636
13637const char AANoUnwind::ID = 0;
13638const char AANoSync::ID = 0;
13639const char AANoFree::ID = 0;
13640const char AANonNull::ID = 0;
13641const char AAMustProgress::ID = 0;
13642const char AANoRecurse::ID = 0;
13643const char AANonConvergent::ID = 0;
13644const char AAWillReturn::ID = 0;
13645const char AAUndefinedBehavior::ID = 0;
13646const char AANoAlias::ID = 0;
13647const char AAIntraFnReachability::ID = 0;
13648const char AANoReturn::ID = 0;
13649const char AAIsDead::ID = 0;
13650const char AADereferenceable::ID = 0;
13651const char AAAlign::ID = 0;
13652const char AAInstanceInfo::ID = 0;
13653const char AANoCapture::ID = 0;
13654const char AAValueSimplify::ID = 0;
13655const char AAHeapToStack::ID = 0;
13656const char AAPrivatizablePtr::ID = 0;
13657const char AAMemoryBehavior::ID = 0;
13658const char AAMemoryLocation::ID = 0;
13659const char AAValueConstantRange::ID = 0;
13660const char AAPotentialConstantValues::ID = 0;
13661const char AAPotentialValues::ID = 0;
13662const char AANoUndef::ID = 0;
13663const char AANoFPClass::ID = 0;
13664const char AACallEdges::ID = 0;
13665const char AAInterFnReachability::ID = 0;
13666const char AAPointerInfo::ID = 0;
13667const char AAAssumptionInfo::ID = 0;
13668const char AAUnderlyingObjects::ID = 0;
13669const char AAInvariantLoadPointer::ID = 0;
13670const char AAAddressSpace::ID = 0;
13671const char AANoAliasAddrSpace::ID = 0;
13672const char AAAllocationInfo::ID = 0;
13673const char AAIndirectCallInfo::ID = 0;
13674const char AAGlobalValueInfo::ID = 0;
13675const char AADenormalFPMath::ID = 0;
13676
13677// Macro magic to create the static generator function for attributes that
13678// follow the naming scheme.
13679
13680#define SWITCH_PK_INV(CLASS, PK, POS_NAME) \
13681 case IRPosition::PK: \
13682 llvm_unreachable("Cannot create " #CLASS " for a " POS_NAME " position!");
13683
13684#define SWITCH_PK_CREATE(CLASS, IRP, PK, SUFFIX) \
13685 case IRPosition::PK: \
13686 AA = new (A.Allocator) CLASS##SUFFIX(IRP, A); \
13687 ++NumAAs; \
13688 break;
13689
13690#define CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13691 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13692 CLASS *AA = nullptr; \
13693 switch (IRP.getPositionKind()) { \
13694 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13695 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
13696 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
13697 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
13698 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
13699 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
13700 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
13701 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
13702 } \
13703 return *AA; \
13704 }
13705
13706#define CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13707 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13708 CLASS *AA = nullptr; \
13709 switch (IRP.getPositionKind()) { \
13710 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13711 SWITCH_PK_INV(CLASS, IRP_FUNCTION, "function") \
13712 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
13713 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
13714 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
13715 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
13716 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
13717 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
13718 } \
13719 return *AA; \
13720 }
13721
13722#define CREATE_ABSTRACT_ATTRIBUTE_FOR_ONE_POSITION(POS, SUFFIX, CLASS) \
13723 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13724 CLASS *AA = nullptr; \
13725 switch (IRP.getPositionKind()) { \
13726 SWITCH_PK_CREATE(CLASS, IRP, POS, SUFFIX) \
13727 default: \
13728 llvm_unreachable("Cannot create " #CLASS " for position otherthan " #POS \
13729 " position!"); \
13730 } \
13731 return *AA; \
13732 }
13733
13734#define CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13735 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13736 CLASS *AA = nullptr; \
13737 switch (IRP.getPositionKind()) { \
13738 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13739 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
13740 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
13741 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
13742 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
13743 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
13744 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
13745 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
13746 } \
13747 return *AA; \
13748 }
13749
13750#define CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13751 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13752 CLASS *AA = nullptr; \
13753 switch (IRP.getPositionKind()) { \
13754 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13755 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
13756 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
13757 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
13758 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
13759 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
13760 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
13761 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
13762 } \
13763 return *AA; \
13764 }
13765
13766#define CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13767 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13768 CLASS *AA = nullptr; \
13769 switch (IRP.getPositionKind()) { \
13770 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13771 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
13772 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
13773 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
13774 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
13775 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
13776 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
13777 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
13778 } \
13779 return *AA; \
13780 }
13781
13791
13809
13814
13819
13826
13828
13829#undef CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION
13830#undef CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION
13831#undef CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION
13832#undef CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION
13833#undef CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION
13834#undef CREATE_ABSTRACT_ATTRIBUTE_FOR_ONE_POSITION
13835#undef SWITCH_PK_CREATE
13836#undef SWITCH_PK_INV
#define Success
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
aarch64 promote const
AMDGPU Register Bank Select
Rewrite undef for PHI
This file implements a class to represent arbitrary precision integral constant values and operations...
ReachingDefInfo InstSet & ToRemove
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis false
This file contains the simple types necessary to represent the attributes associated with functions a...
#define STATS_DECLTRACK(NAME, TYPE, MSG)
static std::optional< Constant * > askForAssumedConstant(Attributor &A, const AbstractAttribute &QueryingAA, const IRPosition &IRP, Type &Ty)
static cl::opt< unsigned, true > MaxPotentialValues("attributor-max-potential-values", cl::Hidden, cl::desc("Maximum number of potential values to be " "tracked for each position."), cl::location(llvm::PotentialConstantIntValuesState::MaxPotentialValues), cl::init(7))
static void clampReturnedValueStates(Attributor &A, const AAType &QueryingAA, StateType &S, const IRPosition::CallBaseContext *CBContext=nullptr)
Clamp the information known for all returned values of a function (identified by QueryingAA) into S.
#define STATS_DECLTRACK_FN_ATTR(NAME)
#define CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
static cl::opt< int > MaxPotentialValuesIterations("attributor-max-potential-values-iterations", cl::Hidden, cl::desc("Maximum number of iterations we keep dismantling potential values."), cl::init(64))
#define STATS_DECLTRACK_CS_ATTR(NAME)
#define PIPE_OPERATOR(CLASS)
static bool mayBeInCycle(const CycleInfo *CI, const Instruction *I, bool HeaderOnly, Cycle **CPtr=nullptr)
#define STATS_DECLTRACK_ARG_ATTR(NAME)
static const Value * stripAndAccumulateOffsets(Attributor &A, const AbstractAttribute &QueryingAA, const Value *Val, const DataLayout &DL, APInt &Offset, bool GetMinOffset, bool AllowNonInbounds, bool UseAssumed=false)
#define STATS_DECLTRACK_CSRET_ATTR(NAME)
static cl::opt< bool > ManifestInternal("attributor-manifest-internal", cl::Hidden, cl::desc("Manifest Attributor internal string attributes."), cl::init(false))
static Value * constructPointer(Value *Ptr, int64_t Offset, IRBuilder< NoFolder > &IRB)
Helper function to create a pointer based on Ptr, and advanced by Offset bytes.
#define CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
#define BUILD_STAT_NAME(NAME, TYPE)
static bool isDenselyPacked(Type *Ty, const DataLayout &DL)
Checks if a type could have padding bytes.
#define CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
static const Value * getMinimalBaseOfPointer(Attributor &A, const AbstractAttribute &QueryingAA, const Value *Ptr, int64_t &BytesOffset, const DataLayout &DL, bool AllowNonInbounds=false)
#define STATS_DECLTRACK_FNRET_ATTR(NAME)
#define STATS_DECLTRACK_CSARG_ATTR(NAME)
#define CREATE_ABSTRACT_ATTRIBUTE_FOR_ONE_POSITION(POS, SUFFIX, CLASS)
#define CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
static cl::opt< int > MaxHeapToStackSize("max-heap-to-stack-size", cl::init(128), cl::Hidden)
#define CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
#define STATS_DECLTRACK_FLOATING_ATTR(NAME)
#define STATS_DECL(NAME, TYPE, MSG)
basic Basic Alias true
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static bool isReachableImpl(SmallVectorImpl< BasicBlock * > &Worklist, const StopSetT &StopSet, const SmallPtrSetImpl< BasicBlock * > *ExclusionSet, const DominatorTree *DT, const LoopInfo *LI, const CycleInfo *CI)
Definition CFG.cpp:145
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file declares an analysis pass that computes CycleInfo for LLVM IR, specialized from GenericCycl...
static uint64_t align(uint64_t Size)
DXIL Forward Handle Accesses
DXIL Resource Access
dxil translate DXIL Translate Metadata
This file defines DenseMapInfo traits for DenseMap.
#define Check(C,...)
Hexagon Common GEP
IRTranslator LLVM IR MI
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
Machine Check Debug Module
This file implements a map that provides insertion order iteration.
#define T
#define T1
static unsigned getAddressSpace(const Value *V, unsigned MaxLookup)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
uint64_t IntrinsicInst * II
if(PassOpts->AAPipeline)
static StringRef getName(Value *V)
Basic Register Allocator
dot regions Print regions of function to dot true view regions View regions of function(with no function bodies)"
Remove Loads Into Fake Uses
This builds on the llvm/ADT/GraphTraits.h file to find the strongly connected components (SCCs) of a ...
bool IsDead
std::pair< BasicBlock *, BasicBlock * > Edge
This file contains some templates that are useful if you are working with the STL at all.
BaseType
A given derived pointer can have multiple base pointers through phi/selects.
This file defines generic set operations that may be used on set's of different types,...
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition Statistic.h:171
This file contains some functions that are useful when dealing with strings.
#define LLVM_DEBUG(...)
Definition Debug.h:119
static SymbolRef::Type getType(const Symbol *Sym)
Definition TapiFile.cpp:39
static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, const llvm::StringTable &StandardNames, VectorLibrary VecLib)
Initialize the set of available library functions based on the specified target triple.
This pass exposes codegen information to IR-level passes.
static unsigned getBitWidth(Type *Ty, const DataLayout &DL)
Returns the bitwidth of the given scalar or pointer type.
Value * RHS
Value * LHS
static unsigned getSize(unsigned Kind)
LLVM_ABI AACallGraphNode * operator*() const
bool isNoAlias(const MemoryLocation &LocA, const MemoryLocation &LocB)
A trivial helper function to check to see if the specified pointers are no-alias.
Class for arbitrary precision integers.
Definition APInt.h:78
int64_t getSExtValue() const
Get sign extended value.
Definition APInt.h:1585
CallBase * getInstruction() const
Return the underlying instruction.
bool isCallbackCall() const
Return true if this ACS represents a callback call.
bool isDirectCall() const
Return true if this ACS represents a direct call.
static LLVM_ABI void getCallbackUses(const CallBase &CB, SmallVectorImpl< const Use * > &CallbackUses)
Add operand uses of CB that represent callback uses into CallbackUses.
int getCallArgOperandNo(Argument &Arg) const
Return the operand index of the underlying instruction associated with Arg.
Align getAlign() const
Return the alignment of the memory that is being allocated by the instruction.
unsigned getAddressSpace() const
Return the address space for the allocation.
LLVM_ABI std::optional< TypeSize > getAllocationSize(const DataLayout &DL) const
Get allocation size in bytes.
This class represents an incoming formal argument to a Function.
Definition Argument.h:32
LLVM_ABI bool hasNoAliasAttr() const
Return true if this argument has the noalias attribute.
Definition Function.cpp:268
LLVM_ABI bool onlyReadsMemory() const
Return true if this argument has the readonly or readnone attribute.
Definition Function.cpp:304
LLVM_ABI bool hasPointeeInMemoryValueAttr() const
Return true if this argument has the byval, sret, inalloca, preallocated, or byref attribute.
Definition Function.cpp:171
LLVM_ABI bool hasReturnedAttr() const
Return true if this argument has the returned attribute.
Definition Function.cpp:292
LLVM_ABI bool hasByValAttr() const
Return true if this argument has the byval attribute.
Definition Function.cpp:128
const Function * getParent() const
Definition Argument.h:44
unsigned getArgNo() const
Return the index of this formal argument in its containing function.
Definition Argument.h:50
A function analysis which provides an AssumptionCache.
A cache of @llvm.assume calls within a function.
Functions, function parameters, and return types can have attributes to indicate how they should be t...
Definition Attributes.h:105
static LLVM_ABI Attribute get(LLVMContext &Context, AttrKind Kind, uint64_t Val=0)
Return a uniquified Attribute object.
LLVM_ABI FPClassTest getNoFPClass() const
Return the FPClassTest for nofpclass.
LLVM_ABI Attribute::AttrKind getKindAsEnum() const
Return the attribute's kind as an enum (Attribute::AttrKind).
LLVM_ABI MemoryEffects getMemoryEffects() const
Returns memory effects.
AttrKind
This enumeration lists the attributes that can be associated with parameters, function results,...
Definition Attributes.h:124
static LLVM_ABI Attribute getWithCaptureInfo(LLVMContext &Context, CaptureInfo CI)
static bool isEnumAttrKind(AttrKind Kind)
Definition Attributes.h:137
bool isValid() const
Return true if the attribute is any kind of attribute.
Definition Attributes.h:261
LLVM_ABI CaptureInfo getCaptureInfo() const
Returns information from captures attribute.
LLVM Basic Block Representation.
Definition BasicBlock.h:62
LLVM_ABI const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
const Function * getParent() const
Return the enclosing method, or null if none.
Definition BasicBlock.h:213
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition BasicBlock.h:206
const Instruction & front() const
Definition BasicBlock.h:484
InstListType::iterator iterator
Instruction iterators...
Definition BasicBlock.h:170
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
Definition BasicBlock.h:237
BinaryOps getOpcode() const
Definition InstrTypes.h:409
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
LLVM_ABI bool isMustTailCall() const
Tests if this call site must be tail call optimized.
LLVM_ABI bool isIndirectCall() const
Return true if the callsite is an indirect call.
bool isCallee(Value::const_user_iterator UI) const
Determine whether the passed iterator points to the callee operand's Use.
Value * getCalledOperand() const
const Use & getCalledOperandUse() const
Attribute getFnAttr(StringRef Kind) const
Get the attribute of a given kind for the function.
const Use & getArgOperandUse(unsigned i) const
Wrappers for getting the Use of a call argument.
LLVM_ABI std::optional< ConstantRange > getRange() const
If this return value has a range attribute, return the value range of the argument.
Value * getArgOperand(unsigned i) const
bool isBundleOperand(unsigned Idx) const
Return true if the operand at index Idx is a bundle operand.
bool isConvergent() const
Determine if the invoke is convergent.
FunctionType * getFunctionType() const
LLVM_ABI Intrinsic::ID getIntrinsicID() const
Returns the intrinsic ID of the intrinsic called or Intrinsic::not_intrinsic if the called function i...
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
unsigned getArgOperandNo(const Use *U) const
Given a use for a arg operand, get the arg operand number that corresponds to it.
unsigned arg_size() const
bool isArgOperand(const Use *U) const
LLVM_ABI Function * getCaller()
Helper to get the caller (the parent function).
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
static CaptureInfo none()
Create CaptureInfo that does not capture any components of the pointer.
Definition ModRef.h:427
Instruction::CastOps getOpcode() const
Return the opcode of this CastInst.
Definition InstrTypes.h:674
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:681
bool isEquality() const
Determine if this is an equals/not equals predicate.
Definition InstrTypes.h:978
bool isFalseWhenEqual() const
This is just a convenience.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition InstrTypes.h:740
@ ICMP_NE
not equal
Definition InstrTypes.h:762
bool isTrueWhenEqual() const
This is just a convenience.
Predicate getPredicate() const
Return the predicate for this instruction.
Definition InstrTypes.h:828
Conditional Branch instruction.
Value * getCondition() const
BasicBlock * getSuccessor(unsigned i) const
static ConstantAsMetadata * get(Constant *C)
Definition Metadata.h:537
static LLVM_ABI Constant * getExtractElement(Constant *Vec, Constant *Idx, Type *OnlyIfReducedTy=nullptr)
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
This class represents a range of values.
const APInt & getLower() const
Return the lower value for this range.
LLVM_ABI bool isFullSet() const
Return true if this set contains all of the elements possible for this data-type.
LLVM_ABI bool isEmptySet() const
Return true if this set contains no members.
bool isSingleElement() const
Return true if this set contains exactly one member.
static LLVM_ABI ConstantRange makeAllowedICmpRegion(CmpInst::Predicate Pred, const ConstantRange &Other)
Produce the smallest range such that all values that may satisfy the given predicate with any value c...
const APInt & getUpper() const
Return the upper value for this range.
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
iterator find(const_arg_type_t< KeyT > Val)
Definition DenseMap.h:225
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
Definition DenseMap.h:301
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:221
iterator end()
Definition DenseMap.h:143
bool contains(const_arg_type_t< KeyT > Val) const
Return true if the specified key is in the map, false otherwise.
Definition DenseMap.h:216
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition DenseMap.h:286
Analysis pass which computes a DominatorTree.
Definition Dominators.h:270
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition Dominators.h:151
LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
const BasicBlock & getEntryBlock() const
Definition Function.h:809
Argument * arg_iterator
Definition Function.h:73
iterator_range< arg_iterator > args()
Definition Function.h:892
const Function & getFunction() const
Definition Function.h:166
size_t arg_size() const
Definition Function.h:901
Argument * getArg(unsigned i) const
Definition Function.h:886
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition Function.cpp:724
CycleT * getCycle(const BlockT *Block) const
Find the innermost cycle containing a given block.
LLVM_ABI bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
Definition Globals.cpp:337
bool hasLocalLinkage() const
static LLVM_ABI bool compare(const APInt &LHS, const APInt &RHS, ICmpInst::Predicate Pred)
Return result of LHS Pred RHS comparison.
Value * CreatePtrAdd(Value *Ptr, Value *Offset, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
Definition IRBuilder.h:2101
ConstantInt * getInt64(uint64_t C)
Get a constant 64-bit value.
Definition IRBuilder.h:534
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2868
LLVM_ABI Instruction * clone() const
Create a copy of 'this' instruction that is identical in all ways except the following:
LLVM_ABI bool isLifetimeStartOrEnd() const LLVM_READONLY
Return true if the instruction is a llvm.lifetime.start or llvm.lifetime.end marker.
bool mayReadOrWriteMemory() const
Return true if this instruction may read or write memory.
LLVM_ABI bool mayWriteToMemory() const LLVM_READONLY
Return true if this instruction may modify memory.
bool hasMetadata() const
Return true if this instruction has any metadata attached to it.
LLVM_ABI void insertBefore(InstListType::iterator InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified position.
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
LLVM_ABI const Function * getFunction() const
Return the function this instruction belongs to.
LLVM_ABI BasicBlock * getSuccessor(unsigned Idx) const LLVM_READONLY
Return the specified successor. This instruction must be a terminator.
LLVM_ABI bool mayHaveSideEffects() const LLVM_READONLY
Return true if the instruction may have side effects.
bool isTerminator() const
LLVM_ABI bool mayReadFromMemory() const LLVM_READONLY
Return true if this instruction may read memory.
LLVM_ABI void setMetadata(unsigned KindID, MDNode *Node)
Set the metadata of the specified kind to the specified node.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this instruction belongs to.
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:68
LLVM_ABI ConstantRange getConstantRange(Value *V, Instruction *CxtI, bool UndefAllowed)
Return the ConstantRange constraint that is known to hold for the specified value at the specified in...
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition Metadata.h:1561
static LLVM_ABI MDNode * getMostGenericRange(MDNode *A, MDNode *B)
bool empty() const
Definition MapVector.h:79
static MemoryEffectsBase readOnly()
Definition ModRef.h:133
bool doesNotAccessMemory() const
Whether this function accesses no memory.
Definition ModRef.h:246
static MemoryEffectsBase argMemOnly(ModRefInfo MR=ModRefInfo::ModRef)
Definition ModRef.h:143
static MemoryEffectsBase inaccessibleMemOnly(ModRefInfo MR=ModRefInfo::ModRef)
Definition ModRef.h:149
bool onlyAccessesInaccessibleMem() const
Whether this function only (at most) accesses inaccessible memory.
Definition ModRef.h:265
ModRefInfo getModRef(Location Loc) const
Get ModRefInfo for the given Location.
Definition ModRef.h:219
bool onlyAccessesArgPointees() const
Whether this function only (at most) accesses argument memory.
Definition ModRef.h:255
bool onlyReadsMemory() const
Whether this function only (at most) reads memory.
Definition ModRef.h:249
static MemoryEffectsBase writeOnly()
Definition ModRef.h:138
static MemoryEffectsBase inaccessibleOrArgMemOnly(ModRefInfo MR=ModRefInfo::ModRef)
Definition ModRef.h:166
static MemoryEffectsBase none()
Definition ModRef.h:128
bool onlyAccessesInaccessibleOrArgMem() const
Whether this function only (at most) accesses argument and inaccessible memory.
Definition ModRef.h:305
static MemoryEffectsBase unknown()
Definition ModRef.h:123
static LLVM_ABI std::optional< MemoryLocation > getOrNone(const Instruction *Inst)
static SizeOffsetValue unknown()
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
Value * getReturnValue() const
Convenience accessor. Returns null if there is no return value.
LLVM_ABI const SCEV * getSCEVAtScope(const SCEV *S, const Loop *L)
Return a SCEV expression for the specified value at the specified scope in the program.
LLVM_ABI const SCEV * getSCEV(Value *V)
Return a SCEV expression for the full generality of the specified expression.
LLVM_ABI unsigned getSmallConstantMaxTripCount(const Loop *L, SmallVectorImpl< const SCEVPredicate * > *Predicates=nullptr)
Returns the upper bound of the loop trip count as a normal unsigned value.
ConstantRange getUnsignedRange(const SCEV *S)
Determine the unsigned range for a particular SCEV.
A vector that has set insertion semantics.
Definition SetVector.h:57
size_type size() const
Determine the number of elements in the SetVector.
Definition SetVector.h:103
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition SetVector.h:151
bool erase(PtrType Ptr)
Remove pointer from the set.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
Definition SmallSet.h:184
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Used to lazily calculate structure layout information for a target machine, based on the DataLayout s...
Definition DataLayout.h:743
TypeSize getElementOffset(unsigned Idx) const
Definition DataLayout.h:774
TypeSize getElementOffsetInBits(unsigned Idx) const
Definition DataLayout.h:779
Class to represent struct types.
unsigned getNumElements() const
Random access to the elements.
Type * getElementType(unsigned N) const
LLVM_ABI bool areTypesABICompatible(const Function *Caller, const Function *Callee, ArrayRef< Type * > Types) const
LLVM_ABI unsigned getAssumedAddrSpace(const Value *V) const
LLVM_ABI bool hasVolatileVariant(Instruction *I, unsigned AddrSpace) const
Return true if the given instruction (assumed to be a memory access instruction) has a volatile varia...
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
LLVM_ABI unsigned getIntegerBitWidth() const
bool isPointerTy() const
True if this is an instance of PointerType.
Definition Type.h:282
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
bool isPtrOrPtrVectorTy() const
Return true if this is a pointer type or a vector of pointer types.
Definition Type.h:285
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:257
bool isVoidTy() const
Return true if this is 'void'.
Definition Type.h:141
static UncondBrInst * Create(BasicBlock *Target, InsertPosition InsertBefore=nullptr)
BasicBlock * getSuccessor(unsigned i=0) const
static LLVM_ABI UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
A Use represents the edge between a Value definition and its users.
Definition Use.h:35
User * getUser() const
Returns the User that contains this Use.
Definition Use.h:61
Value * get() const
Definition Use.h:55
const Use & getOperandUse(unsigned i) const
Definition User.h:220
LLVM_ABI bool isDroppable() const
A droppable user is a user for which uses can be dropped without affecting correctness and should be ...
Definition User.cpp:119
LLVM_ABI bool replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
Definition User.cpp:25
Value * getOperand(unsigned i) const
Definition User.h:207
unsigned getNumOperands() const
Definition User.h:229
ValueT lookup(const KeyT &Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
Definition ValueMap.h:167
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:255
static constexpr uint64_t MaximumAlignment
Definition Value.h:798
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition Value.cpp:552
LLVMContext & getContext() const
All values hold a context through their type.
Definition Value.h:258
iterator_range< user_iterator > users()
Definition Value.h:426
LLVM_ABI const Value * stripAndAccumulateConstantOffsets(const DataLayout &DL, APInt &Offset, bool AllowNonInbounds, bool AllowInvariantGroup=false, function_ref< bool(Value &Value, APInt &Offset)> ExternalAnalysis=nullptr, bool LookThroughIntToPtr=false) const
Accumulate the constant offset this value has compared to a base pointer.
bool use_empty() const
Definition Value.h:346
static constexpr unsigned MaxAlignmentExponent
The maximum alignment for instructions.
Definition Value.h:797
iterator_range< use_iterator > uses()
Definition Value.h:380
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:318
std::pair< iterator, bool > insert(const ValueT &V)
Definition DenseSet.h:212
constexpr ScalarTy getFixedValue() const
Definition TypeSize.h:200
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
Definition TypeSize.h:168
const ParentTy * getParent() const
Definition ilist_node.h:34
self_iterator getIterator()
Definition ilist_node.h:123
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
Definition ilist_node.h:348
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
A raw_ostream that writes to an std::string.
Changed
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Abstract Attribute helper functions.
Definition Attributor.h:165
LLVM_ABI bool isAssumedReadNone(Attributor &A, const IRPosition &IRP, const AbstractAttribute &QueryingAA, bool &IsKnown)
Return true if IRP is readnone.
LLVM_ABI bool isAssumedReadOnly(Attributor &A, const IRPosition &IRP, const AbstractAttribute &QueryingAA, bool &IsKnown)
Return true if IRP is readonly.
raw_ostream & operator<<(raw_ostream &OS, const RangeTy &R)
Definition Attributor.h:335
LLVM_ABI std::optional< Value * > combineOptionalValuesInAAValueLatice(const std::optional< Value * > &A, const std::optional< Value * > &B, Type *Ty)
Return the combination of A and B such that the result is a possible value of both.
LLVM_ABI bool isValidAtPosition(const ValueAndContext &VAC, InformationCache &InfoCache)
Return true if the value of VAC is a valid at the position of VAC, that is a constant,...
LLVM_ABI bool isAssumedThreadLocalObject(Attributor &A, Value &Obj, const AbstractAttribute &QueryingAA)
Return true if Obj is assumed to be a thread local object.
LLVM_ABI bool isGPUConstantAddressSpace(const Module &M, unsigned AS)
Check if the given address space AS corresponds to a GPU constant address space for the target triple...
LLVM_ABI bool isDynamicallyUnique(Attributor &A, const AbstractAttribute &QueryingAA, const Value &V, bool ForAnalysisOnly=true)
Return true if V is dynamically unique, that is, there are no two "instances" of V at runtime with di...
LLVM_ABI bool getPotentialCopiesOfStoredValue(Attributor &A, StoreInst &SI, SmallSetVector< Value *, 4 > &PotentialCopies, const AbstractAttribute &QueryingAA, bool &UsedAssumedInformation, bool OnlyExact=false)
Collect all potential values of the one stored by SI into PotentialCopies.
LLVM_ABI bool isGPUSharedAddressSpace(const Module &M, unsigned AS)
Check if the given address space AS corresponds to a GPU shared address space for the target triple i...
LLVM_ABI bool isGPULocalAddressSpace(const Module &M, unsigned AS)
Check if the given address space AS corresponds to a GPU local/private address space for the target t...
SmallPtrSet< Instruction *, 4 > InstExclusionSetTy
Definition Attributor.h:166
LLVM_ABI bool isGPU(const Module &M)
Return true iff M target a GPU (and we can use GPU AS reasoning).
ValueScope
Flags to distinguish intra-procedural queries from potentially inter-procedural queries.
Definition Attributor.h:194
@ Intraprocedural
Definition Attributor.h:195
@ Interprocedural
Definition Attributor.h:196
LLVM_ABI bool isValidInScope(const Value &V, const Function *Scope)
Return true if V is a valid value in Scope, that is a constant or an instruction/argument of Scope.
LLVM_ABI bool isPotentiallyReachable(Attributor &A, const Instruction &FromI, const Instruction &ToI, const AbstractAttribute &QueryingAA, const AA::InstExclusionSetTy *ExclusionSet=nullptr, std::function< bool(const Function &F)> GoBackwardsCB=nullptr)
Return true if ToI is potentially reachable from FromI without running into any instruction in Exclus...
LLVM_ABI bool isNoSyncInst(Attributor &A, const Instruction &I, const AbstractAttribute &QueryingAA)
Return true if I is a nosync instruction.
bool hasAssumedIRAttr(Attributor &A, const AbstractAttribute *QueryingAA, const IRPosition &IRP, DepClassTy DepClass, bool &IsKnown, bool IgnoreSubsumingPositions=false, const AAType **AAPtr=nullptr)
Helper to avoid creating an AA for IR Attributes that might already be set.
LLVM_ABI bool getPotentiallyLoadedValues(Attributor &A, LoadInst &LI, SmallSetVector< Value *, 4 > &PotentialValues, SmallSetVector< Instruction *, 4 > &PotentialValueOrigins, const AbstractAttribute &QueryingAA, bool &UsedAssumedInformation, bool OnlyExact=false)
Collect all potential values LI could read into PotentialValues.
LLVM_ABI Value * getWithType(Value &V, Type &Ty)
Try to convert V to type Ty without introducing new instructions.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char Attrs[]
Key for Kernel::Metadata::mAttrs.
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
@ BasicBlock
Various leaf nodes.
Definition ISDOpcodes.h:81
@ Unsupported
This operation is completely unsupported on the target.
Offsets
Offsets in bytes from the start of the input buffer.
@ SingleThread
Synchronized with respect to signal handlers executing in the same thread.
Definition LLVMContext.h:55
@ CE
Windows NT (Windows on ARM)
Definition MCAsmInfo.h:50
@ Valid
The data is already valid.
initializer< Ty > init(const Ty &Val)
LocationClass< Ty > location(Ty &L)
unsigned combineHashValue(unsigned a, unsigned b)
Simplistic combination of 32-bit hash values into 32-bit hash values.
ElementType
The element type of an SRV or UAV resource.
Definition DXILABI.h:68
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > dyn_extract_or_null(Y &&MD)
Extract a Value from Metadata, if any, allowing null.
Definition Metadata.h:709
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > extract(Y &&MD)
Extract a Value from Metadata.
Definition Metadata.h:668
@ User
could "use" a pointer
NodeAddr< UseNode * > Use
Definition RDFGraph.h:385
Context & getContext() const
Definition BasicBlock.h:99
iterator end() const
Definition BasicBlock.h:89
friend class Instruction
Iterator for Instructions in a `BasicBlock.
Definition BasicBlock.h:73
LLVM_ABI iterator begin() const
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:558
@ Length
Definition DWP.cpp:558
bool operator<(int64_t V1, const APSInt &V2)
Definition APSInt.h:360
FunctionAddr VTableAddr Value
Definition InstrProf.h:137
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt gcd(const DynamicAPInt &A, const DynamicAPInt &B)
LLVM_ABI KnownFPClass computeKnownFPClass(const Value *V, const APInt &DemandedElts, FPClassTest InterestedClasses, const SimplifyQuery &SQ, unsigned Depth=0)
Determine which floating-point classes are valid for V, and return them in KnownFPClass bit sets.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1738
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:1668
@ Undef
Value of the register doesn't matter.
auto pred_end(const MachineBasicBlock *BB)
unsigned getPointerAddressSpace(const Type *T)
Definition SPIRVUtils.h:392
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
FunctionAddr VTableAddr uintptr_t uintptr_t Int32Ty
Definition InstrProf.h:328
auto successors(const MachineBasicBlock *BB)
LLVM_ABI bool isRemovableAlloc(const CallBase *V, const TargetLibraryInfo *TLI)
Return true if this is a call to an allocation function that does not have side effects that we are r...
APFloat abs(APFloat X)
Returns the absolute value of the argument.
Definition APFloat.h:1660
LLVM_ABI raw_fd_ostream & outs()
This returns a reference to a raw_fd_ostream for standard output.
LLVM_ABI Value * getAllocAlignment(const CallBase *V, const TargetLibraryInfo *TLI)
Gets the alignment argument for an aligned_alloc-like function, using either built-in knowledge based...
auto dyn_cast_if_present(const Y &Val)
dyn_cast_if_present<X> - Functionally identical to dyn_cast, except that a null (or none in the case ...
Definition Casting.h:732
LLVM_ABI Value * simplifyInstructionWithOperands(Instruction *I, ArrayRef< Value * > NewOps, const SimplifyQuery &Q)
Like simplifyInstruction but the operands of I are replaced with NewOps.
Value * GetPointerBaseWithConstantOffset(Value *Ptr, int64_t &Offset, const DataLayout &DL, bool AllowNonInbounds=true)
Analyze the specified pointer to see if it can be expressed as a base pointer plus a constant offset.
scc_iterator< T > scc_begin(const T &G)
Construct the begin iterator for a deduced graph type T.
LLVM_ABI bool isIntrinsicReturningPointerAliasingArgumentWithoutCapturing(const CallBase *Call, bool MustPreserveOffset)
{launder,strip}.invariant.group returns pointer that aliases its argument, and it only captures point...
LLVM_ABI bool isNoAliasCall(const Value *V)
Return true if this pointer is returned by a noalias function.
MemoryEffectsBase< IRMemLocation > MemoryEffects
Summary of how a function affects memory in the program.
Definition ModRef.h:356
raw_ostream & WriteGraph(raw_ostream &O, const GraphType &G, bool ShortNames=false, const Twine &Title="")
LLVM_ABI bool isSafeToSpeculativelyExecute(const Instruction *I, const Instruction *CtxI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr, const TargetLibraryInfo *TLI=nullptr, bool UseVariableInfo=true, bool IgnoreUBImplyingAttrs=true)
Return true if the instruction does not have any effects besides calculating the result and does not ...
bool isa_and_nonnull(const Y &Val)
Definition Casting.h:676
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
LLVM_ABI ConstantRange getConstantRangeFromMetadata(const MDNode &RangeMD)
Parse out a conservative ConstantRange from !range metadata.
auto map_range(ContainerTy &&C, FuncTy F)
Return a range that applies F to the elements of C.
Definition STLExtras.h:365
const Value * getPointerOperand(const Value *V)
A helper function that returns the pointer operand of a load, store or GEP instruction.
LLVM_ABI Value * simplifyInstruction(Instruction *I, const SimplifyQuery &Q)
See if we can compute a simplified version of this instruction.
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:753
CycleInfo::CycleT Cycle
Definition CycleInfo.h:26
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1745
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Definition MathExtras.h:331
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition MathExtras.h:279
PotentialValuesState< std::pair< AA::ValueAndContext, AA::ValueScope > > PotentialLLVMValuesState
void sort(IteratorTy Start, IteratorTy End)
Definition STLExtras.h:1635
LLVM_ABI bool NullPointerIsDefined(const Function *F, unsigned AS=0)
Check whether null pointer dereferencing is considered undefined behavior for a given function or an ...
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
bool isPointerTy(const Type *T)
Definition SPIRVUtils.h:380
LLVM_ABI bool wouldInstructionBeTriviallyDead(const Instruction *I, const TargetLibraryInfo *TLI=nullptr)
Return true if the result produced by the instruction would have no side effects if it was not used.
Definition Local.cpp:422
bool set_union(S1Ty &S1, const S2Ty &S2)
set_union(A, B) - Compute A := A u B, return whether A changed.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
LLVM_ABI CallBase & promoteCall(CallBase &CB, Function *Callee, CastInst **RetBitCast=nullptr)
Promote the given indirect call site to unconditionally call Callee.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
LLVM_ABI bool hasAssumption(const Function &F, const KnownAssumptionString &AssumptionStr)
Return true if F has the assumption AssumptionStr attached.
LLVM_ABI RetainedKnowledge getKnowledgeFromUse(const Use *U, ArrayRef< Attribute::AttrKind > AttrKinds)
Return a valid Knowledge associated to the Use U if its Attribute kind is in AttrKinds.
@ Success
The lock was released successfully.
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
LLVM_ABI bool isKnownNonZero(const Value *V, const SimplifyQuery &Q, unsigned Depth=0)
Return true if the given value is known to be non-zero when defined.
AtomicOrdering
Atomic ordering for LLVM's memory model.
@ Other
Any other memory.
Definition ModRef.h:68
PotentialValuesState< APInt > PotentialConstantIntValuesState
TargetTransformInfo TTI
std::string join(IteratorT Begin, IteratorT End, StringRef Separator)
Joins the strings in the range [Begin, End), adding Separator between the elements.
IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >
InterleavedRange< Range > interleaved_array(const Range &R, StringRef Separator=", ")
Output range R as an array of interleaved elements.
ChangeStatus clampStateAndIndicateChange< DerefState >(DerefState &S, const DerefState &R)
void RemapInstruction(Instruction *I, ValueToValueMapTy &VM, RemapFlags Flags=RF_None, ValueMapTypeRemapper *TypeMapper=nullptr, ValueMaterializer *Materializer=nullptr, const MetadataPredicate *IdentityMD=nullptr)
Convert the instruction operands from referencing the current values into those specified by VM.
DWARFExpression::Operation Op
LLVM_ABI bool isGuaranteedNotToBeUndefOrPoison(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Return true if this function can prove that V does not have undef bits and is never poison.
ArrayRef(const T &OneElt) -> ArrayRef< T >
LLVM_ABI Value * getFreedOperand(const CallBase *CB, const TargetLibraryInfo *TLI)
If this if a call to a free function, return the freed operand.
ChangeStatus clampStateAndIndicateChange(StateType &S, const StateType &R)
Helper function to clamp a state S of type StateType with the information in R and indicate/return if...
constexpr unsigned BitWidth
ValueMap< const Value *, WeakTrackingVH > ValueToValueMapTy
auto pred_begin(const MachineBasicBlock *BB)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
iterator_range< pointer_iterator< WrappedIteratorT > > make_pointer_range(RangeT &&Range)
Definition iterator.h:368
ChangeStatus
{
Definition Attributor.h:485
LLVM_ABI std::optional< APInt > getAllocSize(const CallBase *CB, const TargetLibraryInfo *TLI, function_ref< const Value *(const Value *)> Mapper=[](const Value *V) { return V;})
Return the size of the requested allocation.
LLVM_ABI DenseSet< StringRef > getAssumptions(const Function &F)
Return the set of all assumptions for the function F.
Align assumeAligned(uint64_t Value)
Treats the value 0 as a 1, so Align is always at least 1.
Definition Alignment.h:100
LLVM_ABI Instruction * SplitBlockAndInsertIfThen(Value *Cond, BasicBlock::iterator SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, BasicBlock *ThenBlock=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...
@ OPTIONAL
The target may be valid if the source is not.
Definition Attributor.h:497
@ NONE
Do not track a dependence between source and target.
Definition Attributor.h:498
@ REQUIRED
The target cannot be valid if the source is not.
Definition Attributor.h:496
LLVM_ABI UseCaptureInfo DetermineUseCaptureKind(const Use &U, const Value *Base)
Determine what kind of capture behaviour U may exhibit.
LLVM_ABI Value * simplifyCmpInst(CmpPredicate Predicate, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for a CmpInst, fold the result or return null.
LLVM_ABI bool mayContainIrreducibleControl(const Function &F, const LoopInfo *LI)
BumpPtrAllocatorImpl<> BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
Definition Allocator.h:383
T bit_floor(T Value)
Returns the largest integral power of two no greater than Value if Value is nonzero.
Definition bit.h:347
LLVM_ABI const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=MaxLookupSearchDepth)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
bool capturesNothing(CaptureComponents CC)
Definition ModRef.h:375
LLVM_ABI bool isIdentifiedObject(const Value *V)
Return true if this pointer refers to a distinct and identifiable object.
bool capturesAnyProvenance(CaptureComponents CC)
Definition ModRef.h:400
constexpr StringRef AssumptionAttrKey
The key we use for assumption attributes.
Definition Assumptions.h:29
constexpr bool isCallableCC(CallingConv::ID CC)
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:862
A type to track pointer/struct usage and accesses for AAPointerInfo.
bool forallInterferingAccesses(AA::RangeTy Range, F CB) const
See AAPointerInfo::forallInterferingAccesses.
AAPointerInfo::const_bin_iterator end() const
ChangeStatus addAccess(Attributor &A, const AAPointerInfo::RangeList &Ranges, Instruction &I, std::optional< Value * > Content, AAPointerInfo::AccessKind Kind, Type *Ty, Instruction *RemoteI=nullptr)
Add a new Access to the state at offset Offset and with size Size.
DenseMap< const Instruction *, SmallVector< unsigned > > RemoteIMap
AAPointerInfo::const_bin_iterator begin() const
AAPointerInfo::OffsetInfo ReturnedOffsets
Flag to determine if the underlying pointer is reaching a return statement in the associated function...
State(State &&SIS)=default
const AAPointerInfo::Access & getAccess(unsigned Index) const
SmallVector< AAPointerInfo::Access > AccessList
bool isAtFixpoint() const override
See AbstractState::isAtFixpoint().
bool forallInterferingAccesses(Instruction &I, F CB, AA::RangeTy &Range) const
See AAPointerInfo::forallInterferingAccesses.
static State getWorstState(const State &SIS)
Return the worst possible representable state.
AAPointerInfo::OffsetBinsTy OffsetBins
ChangeStatus indicateOptimisticFixpoint() override
See AbstractState::indicateOptimisticFixpoint().
ChangeStatus indicatePessimisticFixpoint() override
See AbstractState::indicatePessimisticFixpoint().
static State getBestState(const State &SIS)
Return the best possible representable state.
bool isValidState() const override
See AbstractState::isValidState().
----------------—AAIntraFnReachability Attribute-----------------------—
ReachabilityQueryInfo(const ReachabilityQueryInfo &RQI)
unsigned Hash
Precomputed hash for this RQI.
const Instruction * From
Start here,.
Reachable Result
and remember if it worked:
ReachabilityQueryInfo(const Instruction *From, const ToTy *To)
ReachabilityQueryInfo(Attributor &A, const Instruction &From, const ToTy &To, const AA::InstExclusionSetTy *ES, bool MakeUnique)
Constructor replacement to ensure unique and stable sets are used for the cache.
const ToTy * To
reach this place,
const AA::InstExclusionSetTy * ExclusionSet
without going through any of these instructions,
An abstract interface for address space information.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for all align attributes.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
Align getKnownAlign() const
Return known alignment.
static LLVM_ABI const char ID
An abstract attribute for getting assumption information.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract state for querying live call edges.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract Attribute for specializing "dynamic" components of denormal_fpenv to a known denormal mod...
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for all dereferenceable attribute.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for llvm::GlobalValue information interference.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for indirect call information interference.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface to track if a value leaves it's defining function instance.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract Attribute for computing reachability between functions.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
bool canReach(Attributor &A, const Function &Fn) const
If the function represented by this possition can reach Fn.
virtual bool instructionCanReach(Attributor &A, const Instruction &Inst, const Function &Fn, const AA::InstExclusionSetTy *ExclusionSet=nullptr) const =0
Can Inst reach Fn.
An abstract interface to determine reachability of point A to B.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for identifying pointers from which loads can be marked invariant.
static LLVM_ABI const char ID
Unique ID (due to the unique address).
An abstract interface for liveness abstract attribute.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for memory access kind related attributes (readnone/readonly/writeonly).
bool isAssumedReadOnly() const
Return true if we assume that the underlying value is not accessed (=written) in its respective scope...
bool isKnownReadNone() const
Return true if we know that the underlying value is not read or accessed in its respective scope.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
bool isAssumedReadNone() const
Return true if we assume that the underlying value is not read or accessed in its respective scope.
An abstract interface for all memory location attributes (readnone/argmemonly/inaccessiblememonly/ina...
static LLVM_ABI std::string getMemoryLocationsAsStr(MemoryLocationsKind MLK)
Return the locations encoded by MLK as a readable string.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
StateType::base_t MemoryLocationsKind
An abstract interface for all nonnull attributes.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for potential address space information.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for all noalias attributes.
static LLVM_ABI bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
See IRAttribute::isImpliedByIR.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for all nocapture attributes.
@ NO_CAPTURE_MAYBE_RETURNED
If we do not capture the value in memory or through integers we can only communicate it back as a der...
@ NO_CAPTURE
If we do not capture the value in memory, through integers, or as a derived pointer we know it is not...
static LLVM_ABI const char ID
Unique ID (due to the unique address)
bool isAssumedNoCaptureMaybeReturned() const
Return true if we assume that the underlying value is not captured in its respective scope but we all...
static LLVM_ABI bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
See IRAttribute::isImpliedByIR.
static LLVM_ABI void determineFunctionCaptureCapabilities(const IRPosition &IRP, const Function &F, BitIntegerState &State)
Update State according to the capture capabilities of F for position IRP.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An AbstractAttribute for nofree.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract attribute for norecurse.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An AbstractAttribute for noreturn.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI bool isAlignedBarrier(const CallBase &CB, bool ExecutedAligned)
Helper function to determine if CB is an aligned (GPU) barrier.
static LLVM_ABI bool isNonRelaxedAtomic(const Instruction *I)
Helper function used to determine whether an instruction is non-relaxed atomic.
An abstract interface for all noundef attributes.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
See IRAttribute::isImpliedByIR.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract Attribute for determining the necessity of the convergent attribute.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for all nonnull attributes.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
See AbstractAttribute::isImpliedByIR(...).
An access description.
A helper containing a list of offsets computed for a Use.
A container for a list of ranges.
static void set_difference(const RangeList &L, const RangeList &R, RangeList &D)
Copy ranges from L that are not in R, into D.
An abstract interface for struct information.
virtual bool reachesReturn() const =0
OffsetBinsTy::const_iterator const_bin_iterator
virtual const_bin_iterator begin() const =0
DenseMap< AA::RangeTy, SmallSet< unsigned, 4 > > OffsetBinsTy
static LLVM_ABI const char ID
Unique ID (due to the unique address)
virtual int64_t numOffsetBins() const =0
An abstract interface for potential values analysis.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
friend struct Attributor
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI Value * getSingleValue(Attributor &A, const AbstractAttribute &AA, const IRPosition &IRP, SmallVectorImpl< AA::ValueAndContext > &Values)
Extract the single value in Values if any.
An abstract interface for privatizability.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract attribute for undefined behavior.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract attribute for getting all assumption underlying objects.
virtual bool forallUnderlyingObjects(function_ref< bool(Value &)> Pred, AA::ValueScope Scope=AA::Interprocedural) const =0
Check Pred on all underlying objects in Scope collected so far.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for range value analysis.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for value simplify abstract attribute.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract attribute for willreturn.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
Helper to represent an access offset and size, with logic to deal with uncertainty and check for over...
Definition Attributor.h:253
static constexpr int64_t Unknown
Definition Attributor.h:332
static RangeTy getUnknown()
Definition Attributor.h:259
Value * getValue() const
Definition Attributor.h:206
const Instruction * getCtxI() const
Definition Attributor.h:207
Base struct for all "concrete attribute" deductions.
void print(raw_ostream &OS) const
Helper functions, for debug purposes only.
virtual StateType & getState()=0
Return the internal abstract state for inspection.
AbstractState StateType
An interface to query the internal state of an abstract attribute.
virtual bool isAtFixpoint() const =0
Return if this abstract state is fixed, thus does not need to be updated if information changes as it...
virtual bool isValidState() const =0
Return if this abstract state is in a valid state.
Helper for AA::PointerInfo::Access DenseMap/Set usage ignoring everythign but the instruction.
static unsigned getHashValue(const Access &A)
DenseMapInfo< Instruction * > Base
static bool isEqual(const Access &LHS, const Access &RHS)
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
Definition Alignment.h:77
std::function< void( const ArgumentReplacementInfo &, Function &, Function::arg_iterator)> CalleeRepairCBTy
Callee repair callback type.
const Argument & getReplacedArg() const
std::function< void(const ArgumentReplacementInfo &, AbstractCallSite, SmallVectorImpl< Value * > &)> ACSRepairCBTy
Abstract call site (ACS) repair callback type.
The fixpoint analysis framework that orchestrates the attribute deduction.
std::function< std::optional< Value * >( const IRPosition &, const AbstractAttribute *, bool &)> SimplifictionCallbackTy
Register CB as a simplification callback.
Specialization of the integer state for a bit-wise encoding.
BitIntegerState & addKnownBits(base_t Bits)
Add the bits in BitsEncoding to the "known bits".
Simple wrapper for a single bit (boolean) state.
static constexpr DenormalFPEnv getDefault()
static unsigned getHashValue(const Access &A)
static bool isEqual(const Access &LHS, const Access &RHS)
static bool isEqual(const AA::RangeTy &A, const AA::RangeTy B)
static unsigned getHashValue(const AA::RangeTy &Range)
DenseMapInfo< std::pair< const Instruction *, const ToTy * > > PairDMI
static bool isEqual(const ReachabilityQueryInfo< ToTy > *LHS, const ReachabilityQueryInfo< ToTy > *RHS)
DenseMapInfo< const AA::InstExclusionSetTy * > InstSetDMI
static unsigned getHashValue(const ReachabilityQueryInfo< ToTy > *RQI)
An information struct used to provide DenseMap with the various necessary components for a given valu...
State for dereferenceable attribute.
IncIntegerState DerefBytesState
State representing for dereferenceable bytes.
ChangeStatus manifest(Attributor &A) override
See AbstractAttribute::manifest(...).
Helper to describe and deal with positions in the LLVM-IR.
Definition Attributor.h:582
Function * getAssociatedFunction() const
Return the associated function, if any.
Definition Attributor.h:713
static const IRPosition callsite_returned(const CallBase &CB)
Create a position describing the returned value of CB.
Definition Attributor.h:650
static const IRPosition returned(const Function &F, const CallBaseContext *CBContext=nullptr)
Create a position describing the returned value of F.
Definition Attributor.h:632
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:606
CallBase CallBaseContext
Definition Attributor.h:585
int getCalleeArgNo() const
Return the callee argument number of the associated value if it is an argument or call site argument,...
Definition Attributor.h:800
static const IRPosition inst(const Instruction &I, const CallBaseContext *CBContext=nullptr)
Create a position describing the instruction I.
Definition Attributor.h:618
static const IRPosition callsite_argument(const CallBase &CB, unsigned ArgNo)
Create a position describing the argument of CB at position ArgNo.
Definition Attributor.h:655
@ IRP_ARGUMENT
An attribute for a function argument.
Definition Attributor.h:596
@ IRP_RETURNED
An attribute for the function return value.
Definition Attributor.h:592
@ IRP_CALL_SITE
An attribute for a call site (function scope).
Definition Attributor.h:595
@ IRP_CALL_SITE_RETURNED
An attribute for a call site return value.
Definition Attributor.h:593
@ IRP_FUNCTION
An attribute for a function (scope).
Definition Attributor.h:594
@ IRP_CALL_SITE_ARGUMENT
An attribute for a call site argument.
Definition Attributor.h:597
@ IRP_INVALID
An invalid position.
Definition Attributor.h:589
Instruction * getCtxI() const
Return the context instruction, if any.
Definition Attributor.h:766
static const IRPosition argument(const Argument &Arg, const CallBaseContext *CBContext=nullptr)
Create a position describing the argument Arg.
Definition Attributor.h:639
Type * getAssociatedType() const
Return the type this abstract attribute is associated with.
Definition Attributor.h:789
static const IRPosition function(const Function &F, const CallBaseContext *CBContext=nullptr)
Create a position describing the function scope of F.
Definition Attributor.h:625
const CallBaseContext * getCallBaseContext() const
Get the call base context from the position.
Definition Attributor.h:928
Value & getAssociatedValue() const
Return the value this abstract attribute is associated with.
Definition Attributor.h:780
Value & getAnchorValue() const
Return the value this abstract attribute is anchored with.
Definition Attributor.h:699
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:809
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:678
Kind getPositionKind() const
Return the associated position kind.
Definition Attributor.h:878
bool isArgumentPosition() const
Return true if the position is an argument or call site argument.
Definition Attributor.h:910
static const IRPosition callsite_function(const CallBase &CB)
Create a position describing the function scope of CB.
Definition Attributor.h:645
Function * getAnchorScope() const
Return the Function surrounding the anchor value.
Definition Attributor.h:754
Data structure to hold cached (LLVM-IR) information.
TargetLibraryInfo * getTargetLibraryInfoForFunction(const Function &F)
Return TargetLibraryInfo for function F.
bool isOnlyUsedByAssume(const Instruction &I) const
AP::Result * getAnalysisResultForFunction(const Function &F, bool CachedOnly=false)
Return the analysis result from a pass AP for function F.
ConstantRange getKnown() const
Return the known state encoding.
ConstantRange getAssumed() const
Return the assumed state encoding.
base_t getAssumed() const
Return the assumed state encoding.
Helper that allows to insert a new assumption string in the known assumption set by creating a (stati...
Definition Assumptions.h:37
FPClassTest KnownFPClasses
Floating-point classes the value could be one of.
A "must be executed context" for a given program point PP is the set of instructions,...
iterator & end()
Return an universal end iterator.
bool findInContextOf(const Instruction *I, const Instruction *PP)
Helper to look for I in the context of PP.
iterator & begin(const Instruction *PP)
Return an iterator to explore the context around PP.
bool checkForAllContext(const Instruction *PP, function_ref< bool(const Instruction *)> Pred)
}
Helper to tie a abstract state implementation to an abstract attribute.
StateType & getState() override
See AbstractAttribute::getState(...).
CaptureComponents ResultCC
Components captured by the return value of the user of this Use.
LLVM_ABI bool unionAssumed(std::optional< Value * > Other)
Merge Other into the currently assumed simplified value.
std::optional< Value * > SimplifiedAssociatedValue
An assumed simplified value.
Type * Ty
The type of the original value.