LLVM 23.0.0git
AttributorAttributes.cpp
Go to the documentation of this file.
1//===- AttributorAttributes.cpp - Attributes for Attributor deduction -----===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// See the Attributor.h file comment and the class descriptions in that file for
10// more information.
11//
12//===----------------------------------------------------------------------===//
13
15
16#include "llvm/ADT/APInt.h"
17#include "llvm/ADT/ArrayRef.h"
19#include "llvm/ADT/MapVector.h"
21#include "llvm/ADT/STLExtras.h"
23#include "llvm/ADT/SetVector.h"
26#include "llvm/ADT/Statistic.h"
39#include "llvm/IR/Argument.h"
40#include "llvm/IR/Assumptions.h"
41#include "llvm/IR/Attributes.h"
42#include "llvm/IR/BasicBlock.h"
43#include "llvm/IR/Constant.h"
44#include "llvm/IR/Constants.h"
45#include "llvm/IR/DataLayout.h"
47#include "llvm/IR/GlobalValue.h"
48#include "llvm/IR/IRBuilder.h"
49#include "llvm/IR/InlineAsm.h"
50#include "llvm/IR/InstrTypes.h"
51#include "llvm/IR/Instruction.h"
54#include "llvm/IR/IntrinsicsAMDGPU.h"
55#include "llvm/IR/IntrinsicsNVPTX.h"
56#include "llvm/IR/LLVMContext.h"
57#include "llvm/IR/MDBuilder.h"
58#include "llvm/IR/NoFolder.h"
59#include "llvm/IR/Value.h"
60#include "llvm/IR/ValueHandle.h"
75#include <cassert>
76#include <numeric>
77#include <optional>
78#include <string>
79
80using namespace llvm;
81
82#define DEBUG_TYPE "attributor"
83
85 "attributor-manifest-internal", cl::Hidden,
86 cl::desc("Manifest Attributor internal string attributes."),
87 cl::init(false));
88
89static cl::opt<int> MaxHeapToStackSize("max-heap-to-stack-size", cl::init(128),
91
92template <>
94
96
98 "attributor-max-potential-values", cl::Hidden,
99 cl::desc("Maximum number of potential values to be "
100 "tracked for each position."),
102 cl::init(7));
103
105 "attributor-max-potential-values-iterations", cl::Hidden,
106 cl::desc(
107 "Maximum number of iterations we keep dismantling potential values."),
108 cl::init(64));
109
110STATISTIC(NumAAs, "Number of abstract attributes created");
111STATISTIC(NumIndirectCallsPromoted, "Number of indirect calls promoted");
112
113// Some helper macros to deal with statistics tracking.
114//
115// Usage:
116// For simple IR attribute tracking overload trackStatistics in the abstract
117// attribute and choose the right STATS_DECLTRACK_********* macro,
118// e.g.,:
119// void trackStatistics() const override {
120// STATS_DECLTRACK_ARG_ATTR(returned)
121// }
122// If there is a single "increment" side one can use the macro
123// STATS_DECLTRACK with a custom message. If there are multiple increment
124// sides, STATS_DECL and STATS_TRACK can also be used separately.
125//
126#define BUILD_STAT_MSG_IR_ATTR(TYPE, NAME) \
127 ("Number of " #TYPE " marked '" #NAME "'")
128#define BUILD_STAT_NAME(NAME, TYPE) NumIR##TYPE##_##NAME
129#define STATS_DECL_(NAME, MSG) STATISTIC(NAME, MSG);
130#define STATS_DECL(NAME, TYPE, MSG) \
131 STATS_DECL_(BUILD_STAT_NAME(NAME, TYPE), MSG);
132#define STATS_TRACK(NAME, TYPE) ++(BUILD_STAT_NAME(NAME, TYPE));
133#define STATS_DECLTRACK(NAME, TYPE, MSG) \
134 {STATS_DECL(NAME, TYPE, MSG) STATS_TRACK(NAME, TYPE)}
135#define STATS_DECLTRACK_ARG_ATTR(NAME) \
136 STATS_DECLTRACK(NAME, Arguments, BUILD_STAT_MSG_IR_ATTR(arguments, NAME))
137#define STATS_DECLTRACK_CSARG_ATTR(NAME) \
138 STATS_DECLTRACK(NAME, CSArguments, \
139 BUILD_STAT_MSG_IR_ATTR(call site arguments, NAME))
140#define STATS_DECLTRACK_FN_ATTR(NAME) \
141 STATS_DECLTRACK(NAME, Function, BUILD_STAT_MSG_IR_ATTR(functions, NAME))
142#define STATS_DECLTRACK_CS_ATTR(NAME) \
143 STATS_DECLTRACK(NAME, CS, BUILD_STAT_MSG_IR_ATTR(call site, NAME))
144#define STATS_DECLTRACK_FNRET_ATTR(NAME) \
145 STATS_DECLTRACK(NAME, FunctionReturn, \
146 BUILD_STAT_MSG_IR_ATTR(function returns, NAME))
147#define STATS_DECLTRACK_CSRET_ATTR(NAME) \
148 STATS_DECLTRACK(NAME, CSReturn, \
149 BUILD_STAT_MSG_IR_ATTR(call site returns, NAME))
150#define STATS_DECLTRACK_FLOATING_ATTR(NAME) \
151 STATS_DECLTRACK(NAME, Floating, \
152 ("Number of floating values known to be '" #NAME "'"))
153
154// Specialization of the operator<< for abstract attributes subclasses. This
155// disambiguates situations where multiple operators are applicable.
156namespace llvm {
157#define PIPE_OPERATOR(CLASS) \
158 raw_ostream &operator<<(raw_ostream &OS, const CLASS &AA) { \
159 return OS << static_cast<const AbstractAttribute &>(AA); \
160 }
161
201
202#undef PIPE_OPERATOR
203
204template <>
206 const DerefState &R) {
207 ChangeStatus CS0 =
208 clampStateAndIndicateChange(S.DerefBytesState, R.DerefBytesState);
209 ChangeStatus CS1 = clampStateAndIndicateChange(S.GlobalState, R.GlobalState);
210 return CS0 | CS1;
211}
212
213} // namespace llvm
214
215static bool mayBeInCycle(const CycleInfo *CI, const Instruction *I,
216 bool HeaderOnly, Cycle **CPtr = nullptr) {
217 if (!CI)
218 return true;
219 auto *BB = I->getParent();
220 auto *C = CI->getCycle(BB);
221 if (!C)
222 return false;
223 if (CPtr)
224 *CPtr = C;
225 return !HeaderOnly || BB == C->getHeader();
226}
227
228/// Checks if a type could have padding bytes.
229static bool isDenselyPacked(Type *Ty, const DataLayout &DL) {
230 // There is no size information, so be conservative.
231 if (!Ty->isSized())
232 return false;
233
234 // If the alloc size is not equal to the storage size, then there are padding
235 // bytes. For x86_fp80 on x86-64, size: 80 alloc size: 128.
236 if (DL.getTypeSizeInBits(Ty) != DL.getTypeAllocSizeInBits(Ty))
237 return false;
238
239 // FIXME: This isn't the right way to check for padding in vectors with
240 // non-byte-size elements.
241 if (VectorType *SeqTy = dyn_cast<VectorType>(Ty))
242 return isDenselyPacked(SeqTy->getElementType(), DL);
243
244 // For array types, check for padding within members.
245 if (ArrayType *SeqTy = dyn_cast<ArrayType>(Ty))
246 return isDenselyPacked(SeqTy->getElementType(), DL);
247
248 if (!isa<StructType>(Ty))
249 return true;
250
251 // Check for padding within and between elements of a struct.
252 StructType *StructTy = cast<StructType>(Ty);
253 const StructLayout *Layout = DL.getStructLayout(StructTy);
254 uint64_t StartPos = 0;
255 for (unsigned I = 0, E = StructTy->getNumElements(); I < E; ++I) {
256 Type *ElTy = StructTy->getElementType(I);
257 if (!isDenselyPacked(ElTy, DL))
258 return false;
259 if (StartPos != Layout->getElementOffsetInBits(I))
260 return false;
261 StartPos += DL.getTypeAllocSizeInBits(ElTy);
262 }
263
264 return true;
265}
266
267/// Get pointer operand of memory accessing instruction. If \p I is
268/// not a memory accessing instruction, return nullptr. If \p AllowVolatile,
269/// is set to false and the instruction is volatile, return nullptr.
271 bool AllowVolatile) {
272 if (!AllowVolatile && I->isVolatile())
273 return nullptr;
274
275 if (auto *LI = dyn_cast<LoadInst>(I)) {
276 return LI->getPointerOperand();
277 }
278
279 if (auto *SI = dyn_cast<StoreInst>(I)) {
280 return SI->getPointerOperand();
281 }
282
283 if (auto *CXI = dyn_cast<AtomicCmpXchgInst>(I)) {
284 return CXI->getPointerOperand();
285 }
286
287 if (auto *RMWI = dyn_cast<AtomicRMWInst>(I)) {
288 return RMWI->getPointerOperand();
289 }
290
291 return nullptr;
292}
293
294/// Helper function to create a pointer based on \p Ptr, and advanced by \p
295/// Offset bytes.
296static Value *constructPointer(Value *Ptr, int64_t Offset,
297 IRBuilder<NoFolder> &IRB) {
298 LLVM_DEBUG(dbgs() << "Construct pointer: " << *Ptr << " + " << Offset
299 << "-bytes\n");
300
301 if (Offset)
302 Ptr = IRB.CreatePtrAdd(Ptr, IRB.getInt64(Offset),
303 Ptr->getName() + ".b" + Twine(Offset));
304 return Ptr;
305}
306
307static const Value *
309 const Value *Val, const DataLayout &DL, APInt &Offset,
310 bool GetMinOffset, bool AllowNonInbounds,
311 bool UseAssumed = false) {
312
313 auto AttributorAnalysis = [&](Value &V, APInt &ROffset) -> bool {
314 const IRPosition &Pos = IRPosition::value(V);
315 // Only track dependence if we are going to use the assumed info.
316 const AAValueConstantRange *ValueConstantRangeAA =
317 A.getAAFor<AAValueConstantRange>(QueryingAA, Pos,
318 UseAssumed ? DepClassTy::OPTIONAL
320 if (!ValueConstantRangeAA)
321 return false;
322 ConstantRange Range = UseAssumed ? ValueConstantRangeAA->getAssumed()
323 : ValueConstantRangeAA->getKnown();
324 if (Range.isFullSet())
325 return false;
326
327 // We can only use the lower part of the range because the upper part can
328 // be higher than what the value can really be.
329 if (GetMinOffset)
330 ROffset = Range.getSignedMin();
331 else
332 ROffset = Range.getSignedMax();
333 return true;
334 };
335
336 return Val->stripAndAccumulateConstantOffsets(DL, Offset, AllowNonInbounds,
337 /* AllowInvariant */ true,
338 AttributorAnalysis);
339}
340
341static const Value *
343 const Value *Ptr, int64_t &BytesOffset,
344 const DataLayout &DL, bool AllowNonInbounds = false) {
345 APInt OffsetAPInt(DL.getIndexTypeSizeInBits(Ptr->getType()), 0);
346 const Value *Base =
347 stripAndAccumulateOffsets(A, QueryingAA, Ptr, DL, OffsetAPInt,
348 /* GetMinOffset */ true, AllowNonInbounds);
349
350 BytesOffset = OffsetAPInt.getSExtValue();
351 return Base;
352}
353
354/// Clamp the information known for all returned values of a function
355/// (identified by \p QueryingAA) into \p S.
356template <typename AAType, typename StateType = typename AAType::StateType,
357 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind,
358 bool RecurseForSelectAndPHI = true>
360 Attributor &A, const AAType &QueryingAA, StateType &S,
361 const IRPosition::CallBaseContext *CBContext = nullptr) {
362 LLVM_DEBUG(dbgs() << "[Attributor] Clamp return value states for "
363 << QueryingAA << " into " << S << "\n");
364
365 assert((QueryingAA.getIRPosition().getPositionKind() ==
367 QueryingAA.getIRPosition().getPositionKind() ==
369 "Can only clamp returned value states for a function returned or call "
370 "site returned position!");
371
372 // Use an optional state as there might not be any return values and we want
373 // to join (IntegerState::operator&) the state of all there are.
374 std::optional<StateType> T;
375
376 // Callback for each possibly returned value.
377 auto CheckReturnValue = [&](Value &RV) -> bool {
378 const IRPosition &RVPos = IRPosition::value(RV, CBContext);
379 // If possible, use the hasAssumedIRAttr interface.
380 if (Attribute::isEnumAttrKind(IRAttributeKind)) {
381 bool IsKnown;
383 A, &QueryingAA, RVPos, DepClassTy::REQUIRED, IsKnown);
384 }
385
386 const AAType *AA =
387 A.getAAFor<AAType>(QueryingAA, RVPos, DepClassTy::REQUIRED);
388 if (!AA)
389 return false;
390 LLVM_DEBUG(dbgs() << "[Attributor] RV: " << RV
391 << " AA: " << AA->getAsStr(&A) << " @ " << RVPos << "\n");
392 const StateType &AAS = AA->getState();
393 if (!T)
394 T = StateType::getBestState(AAS);
395 *T &= AAS;
396 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS << " RV State: " << T
397 << "\n");
398 return T->isValidState();
399 };
400
401 if (!A.checkForAllReturnedValues(CheckReturnValue, QueryingAA,
403 RecurseForSelectAndPHI))
404 S.indicatePessimisticFixpoint();
405 else if (T)
406 S ^= *T;
407}
408
409namespace {
410/// Helper class for generic deduction: return value -> returned position.
411template <typename AAType, typename BaseType,
412 typename StateType = typename BaseType::StateType,
413 bool PropagateCallBaseContext = false,
414 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind,
415 bool RecurseForSelectAndPHI = true>
416struct AAReturnedFromReturnedValues : public BaseType {
417 AAReturnedFromReturnedValues(const IRPosition &IRP, Attributor &A)
418 : BaseType(IRP, A) {}
419
420 /// See AbstractAttribute::updateImpl(...).
421 ChangeStatus updateImpl(Attributor &A) override {
422 StateType S(StateType::getBestState(this->getState()));
423 clampReturnedValueStates<AAType, StateType, IRAttributeKind,
424 RecurseForSelectAndPHI>(
425 A, *this, S,
426 PropagateCallBaseContext ? this->getCallBaseContext() : nullptr);
427 // TODO: If we know we visited all returned values, thus no are assumed
428 // dead, we can take the known information from the state T.
429 return clampStateAndIndicateChange<StateType>(this->getState(), S);
430 }
431};
432
433/// Clamp the information known at all call sites for a given argument
434/// (identified by \p QueryingAA) into \p S.
435template <typename AAType, typename StateType = typename AAType::StateType,
436 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind>
437static void clampCallSiteArgumentStates(Attributor &A, const AAType &QueryingAA,
438 StateType &S) {
439 LLVM_DEBUG(dbgs() << "[Attributor] Clamp call site argument states for "
440 << QueryingAA << " into " << S << "\n");
441
442 assert(QueryingAA.getIRPosition().getPositionKind() ==
444 "Can only clamp call site argument states for an argument position!");
445
446 // Use an optional state as there might not be any return values and we want
447 // to join (IntegerState::operator&) the state of all there are.
448 std::optional<StateType> T;
449
450 // The argument number which is also the call site argument number.
451 unsigned ArgNo = QueryingAA.getIRPosition().getCallSiteArgNo();
452
453 auto CallSiteCheck = [&](AbstractCallSite ACS) {
454 const IRPosition &ACSArgPos = IRPosition::callsite_argument(ACS, ArgNo);
455 // Check if a coresponding argument was found or if it is on not associated
456 // (which can happen for callback calls).
457 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
458 return false;
459
460 // If possible, use the hasAssumedIRAttr interface.
461 if (Attribute::isEnumAttrKind(IRAttributeKind)) {
462 bool IsKnown;
464 A, &QueryingAA, ACSArgPos, DepClassTy::REQUIRED, IsKnown);
465 }
466
467 const AAType *AA =
468 A.getAAFor<AAType>(QueryingAA, ACSArgPos, DepClassTy::REQUIRED);
469 if (!AA)
470 return false;
471 LLVM_DEBUG(dbgs() << "[Attributor] ACS: " << *ACS.getInstruction()
472 << " AA: " << AA->getAsStr(&A) << " @" << ACSArgPos
473 << "\n");
474 const StateType &AAS = AA->getState();
475 if (!T)
476 T = StateType::getBestState(AAS);
477 *T &= AAS;
478 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS << " CSA State: " << T
479 << "\n");
480 return T->isValidState();
481 };
482
483 bool UsedAssumedInformation = false;
484 if (!A.checkForAllCallSites(CallSiteCheck, QueryingAA, true,
485 UsedAssumedInformation))
486 S.indicatePessimisticFixpoint();
487 else if (T)
488 S ^= *T;
489}
490
491/// This function is the bridge between argument position and the call base
492/// context.
493template <typename AAType, typename BaseType,
494 typename StateType = typename AAType::StateType,
495 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind>
496bool getArgumentStateFromCallBaseContext(Attributor &A,
497 BaseType &QueryingAttribute,
498 IRPosition &Pos, StateType &State) {
500 "Expected an 'argument' position !");
501 const CallBase *CBContext = Pos.getCallBaseContext();
502 if (!CBContext)
503 return false;
504
505 int ArgNo = Pos.getCallSiteArgNo();
506 assert(ArgNo >= 0 && "Invalid Arg No!");
507 const IRPosition CBArgPos = IRPosition::callsite_argument(*CBContext, ArgNo);
508
509 // If possible, use the hasAssumedIRAttr interface.
510 if (Attribute::isEnumAttrKind(IRAttributeKind)) {
511 bool IsKnown;
513 A, &QueryingAttribute, CBArgPos, DepClassTy::REQUIRED, IsKnown);
514 }
515
516 const auto *AA =
517 A.getAAFor<AAType>(QueryingAttribute, CBArgPos, DepClassTy::REQUIRED);
518 if (!AA)
519 return false;
520 const StateType &CBArgumentState =
521 static_cast<const StateType &>(AA->getState());
522
523 LLVM_DEBUG(dbgs() << "[Attributor] Briding Call site context to argument"
524 << "Position:" << Pos << "CB Arg state:" << CBArgumentState
525 << "\n");
526
527 // NOTE: If we want to do call site grouping it should happen here.
528 State ^= CBArgumentState;
529 return true;
530}
531
532/// Helper class for generic deduction: call site argument -> argument position.
533template <typename AAType, typename BaseType,
534 typename StateType = typename AAType::StateType,
535 bool BridgeCallBaseContext = false,
536 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind>
537struct AAArgumentFromCallSiteArguments : public BaseType {
538 AAArgumentFromCallSiteArguments(const IRPosition &IRP, Attributor &A)
539 : BaseType(IRP, A) {}
540
541 /// See AbstractAttribute::updateImpl(...).
542 ChangeStatus updateImpl(Attributor &A) override {
543 StateType S = StateType::getBestState(this->getState());
544
545 if (BridgeCallBaseContext) {
546 bool Success =
547 getArgumentStateFromCallBaseContext<AAType, BaseType, StateType,
548 IRAttributeKind>(
549 A, *this, this->getIRPosition(), S);
550 if (Success)
551 return clampStateAndIndicateChange<StateType>(this->getState(), S);
552 }
553 clampCallSiteArgumentStates<AAType, StateType, IRAttributeKind>(A, *this,
554 S);
555
556 // TODO: If we know we visited all incoming values, thus no are assumed
557 // dead, we can take the known information from the state T.
558 return clampStateAndIndicateChange<StateType>(this->getState(), S);
559 }
560};
561
562/// Helper class for generic replication: function returned -> cs returned.
563template <typename AAType, typename BaseType,
564 typename StateType = typename BaseType::StateType,
565 bool IntroduceCallBaseContext = false,
566 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind>
567struct AACalleeToCallSite : public BaseType {
568 AACalleeToCallSite(const IRPosition &IRP, Attributor &A) : BaseType(IRP, A) {}
569
570 /// See AbstractAttribute::updateImpl(...).
571 ChangeStatus updateImpl(Attributor &A) override {
572 auto IRPKind = this->getIRPosition().getPositionKind();
574 IRPKind == IRPosition::IRP_CALL_SITE) &&
575 "Can only wrap function returned positions for call site "
576 "returned positions!");
577 auto &S = this->getState();
578
579 CallBase &CB = cast<CallBase>(this->getAnchorValue());
580 if (IntroduceCallBaseContext)
581 LLVM_DEBUG(dbgs() << "[Attributor] Introducing call base context:" << CB
582 << "\n");
583
584 ChangeStatus Changed = ChangeStatus::UNCHANGED;
585 auto CalleePred = [&](ArrayRef<const Function *> Callees) {
586 for (const Function *Callee : Callees) {
587 IRPosition FnPos =
589 ? IRPosition::returned(*Callee,
590 IntroduceCallBaseContext ? &CB : nullptr)
591 : IRPosition::function(
592 *Callee, IntroduceCallBaseContext ? &CB : nullptr);
593 // If possible, use the hasAssumedIRAttr interface.
594 if (Attribute::isEnumAttrKind(IRAttributeKind)) {
595 bool IsKnown;
597 A, this, FnPos, DepClassTy::REQUIRED, IsKnown))
598 return false;
599 continue;
600 }
601
602 const AAType *AA =
603 A.getAAFor<AAType>(*this, FnPos, DepClassTy::REQUIRED);
604 if (!AA)
605 return false;
606 Changed |= clampStateAndIndicateChange(S, AA->getState());
607 if (S.isAtFixpoint())
608 return S.isValidState();
609 }
610 return true;
611 };
612 if (!A.checkForAllCallees(CalleePred, *this, CB))
613 return S.indicatePessimisticFixpoint();
614 return Changed;
615 }
616};
617
618/// Helper function to accumulate uses.
619template <class AAType, typename StateType = typename AAType::StateType>
620static void followUsesInContext(AAType &AA, Attributor &A,
622 const Instruction *CtxI,
624 StateType &State) {
625 auto EIt = Explorer.begin(CtxI), EEnd = Explorer.end(CtxI);
626 for (unsigned u = 0; u < Uses.size(); ++u) {
627 const Use *U = Uses[u];
628 if (const Instruction *UserI = dyn_cast<Instruction>(U->getUser())) {
629 bool Found = Explorer.findInContextOf(UserI, EIt, EEnd);
630 if (Found && AA.followUseInMBEC(A, U, UserI, State))
631 Uses.insert_range(llvm::make_pointer_range(UserI->uses()));
632 }
633 }
634}
635
636/// Use the must-be-executed-context around \p I to add information into \p S.
637/// The AAType class is required to have `followUseInMBEC` method with the
638/// following signature and behaviour:
639///
640/// bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I)
641/// U - Underlying use.
642/// I - The user of the \p U.
643/// Returns true if the value should be tracked transitively.
644///
645template <class AAType, typename StateType = typename AAType::StateType>
646static void followUsesInMBEC(AAType &AA, Attributor &A, StateType &S,
647 Instruction &CtxI) {
648 const Value &Val = AA.getIRPosition().getAssociatedValue();
649 if (isa<ConstantData>(Val))
650 return;
651
653 A.getInfoCache().getMustBeExecutedContextExplorer();
654 if (!Explorer)
655 return;
656
657 // Container for (transitive) uses of the associated value.
659 for (const Use &U : Val.uses())
660 Uses.insert(&U);
661
662 followUsesInContext<AAType>(AA, A, *Explorer, &CtxI, Uses, S);
663
664 if (S.isAtFixpoint())
665 return;
666
668 auto Pred = [&](const Instruction *I) {
669 if (const CondBrInst *Br = dyn_cast<CondBrInst>(I))
670 BrInsts.push_back(Br);
671 return true;
672 };
673
674 // Here, accumulate conditional branch instructions in the context. We
675 // explore the child paths and collect the known states. The disjunction of
676 // those states can be merged to its own state. Let ParentState_i be a state
677 // to indicate the known information for an i-th branch instruction in the
678 // context. ChildStates are created for its successors respectively.
679 //
680 // ParentS_1 = ChildS_{1, 1} /\ ChildS_{1, 2} /\ ... /\ ChildS_{1, n_1}
681 // ParentS_2 = ChildS_{2, 1} /\ ChildS_{2, 2} /\ ... /\ ChildS_{2, n_2}
682 // ...
683 // ParentS_m = ChildS_{m, 1} /\ ChildS_{m, 2} /\ ... /\ ChildS_{m, n_m}
684 //
685 // Known State |= ParentS_1 \/ ParentS_2 \/... \/ ParentS_m
686 //
687 // FIXME: Currently, recursive branches are not handled. For example, we
688 // can't deduce that ptr must be dereferenced in below function.
689 //
690 // void f(int a, int c, int *ptr) {
691 // if(a)
692 // if (b) {
693 // *ptr = 0;
694 // } else {
695 // *ptr = 1;
696 // }
697 // else {
698 // if (b) {
699 // *ptr = 0;
700 // } else {
701 // *ptr = 1;
702 // }
703 // }
704 // }
705
706 Explorer->checkForAllContext(&CtxI, Pred);
707 for (const CondBrInst *Br : BrInsts) {
708 StateType ParentState;
709
710 // The known state of the parent state is a conjunction of children's
711 // known states so it is initialized with a best state.
712 ParentState.indicateOptimisticFixpoint();
713
714 for (const BasicBlock *BB : Br->successors()) {
715 StateType ChildState;
716
717 size_t BeforeSize = Uses.size();
718 followUsesInContext(AA, A, *Explorer, &BB->front(), Uses, ChildState);
719
720 // Erase uses which only appear in the child.
721 for (auto It = Uses.begin() + BeforeSize; It != Uses.end();)
722 It = Uses.erase(It);
723
724 ParentState &= ChildState;
725 }
726
727 // Use only known state.
728 S += ParentState;
729 }
730}
731} // namespace
732
733/// ------------------------ PointerInfo ---------------------------------------
734
735namespace llvm {
736namespace AA {
737namespace PointerInfo {
738
739struct State;
740
741} // namespace PointerInfo
742} // namespace AA
743
744/// Helper for AA::PointerInfo::Access DenseMap/Set usage.
745template <>
748 static inline Access getEmptyKey();
749 static inline Access getTombstoneKey();
750 static unsigned getHashValue(const Access &A);
751 static bool isEqual(const Access &LHS, const Access &RHS);
752};
753
754/// Helper that allows RangeTy as a key in a DenseMap.
755template <> struct DenseMapInfo<AA::RangeTy> {
756 static inline AA::RangeTy getEmptyKey() {
757 auto EmptyKey = DenseMapInfo<int64_t>::getEmptyKey();
758 return AA::RangeTy{EmptyKey, EmptyKey};
759 }
760
761 static inline AA::RangeTy getTombstoneKey() {
762 auto TombstoneKey = DenseMapInfo<int64_t>::getTombstoneKey();
763 return AA::RangeTy{TombstoneKey, TombstoneKey};
764 }
765
771
772 static bool isEqual(const AA::RangeTy &A, const AA::RangeTy B) {
773 return A == B;
774 }
775};
776
777/// Helper for AA::PointerInfo::Access DenseMap/Set usage ignoring everythign
778/// but the instruction
779struct AccessAsInstructionInfo : DenseMapInfo<Instruction *> {
782 static inline Access getEmptyKey();
783 static inline Access getTombstoneKey();
784 static unsigned getHashValue(const Access &A);
785 static bool isEqual(const Access &LHS, const Access &RHS);
786};
787
788} // namespace llvm
789
790/// A type to track pointer/struct usage and accesses for AAPointerInfo.
792 /// Return the best possible representable state.
793 static State getBestState(const State &SIS) { return State(); }
794
795 /// Return the worst possible representable state.
796 static State getWorstState(const State &SIS) {
797 State R;
798 R.indicatePessimisticFixpoint();
799 return R;
800 }
801
802 State() = default;
803 State(State &&SIS) = default;
804
805 const State &getAssumed() const { return *this; }
806
807 /// See AbstractState::isValidState().
808 bool isValidState() const override { return BS.isValidState(); }
809
810 /// See AbstractState::isAtFixpoint().
811 bool isAtFixpoint() const override { return BS.isAtFixpoint(); }
812
813 /// See AbstractState::indicateOptimisticFixpoint().
815 BS.indicateOptimisticFixpoint();
817 }
818
819 /// See AbstractState::indicatePessimisticFixpoint().
821 BS.indicatePessimisticFixpoint();
823 }
824
825 State &operator=(const State &R) {
826 if (this == &R)
827 return *this;
828 BS = R.BS;
829 AccessList = R.AccessList;
830 OffsetBins = R.OffsetBins;
831 RemoteIMap = R.RemoteIMap;
832 ReturnedOffsets = R.ReturnedOffsets;
833 return *this;
834 }
835
837 if (this == &R)
838 return *this;
839 std::swap(BS, R.BS);
840 std::swap(AccessList, R.AccessList);
841 std::swap(OffsetBins, R.OffsetBins);
842 std::swap(RemoteIMap, R.RemoteIMap);
843 std::swap(ReturnedOffsets, R.ReturnedOffsets);
844 return *this;
845 }
846
847 /// Add a new Access to the state at offset \p Offset and with size \p Size.
848 /// The access is associated with \p I, writes \p Content (if anything), and
849 /// is of kind \p Kind. If an Access already exists for the same \p I and same
850 /// \p RemoteI, the two are combined, potentially losing information about
851 /// offset and size. The resulting access must now be moved from its original
852 /// OffsetBin to the bin for its new offset.
853 ///
854 /// \Returns CHANGED, if the state changed, UNCHANGED otherwise.
856 Instruction &I, std::optional<Value *> Content,
858 Instruction *RemoteI = nullptr);
859
862 int64_t numOffsetBins() const { return OffsetBins.size(); }
863
864 const AAPointerInfo::Access &getAccess(unsigned Index) const {
865 return AccessList[Index];
866 }
867
868protected:
869 // Every memory instruction results in an Access object. We maintain a list of
870 // all Access objects that we own, along with the following maps:
871 //
872 // - OffsetBins: RangeTy -> { Access }
873 // - RemoteIMap: RemoteI x LocalI -> Access
874 //
875 // A RemoteI is any instruction that accesses memory. RemoteI is different
876 // from LocalI if and only if LocalI is a call; then RemoteI is some
877 // instruction in the callgraph starting from LocalI. Multiple paths in the
878 // callgraph from LocalI to RemoteI may produce multiple accesses, but these
879 // are all combined into a single Access object. This may result in loss of
880 // information in RangeTy in the Access object.
884
885 /// Flag to determine if the underlying pointer is reaching a return statement
886 /// in the associated function or not. Returns in other functions cause
887 /// invalidation.
889
890 /// See AAPointerInfo::forallInterferingAccesses.
891 template <typename F>
893 if (!isValidState() || !ReturnedOffsets.isUnassigned())
894 return false;
895
896 for (const auto &It : OffsetBins) {
897 AA::RangeTy ItRange = It.getFirst();
898 if (!Range.mayOverlap(ItRange))
899 continue;
900 bool IsExact = Range == ItRange && !Range.offsetOrSizeAreUnknown();
901 for (auto Index : It.getSecond()) {
902 auto &Access = AccessList[Index];
903 if (!CB(Access, IsExact))
904 return false;
905 }
906 }
907 return true;
908 }
909
910 /// See AAPointerInfo::forallInterferingAccesses.
911 template <typename F>
913 AA::RangeTy &Range) const {
914 if (!isValidState() || !ReturnedOffsets.isUnassigned())
915 return false;
916
917 auto LocalList = RemoteIMap.find(&I);
918 if (LocalList == RemoteIMap.end()) {
919 return true;
920 }
921
922 for (unsigned Index : LocalList->getSecond()) {
923 for (auto &R : AccessList[Index]) {
924 Range &= R;
925 if (Range.offsetAndSizeAreUnknown())
926 break;
927 }
928 }
930 }
931
932private:
933 /// State to track fixpoint and validity.
934 BooleanState BS;
935};
936
939 std::optional<Value *> Content, AAPointerInfo::AccessKind Kind, Type *Ty,
940 Instruction *RemoteI) {
941 RemoteI = RemoteI ? RemoteI : &I;
942
943 // Check if we have an access for this instruction, if not, simply add it.
944 auto &LocalList = RemoteIMap[RemoteI];
945 bool AccExists = false;
946 unsigned AccIndex = AccessList.size();
947 for (auto Index : LocalList) {
948 auto &A = AccessList[Index];
949 if (A.getLocalInst() == &I) {
950 AccExists = true;
951 AccIndex = Index;
952 break;
953 }
954 }
955
956 auto AddToBins = [&](const AAPointerInfo::RangeList &ToAdd) {
957 LLVM_DEBUG(if (ToAdd.size()) dbgs()
958 << "[AAPointerInfo] Inserting access in new offset bins\n";);
959
960 for (auto Key : ToAdd) {
961 LLVM_DEBUG(dbgs() << " key " << Key << "\n");
962 OffsetBins[Key].insert(AccIndex);
963 }
964 };
965
966 if (!AccExists) {
967 AccessList.emplace_back(&I, RemoteI, Ranges, Content, Kind, Ty);
968 assert((AccessList.size() == AccIndex + 1) &&
969 "New Access should have been at AccIndex");
970 LocalList.push_back(AccIndex);
971 AddToBins(AccessList[AccIndex].getRanges());
973 }
974
975 // Combine the new Access with the existing Access, and then update the
976 // mapping in the offset bins.
977 AAPointerInfo::Access Acc(&I, RemoteI, Ranges, Content, Kind, Ty);
978 auto &Current = AccessList[AccIndex];
979 auto Before = Current;
980 Current &= Acc;
981 if (Current == Before)
983
984 auto &ExistingRanges = Before.getRanges();
985 auto &NewRanges = Current.getRanges();
986
987 // Ranges that are in the old access but not the new access need to be removed
988 // from the offset bins.
990 AAPointerInfo::RangeList::set_difference(ExistingRanges, NewRanges, ToRemove);
991 LLVM_DEBUG(if (ToRemove.size()) dbgs()
992 << "[AAPointerInfo] Removing access from old offset bins\n";);
993
994 for (auto Key : ToRemove) {
995 LLVM_DEBUG(dbgs() << " key " << Key << "\n");
996 assert(OffsetBins.count(Key) && "Existing Access must be in some bin.");
997 auto &Bin = OffsetBins[Key];
998 assert(Bin.count(AccIndex) &&
999 "Expected bin to actually contain the Access.");
1000 Bin.erase(AccIndex);
1001 }
1002
1003 // Ranges that are in the new access but not the old access need to be added
1004 // to the offset bins.
1006 AAPointerInfo::RangeList::set_difference(NewRanges, ExistingRanges, ToAdd);
1007 AddToBins(ToAdd);
1008 return ChangeStatus::CHANGED;
1009}
1010
1011namespace {
1012
1013#ifndef NDEBUG
1015 const AAPointerInfo::OffsetInfo &OI) {
1016 OS << llvm::interleaved_array(OI);
1017 return OS;
1018}
1019#endif // NDEBUG
1020
1021struct AAPointerInfoImpl
1022 : public StateWrapper<AA::PointerInfo::State, AAPointerInfo> {
1024 AAPointerInfoImpl(const IRPosition &IRP, Attributor &A) : BaseTy(IRP) {}
1025
1026 /// See AbstractAttribute::getAsStr().
1027 const std::string getAsStr(Attributor *A) const override {
1028 return std::string("PointerInfo ") +
1029 (isValidState() ? (std::string("#") +
1030 std::to_string(OffsetBins.size()) + " bins")
1031 : "<invalid>") +
1032 (reachesReturn()
1033 ? (" (returned:" +
1034 join(map_range(ReturnedOffsets,
1035 [](int64_t O) { return std::to_string(O); }),
1036 ", ") +
1037 ")")
1038 : "");
1039 }
1040
1041 /// See AbstractAttribute::manifest(...).
1042 ChangeStatus manifest(Attributor &A) override {
1043 return AAPointerInfo::manifest(A);
1044 }
1045
1046 const_bin_iterator begin() const override { return State::begin(); }
1047 const_bin_iterator end() const override { return State::end(); }
1048 int64_t numOffsetBins() const override { return State::numOffsetBins(); }
1049 bool reachesReturn() const override {
1050 return !ReturnedOffsets.isUnassigned();
1051 }
1052 void addReturnedOffsetsTo(OffsetInfo &OI) const override {
1053 if (ReturnedOffsets.isUnknown()) {
1054 OI.setUnknown();
1055 return;
1056 }
1057
1058 OffsetInfo MergedOI;
1059 for (auto Offset : ReturnedOffsets) {
1060 OffsetInfo TmpOI = OI;
1061 TmpOI.addToAll(Offset);
1062 MergedOI.merge(TmpOI);
1063 }
1064 OI = std::move(MergedOI);
1065 }
1066
1067 ChangeStatus setReachesReturn(const OffsetInfo &ReachedReturnedOffsets) {
1068 if (ReturnedOffsets.isUnknown())
1069 return ChangeStatus::UNCHANGED;
1070 if (ReachedReturnedOffsets.isUnknown()) {
1071 ReturnedOffsets.setUnknown();
1072 return ChangeStatus::CHANGED;
1073 }
1074 if (ReturnedOffsets.merge(ReachedReturnedOffsets))
1075 return ChangeStatus::CHANGED;
1076 return ChangeStatus::UNCHANGED;
1077 }
1078
1079 bool forallInterferingAccesses(
1080 AA::RangeTy Range,
1081 function_ref<bool(const AAPointerInfo::Access &, bool)> CB)
1082 const override {
1083 return State::forallInterferingAccesses(Range, CB);
1084 }
1085
1086 bool forallInterferingAccesses(
1087 Attributor &A, const AbstractAttribute &QueryingAA, Instruction &I,
1088 bool FindInterferingWrites, bool FindInterferingReads,
1089 function_ref<bool(const Access &, bool)> UserCB, bool &HasBeenWrittenTo,
1090 AA::RangeTy &Range,
1091 function_ref<bool(const Access &)> SkipCB) const override {
1092 HasBeenWrittenTo = false;
1093
1094 SmallPtrSet<const Access *, 8> DominatingWrites;
1095 SmallVector<std::pair<const Access *, bool>, 8> InterferingAccesses;
1096
1097 Function &Scope = *I.getFunction();
1098 bool IsKnownNoSync;
1099 bool IsAssumedNoSync = AA::hasAssumedIRAttr<Attribute::NoSync>(
1100 A, &QueryingAA, IRPosition::function(Scope), DepClassTy::OPTIONAL,
1101 IsKnownNoSync);
1102 const auto *ExecDomainAA = A.lookupAAFor<AAExecutionDomain>(
1103 IRPosition::function(Scope), &QueryingAA, DepClassTy::NONE);
1104 bool AllInSameNoSyncFn = IsAssumedNoSync;
1105 bool InstIsExecutedByInitialThreadOnly =
1106 ExecDomainAA && ExecDomainAA->isExecutedByInitialThreadOnly(I);
1107
1108 // If the function is not ending in aligned barriers, we need the stores to
1109 // be in aligned barriers. The load being in one is not sufficient since the
1110 // store might be executed by a thread that disappears after, causing the
1111 // aligned barrier guarding the load to unblock and the load to read a value
1112 // that has no CFG path to the load.
1113 bool InstIsExecutedInAlignedRegion =
1114 FindInterferingReads && ExecDomainAA &&
1115 ExecDomainAA->isExecutedInAlignedRegion(A, I);
1116
1117 if (InstIsExecutedInAlignedRegion || InstIsExecutedByInitialThreadOnly)
1118 A.recordDependence(*ExecDomainAA, QueryingAA, DepClassTy::OPTIONAL);
1119
1120 InformationCache &InfoCache = A.getInfoCache();
1121 bool IsThreadLocalObj =
1122 AA::isAssumedThreadLocalObject(A, getAssociatedValue(), *this);
1123
1124 // Helper to determine if we need to consider threading, which we cannot
1125 // right now. However, if the function is (assumed) nosync or the thread
1126 // executing all instructions is the main thread only we can ignore
1127 // threading. Also, thread-local objects do not require threading reasoning.
1128 // Finally, we can ignore threading if either access is executed in an
1129 // aligned region.
1130 auto CanIgnoreThreadingForInst = [&](const Instruction &I) -> bool {
1131 if (IsThreadLocalObj || AllInSameNoSyncFn)
1132 return true;
1133 const auto *FnExecDomainAA =
1134 I.getFunction() == &Scope
1135 ? ExecDomainAA
1136 : A.lookupAAFor<AAExecutionDomain>(
1137 IRPosition::function(*I.getFunction()), &QueryingAA,
1138 DepClassTy::NONE);
1139 if (!FnExecDomainAA)
1140 return false;
1141 if (InstIsExecutedInAlignedRegion ||
1142 (FindInterferingWrites &&
1143 FnExecDomainAA->isExecutedInAlignedRegion(A, I))) {
1144 A.recordDependence(*FnExecDomainAA, QueryingAA, DepClassTy::OPTIONAL);
1145 return true;
1146 }
1147 if (InstIsExecutedByInitialThreadOnly &&
1148 FnExecDomainAA->isExecutedByInitialThreadOnly(I)) {
1149 A.recordDependence(*FnExecDomainAA, QueryingAA, DepClassTy::OPTIONAL);
1150 return true;
1151 }
1152 return false;
1153 };
1154
1155 // Helper to determine if the access is executed by the same thread as the
1156 // given instruction, for now it is sufficient to avoid any potential
1157 // threading effects as we cannot deal with them anyway.
1158 auto CanIgnoreThreading = [&](const Access &Acc) -> bool {
1159 return CanIgnoreThreadingForInst(*Acc.getRemoteInst()) ||
1160 (Acc.getRemoteInst() != Acc.getLocalInst() &&
1161 CanIgnoreThreadingForInst(*Acc.getLocalInst()));
1162 };
1163
1164 // TODO: Use inter-procedural reachability and dominance.
1165 bool IsKnownNoRecurse;
1167 A, this, IRPosition::function(Scope), DepClassTy::OPTIONAL,
1168 IsKnownNoRecurse);
1169
1170 // TODO: Use reaching kernels from AAKernelInfo (or move it to
1171 // AAExecutionDomain) such that we allow scopes other than kernels as long
1172 // as the reaching kernels are disjoint.
1173 bool InstInKernel = A.getInfoCache().isKernel(Scope);
1174 bool ObjHasKernelLifetime = false;
1175 const bool UseDominanceReasoning =
1176 FindInterferingWrites && IsKnownNoRecurse;
1177 const DominatorTree *DT =
1178 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(Scope);
1179
1180 // Helper to check if a value has "kernel lifetime", that is it will not
1181 // outlive a GPU kernel. This is true for shared, constant, and local
1182 // globals on AMD and NVIDIA GPUs.
1183 auto HasKernelLifetime = [&](Value *V, Module &M) {
1184 if (!AA::isGPU(M))
1185 return false;
1186 unsigned VAS = V->getType()->getPointerAddressSpace();
1187 return AA::isGPUSharedAddressSpace(M, VAS) ||
1190 };
1191
1192 // The IsLiveInCalleeCB will be used by the AA::isPotentiallyReachable query
1193 // to determine if we should look at reachability from the callee. For
1194 // certain pointers we know the lifetime and we do not have to step into the
1195 // callee to determine reachability as the pointer would be dead in the
1196 // callee. See the conditional initialization below.
1197 std::function<bool(const Function &)> IsLiveInCalleeCB;
1198
1199 if (auto *AI = dyn_cast<AllocaInst>(&getAssociatedValue())) {
1200 // If the alloca containing function is not recursive the alloca
1201 // must be dead in the callee.
1202 const Function *AIFn = AI->getFunction();
1203 ObjHasKernelLifetime = A.getInfoCache().isKernel(*AIFn);
1204 bool IsKnownNoRecurse;
1206 A, this, IRPosition::function(*AIFn), DepClassTy::OPTIONAL,
1207 IsKnownNoRecurse)) {
1208 IsLiveInCalleeCB = [AIFn](const Function &Fn) { return AIFn != &Fn; };
1209 }
1210 } else if (auto *GV = dyn_cast<GlobalValue>(&getAssociatedValue())) {
1211 // If the global has kernel lifetime we can stop if we reach a kernel
1212 // as it is "dead" in the (unknown) callees.
1213 ObjHasKernelLifetime = HasKernelLifetime(GV, *GV->getParent());
1214 if (ObjHasKernelLifetime)
1215 IsLiveInCalleeCB = [&A](const Function &Fn) {
1216 return !A.getInfoCache().isKernel(Fn);
1217 };
1218 }
1219
1220 // Set of accesses/instructions that will overwrite the result and are
1221 // therefore blockers in the reachability traversal.
1222 AA::InstExclusionSetTy ExclusionSet;
1223
1224 auto AccessCB = [&](const Access &Acc, bool Exact) {
1225 Function *AccScope = Acc.getRemoteInst()->getFunction();
1226 bool AccInSameScope = AccScope == &Scope;
1227
1228 // If the object has kernel lifetime we can ignore accesses only reachable
1229 // by other kernels. For now we only skip accesses *in* other kernels.
1230 if (InstInKernel && ObjHasKernelLifetime && !AccInSameScope &&
1231 A.getInfoCache().isKernel(*AccScope))
1232 return true;
1233
1234 if (Exact && Acc.isMustAccess() && Acc.getRemoteInst() != &I) {
1235 if (Acc.isWrite() || (isa<LoadInst>(I) && Acc.isWriteOrAssumption()))
1236 ExclusionSet.insert(Acc.getRemoteInst());
1237 }
1238
1239 if ((!FindInterferingWrites || !Acc.isWriteOrAssumption()) &&
1240 (!FindInterferingReads || !Acc.isRead()))
1241 return true;
1242
1243 bool Dominates = FindInterferingWrites && DT && Exact &&
1244 Acc.isMustAccess() && AccInSameScope &&
1245 DT->dominates(Acc.getRemoteInst(), &I);
1246 if (Dominates)
1247 DominatingWrites.insert(&Acc);
1248
1249 // Track if all interesting accesses are in the same `nosync` function as
1250 // the given instruction.
1251 AllInSameNoSyncFn &= Acc.getRemoteInst()->getFunction() == &Scope;
1252
1253 InterferingAccesses.push_back({&Acc, Exact});
1254 return true;
1255 };
1256 if (!State::forallInterferingAccesses(I, AccessCB, Range))
1257 return false;
1258
1259 HasBeenWrittenTo = !DominatingWrites.empty();
1260
1261 // Dominating writes form a chain, find the least/lowest member.
1262 Instruction *LeastDominatingWriteInst = nullptr;
1263 for (const Access *Acc : DominatingWrites) {
1264 if (!LeastDominatingWriteInst) {
1265 LeastDominatingWriteInst = Acc->getRemoteInst();
1266 } else if (DT->dominates(LeastDominatingWriteInst,
1267 Acc->getRemoteInst())) {
1268 LeastDominatingWriteInst = Acc->getRemoteInst();
1269 }
1270 }
1271
1272 // Helper to determine if we can skip a specific write access.
1273 auto CanSkipAccess = [&](const Access &Acc, bool Exact) {
1274 if (SkipCB && SkipCB(Acc))
1275 return true;
1276 if (!CanIgnoreThreading(Acc))
1277 return false;
1278
1279 // Check read (RAW) dependences and write (WAR) dependences as necessary.
1280 // If we successfully excluded all effects we are interested in, the
1281 // access can be skipped.
1282 bool ReadChecked = !FindInterferingReads;
1283 bool WriteChecked = !FindInterferingWrites;
1284
1285 // If the instruction cannot reach the access, the former does not
1286 // interfere with what the access reads.
1287 if (!ReadChecked) {
1288 if (!AA::isPotentiallyReachable(A, I, *Acc.getRemoteInst(), QueryingAA,
1289 &ExclusionSet, IsLiveInCalleeCB))
1290 ReadChecked = true;
1291 }
1292 // If the instruction cannot be reach from the access, the latter does not
1293 // interfere with what the instruction reads.
1294 if (!WriteChecked) {
1295 if (!AA::isPotentiallyReachable(A, *Acc.getRemoteInst(), I, QueryingAA,
1296 &ExclusionSet, IsLiveInCalleeCB))
1297 WriteChecked = true;
1298 }
1299
1300 // If we still might be affected by the write of the access but there are
1301 // dominating writes in the function of the instruction
1302 // (HasBeenWrittenTo), we can try to reason that the access is overwritten
1303 // by them. This would have happend above if they are all in the same
1304 // function, so we only check the inter-procedural case. Effectively, we
1305 // want to show that there is no call after the dominting write that might
1306 // reach the access, and when it returns reach the instruction with the
1307 // updated value. To this end, we iterate all call sites, check if they
1308 // might reach the instruction without going through another access
1309 // (ExclusionSet) and at the same time might reach the access. However,
1310 // that is all part of AAInterFnReachability.
1311 if (!WriteChecked && HasBeenWrittenTo &&
1312 Acc.getRemoteInst()->getFunction() != &Scope) {
1313
1314 const auto *FnReachabilityAA = A.getAAFor<AAInterFnReachability>(
1315 QueryingAA, IRPosition::function(Scope), DepClassTy::OPTIONAL);
1316 if (FnReachabilityAA) {
1317 // Without going backwards in the call tree, can we reach the access
1318 // from the least dominating write. Do not allow to pass the
1319 // instruction itself either.
1320 bool Inserted = ExclusionSet.insert(&I).second;
1321
1322 if (!FnReachabilityAA->instructionCanReach(
1323 A, *LeastDominatingWriteInst,
1324 *Acc.getRemoteInst()->getFunction(), &ExclusionSet))
1325 WriteChecked = true;
1326
1327 if (Inserted)
1328 ExclusionSet.erase(&I);
1329 }
1330 }
1331
1332 if (ReadChecked && WriteChecked)
1333 return true;
1334
1335 if (!DT || !UseDominanceReasoning)
1336 return false;
1337 if (!DominatingWrites.count(&Acc))
1338 return false;
1339 return LeastDominatingWriteInst != Acc.getRemoteInst();
1340 };
1341
1342 // Run the user callback on all accesses we cannot skip and return if
1343 // that succeeded for all or not.
1344 for (auto &It : InterferingAccesses) {
1345 if ((!AllInSameNoSyncFn && !IsThreadLocalObj && !ExecDomainAA) ||
1346 !CanSkipAccess(*It.first, It.second)) {
1347 if (!UserCB(*It.first, It.second))
1348 return false;
1349 }
1350 }
1351 return true;
1352 }
1353
1354 ChangeStatus translateAndAddStateFromCallee(Attributor &A,
1355 const AAPointerInfo &OtherAA,
1356 CallBase &CB) {
1357 using namespace AA::PointerInfo;
1358 if (!OtherAA.getState().isValidState() || !isValidState())
1359 return indicatePessimisticFixpoint();
1360
1361 ChangeStatus Changed = ChangeStatus::UNCHANGED;
1362 const auto &OtherAAImpl = static_cast<const AAPointerInfoImpl &>(OtherAA);
1363 bool IsByval = OtherAAImpl.getAssociatedArgument()->hasByValAttr();
1364 Changed |= setReachesReturn(OtherAAImpl.ReturnedOffsets);
1365
1366 // Combine the accesses bin by bin.
1367 const auto &State = OtherAAImpl.getState();
1368 for (const auto &It : State) {
1369 for (auto Index : It.getSecond()) {
1370 const auto &RAcc = State.getAccess(Index);
1371 if (IsByval && !RAcc.isRead())
1372 continue;
1373 bool UsedAssumedInformation = false;
1374 AccessKind AK = RAcc.getKind();
1375 auto Content = A.translateArgumentToCallSiteContent(
1376 RAcc.getContent(), CB, *this, UsedAssumedInformation);
1377 AK = AccessKind(AK & (IsByval ? AccessKind::AK_R : AccessKind::AK_RW));
1378 AK = AccessKind(AK | (RAcc.isMayAccess() ? AK_MAY : AK_MUST));
1379
1380 Changed |= addAccess(A, RAcc.getRanges(), CB, Content, AK,
1381 RAcc.getType(), RAcc.getRemoteInst());
1382 }
1383 }
1384 return Changed;
1385 }
1386
1387 ChangeStatus translateAndAddState(Attributor &A, const AAPointerInfo &OtherAA,
1388 const OffsetInfo &Offsets, CallBase &CB,
1389 bool IsMustAcc) {
1390 using namespace AA::PointerInfo;
1391 if (!OtherAA.getState().isValidState() || !isValidState())
1392 return indicatePessimisticFixpoint();
1393
1394 const auto &OtherAAImpl = static_cast<const AAPointerInfoImpl &>(OtherAA);
1395
1396 // Combine the accesses bin by bin.
1397 ChangeStatus Changed = ChangeStatus::UNCHANGED;
1398 const auto &State = OtherAAImpl.getState();
1399 for (const auto &It : State) {
1400 for (auto Index : It.getSecond()) {
1401 const auto &RAcc = State.getAccess(Index);
1402 if (!IsMustAcc && RAcc.isAssumption())
1403 continue;
1404 for (auto Offset : Offsets) {
1405 auto NewRanges = Offset == AA::RangeTy::Unknown
1407 : RAcc.getRanges();
1408 if (!NewRanges.isUnknown()) {
1409 NewRanges.addToAllOffsets(Offset);
1410 }
1411 AccessKind AK = RAcc.getKind();
1412 if (!IsMustAcc)
1413 AK = AccessKind((AK & ~AK_MUST) | AK_MAY);
1414 Changed |= addAccess(A, NewRanges, CB, RAcc.getContent(), AK,
1415 RAcc.getType(), RAcc.getRemoteInst());
1416 }
1417 }
1418 }
1419 return Changed;
1420 }
1421
1422 /// Statistic tracking for all AAPointerInfo implementations.
1423 /// See AbstractAttribute::trackStatistics().
1424 void trackPointerInfoStatistics(const IRPosition &IRP) const {}
1425
1426 /// Dump the state into \p O.
1427 void dumpState(raw_ostream &O) {
1428 for (auto &It : OffsetBins) {
1429 O << "[" << It.first.Offset << "-" << It.first.Offset + It.first.Size
1430 << "] : " << It.getSecond().size() << "\n";
1431 for (auto AccIndex : It.getSecond()) {
1432 auto &Acc = AccessList[AccIndex];
1433 O << " - " << Acc.getKind() << " - " << *Acc.getLocalInst() << "\n";
1434 if (Acc.getLocalInst() != Acc.getRemoteInst())
1435 O << " --> " << *Acc.getRemoteInst()
1436 << "\n";
1437 if (!Acc.isWrittenValueYetUndetermined()) {
1438 if (isa_and_nonnull<Function>(Acc.getWrittenValue()))
1439 O << " - c: func " << Acc.getWrittenValue()->getName()
1440 << "\n";
1441 else if (Acc.getWrittenValue())
1442 O << " - c: " << *Acc.getWrittenValue() << "\n";
1443 else
1444 O << " - c: <unknown>\n";
1445 }
1446 }
1447 }
1448 }
1449};
1450
1451struct AAPointerInfoFloating : public AAPointerInfoImpl {
1453 AAPointerInfoFloating(const IRPosition &IRP, Attributor &A)
1454 : AAPointerInfoImpl(IRP, A) {}
1455
1456 /// Deal with an access and signal if it was handled successfully.
1457 bool handleAccess(Attributor &A, Instruction &I,
1458 std::optional<Value *> Content, AccessKind Kind,
1459 OffsetInfo::VecTy &Offsets, ChangeStatus &Changed,
1460 Type &Ty) {
1461 using namespace AA::PointerInfo;
1463 const DataLayout &DL = A.getDataLayout();
1464 TypeSize AccessSize = DL.getTypeStoreSize(&Ty);
1465 if (!AccessSize.isScalable())
1466 Size = AccessSize.getFixedValue();
1467
1468 // Make a strictly ascending list of offsets as required by addAccess()
1469 SmallVector<int64_t> OffsetsSorted(Offsets.begin(), Offsets.end());
1470 llvm::sort(OffsetsSorted);
1471
1473 if (!VT || VT->getElementCount().isScalable() ||
1474 !Content.value_or(nullptr) || !isa<Constant>(*Content) ||
1475 (*Content)->getType() != VT ||
1476 DL.getTypeStoreSize(VT->getElementType()).isScalable()) {
1477 Changed =
1478 Changed | addAccess(A, {OffsetsSorted, Size}, I, Content, Kind, &Ty);
1479 } else {
1480 // Handle vector stores with constant content element-wise.
1481 // TODO: We could look for the elements or create instructions
1482 // representing them.
1483 // TODO: We need to push the Content into the range abstraction
1484 // (AA::RangeTy) to allow different content values for different
1485 // ranges. ranges. Hence, support vectors storing different values.
1486 Type *ElementType = VT->getElementType();
1487 int64_t ElementSize = DL.getTypeStoreSize(ElementType).getFixedValue();
1488 auto *ConstContent = cast<Constant>(*Content);
1489 Type *Int32Ty = Type::getInt32Ty(ElementType->getContext());
1490 SmallVector<int64_t> ElementOffsets(Offsets.begin(), Offsets.end());
1491
1492 for (int i = 0, e = VT->getElementCount().getFixedValue(); i != e; ++i) {
1493 Value *ElementContent = ConstantExpr::getExtractElement(
1494 ConstContent, ConstantInt::get(Int32Ty, i));
1495
1496 // Add the element access.
1497 Changed = Changed | addAccess(A, {ElementOffsets, ElementSize}, I,
1498 ElementContent, Kind, ElementType);
1499
1500 // Advance the offsets for the next element.
1501 for (auto &ElementOffset : ElementOffsets)
1502 ElementOffset += ElementSize;
1503 }
1504 }
1505 return true;
1506 };
1507
1508 /// See AbstractAttribute::updateImpl(...).
1509 ChangeStatus updateImpl(Attributor &A) override;
1510
1511 /// If the indices to \p GEP can be traced to constants, incorporate all
1512 /// of these into \p UsrOI.
1513 ///
1514 /// \return true iff \p UsrOI is updated.
1515 bool collectConstantsForGEP(Attributor &A, const DataLayout &DL,
1516 OffsetInfo &UsrOI, const OffsetInfo &PtrOI,
1517 const GEPOperator *GEP);
1518
1519 /// See AbstractAttribute::trackStatistics()
1520 void trackStatistics() const override {
1521 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
1522 }
1523};
1524
1525bool AAPointerInfoFloating::collectConstantsForGEP(Attributor &A,
1526 const DataLayout &DL,
1527 OffsetInfo &UsrOI,
1528 const OffsetInfo &PtrOI,
1529 const GEPOperator *GEP) {
1530 unsigned BitWidth = DL.getIndexTypeSizeInBits(GEP->getType());
1531 SmallMapVector<Value *, APInt, 4> VariableOffsets;
1532 APInt ConstantOffset(BitWidth, 0);
1533
1534 assert(!UsrOI.isUnknown() && !PtrOI.isUnknown() &&
1535 "Don't look for constant values if the offset has already been "
1536 "determined to be unknown.");
1537
1538 if (!GEP->collectOffset(DL, BitWidth, VariableOffsets, ConstantOffset)) {
1539 UsrOI.setUnknown();
1540 return true;
1541 }
1542
1543 LLVM_DEBUG(dbgs() << "[AAPointerInfo] GEP offset is "
1544 << (VariableOffsets.empty() ? "" : "not") << " constant "
1545 << *GEP << "\n");
1546
1547 auto Union = PtrOI;
1548 Union.addToAll(ConstantOffset.getSExtValue());
1549
1550 // Each VI in VariableOffsets has a set of potential constant values. Every
1551 // combination of elements, picked one each from these sets, is separately
1552 // added to the original set of offsets, thus resulting in more offsets.
1553 for (const auto &VI : VariableOffsets) {
1554 auto *PotentialConstantsAA = A.getAAFor<AAPotentialConstantValues>(
1555 *this, IRPosition::value(*VI.first), DepClassTy::OPTIONAL);
1556 if (!PotentialConstantsAA || !PotentialConstantsAA->isValidState()) {
1557 UsrOI.setUnknown();
1558 return true;
1559 }
1560
1561 // UndefValue is treated as a zero, which leaves Union as is.
1562 if (PotentialConstantsAA->undefIsContained())
1563 continue;
1564
1565 // We need at least one constant in every set to compute an actual offset.
1566 // Otherwise, we end up pessimizing AAPointerInfo by respecting offsets that
1567 // don't actually exist. In other words, the absence of constant values
1568 // implies that the operation can be assumed dead for now.
1569 auto &AssumedSet = PotentialConstantsAA->getAssumedSet();
1570 if (AssumedSet.empty())
1571 return false;
1572
1573 OffsetInfo Product;
1574 for (const auto &ConstOffset : AssumedSet) {
1575 auto CopyPerOffset = Union;
1576 CopyPerOffset.addToAll(ConstOffset.getSExtValue() *
1577 VI.second.getZExtValue());
1578 Product.merge(CopyPerOffset);
1579 }
1580 Union = Product;
1581 }
1582
1583 UsrOI = std::move(Union);
1584 return true;
1585}
1586
1587ChangeStatus AAPointerInfoFloating::updateImpl(Attributor &A) {
1588 using namespace AA::PointerInfo;
1590 const DataLayout &DL = A.getDataLayout();
1591 Value &AssociatedValue = getAssociatedValue();
1592
1593 DenseMap<Value *, OffsetInfo> OffsetInfoMap;
1594 OffsetInfoMap[&AssociatedValue].insert(0);
1595
1596 auto HandlePassthroughUser = [&](Value *Usr, Value *CurPtr, bool &Follow) {
1597 // One does not simply walk into a map and assign a reference to a possibly
1598 // new location. That can cause an invalidation before the assignment
1599 // happens, like so:
1600 //
1601 // OffsetInfoMap[Usr] = OffsetInfoMap[CurPtr]; /* bad idea! */
1602 //
1603 // The RHS is a reference that may be invalidated by an insertion caused by
1604 // the LHS. So we ensure that the side-effect of the LHS happens first.
1605
1606 assert(OffsetInfoMap.contains(CurPtr) &&
1607 "CurPtr does not exist in the map!");
1608
1609 auto &UsrOI = OffsetInfoMap[Usr];
1610 auto &PtrOI = OffsetInfoMap[CurPtr];
1611 assert(!PtrOI.isUnassigned() &&
1612 "Cannot pass through if the input Ptr was not visited!");
1613 UsrOI.merge(PtrOI);
1614 Follow = true;
1615 return true;
1616 };
1617
1618 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
1619 Value *CurPtr = U.get();
1620 User *Usr = U.getUser();
1621 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Analyze " << *CurPtr << " in " << *Usr
1622 << "\n");
1623 assert(OffsetInfoMap.count(CurPtr) &&
1624 "The current pointer offset should have been seeded!");
1625 assert(!OffsetInfoMap[CurPtr].isUnassigned() &&
1626 "Current pointer should be assigned");
1627
1628 if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Usr)) {
1629 if (CE->isCast())
1630 return HandlePassthroughUser(Usr, CurPtr, Follow);
1631 if (!isa<GEPOperator>(CE)) {
1632 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Unhandled constant user " << *CE
1633 << "\n");
1634 return false;
1635 }
1636 }
1637 if (auto *GEP = dyn_cast<GEPOperator>(Usr)) {
1638 // Note the order here, the Usr access might change the map, CurPtr is
1639 // already in it though.
1640 auto &UsrOI = OffsetInfoMap[Usr];
1641 auto &PtrOI = OffsetInfoMap[CurPtr];
1642
1643 if (UsrOI.isUnknown())
1644 return true;
1645
1646 if (PtrOI.isUnknown()) {
1647 Follow = true;
1648 UsrOI.setUnknown();
1649 return true;
1650 }
1651
1652 Follow = collectConstantsForGEP(A, DL, UsrOI, PtrOI, GEP);
1653 return true;
1654 }
1655 if (isa<PtrToIntInst>(Usr))
1656 return false;
1657 if (isa<CastInst>(Usr) || isa<SelectInst>(Usr))
1658 return HandlePassthroughUser(Usr, CurPtr, Follow);
1659 // Returns are allowed if they are in the associated functions. Users can
1660 // then check the call site return. Returns from other functions can't be
1661 // tracked and are cause for invalidation.
1662 if (auto *RI = dyn_cast<ReturnInst>(Usr)) {
1663 if (RI->getFunction() == getAssociatedFunction()) {
1664 auto &PtrOI = OffsetInfoMap[CurPtr];
1665 Changed |= setReachesReturn(PtrOI);
1666 return true;
1667 }
1668 return false;
1669 }
1670
1671 // For PHIs we need to take care of the recurrence explicitly as the value
1672 // might change while we iterate through a loop. For now, we give up if
1673 // the PHI is not invariant.
1674 if (auto *PHI = dyn_cast<PHINode>(Usr)) {
1675 // Note the order here, the Usr access might change the map, CurPtr is
1676 // already in it though.
1677 auto [PhiIt, IsFirstPHIUser] = OffsetInfoMap.try_emplace(PHI);
1678 auto &UsrOI = PhiIt->second;
1679 auto &PtrOI = OffsetInfoMap[CurPtr];
1680
1681 // Check if the PHI operand has already an unknown offset as we can't
1682 // improve on that anymore.
1683 if (PtrOI.isUnknown()) {
1684 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI operand offset unknown "
1685 << *CurPtr << " in " << *PHI << "\n");
1686 Follow = !UsrOI.isUnknown();
1687 UsrOI.setUnknown();
1688 return true;
1689 }
1690
1691 // Check if the PHI is invariant (so far).
1692 if (UsrOI == PtrOI) {
1693 assert(!PtrOI.isUnassigned() &&
1694 "Cannot assign if the current Ptr was not visited!");
1695 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI is invariant (so far)");
1696 return true;
1697 }
1698
1699 // Check if the PHI operand can be traced back to AssociatedValue.
1700 APInt Offset(
1701 DL.getIndexSizeInBits(CurPtr->getType()->getPointerAddressSpace()),
1702 0);
1703 Value *CurPtrBase = CurPtr->stripAndAccumulateConstantOffsets(
1704 DL, Offset, /* AllowNonInbounds */ true);
1705 auto It = OffsetInfoMap.find(CurPtrBase);
1706 if (It == OffsetInfoMap.end()) {
1707 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI operand is too complex "
1708 << *CurPtr << " in " << *PHI
1709 << " (base: " << *CurPtrBase << ")\n");
1710 UsrOI.setUnknown();
1711 Follow = true;
1712 return true;
1713 }
1714
1715 // Check if the PHI operand is not dependent on the PHI itself. Every
1716 // recurrence is a cyclic net of PHIs in the data flow, and has an
1717 // equivalent Cycle in the control flow. One of those PHIs must be in the
1718 // header of that control flow Cycle. This is independent of the choice of
1719 // Cycles reported by CycleInfo. It is sufficient to check the PHIs in
1720 // every Cycle header; if such a node is marked unknown, this will
1721 // eventually propagate through the whole net of PHIs in the recurrence.
1722 const auto *CI =
1723 A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>(
1724 *PHI->getFunction());
1725 if (mayBeInCycle(CI, cast<Instruction>(Usr), /* HeaderOnly */ true)) {
1726 auto BaseOI = It->getSecond();
1727 BaseOI.addToAll(Offset.getZExtValue());
1728 if (IsFirstPHIUser || BaseOI == UsrOI) {
1729 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI is invariant " << *CurPtr
1730 << " in " << *Usr << "\n");
1731 return HandlePassthroughUser(Usr, CurPtr, Follow);
1732 }
1733
1734 LLVM_DEBUG(
1735 dbgs() << "[AAPointerInfo] PHI operand pointer offset mismatch "
1736 << *CurPtr << " in " << *PHI << "\n");
1737 UsrOI.setUnknown();
1738 Follow = true;
1739 return true;
1740 }
1741
1742 UsrOI.merge(PtrOI);
1743 Follow = true;
1744 return true;
1745 }
1746
1747 if (auto *LoadI = dyn_cast<LoadInst>(Usr)) {
1748 // If the access is to a pointer that may or may not be the associated
1749 // value, e.g. due to a PHI, we cannot assume it will be read.
1750 AccessKind AK = AccessKind::AK_R;
1751 if (getUnderlyingObject(CurPtr) == &AssociatedValue)
1752 AK = AccessKind(AK | AccessKind::AK_MUST);
1753 else
1754 AK = AccessKind(AK | AccessKind::AK_MAY);
1755 if (!handleAccess(A, *LoadI, /* Content */ nullptr, AK,
1756 OffsetInfoMap[CurPtr].Offsets, Changed,
1757 *LoadI->getType()))
1758 return false;
1759
1760 auto IsAssumption = [](Instruction &I) {
1761 if (auto *II = dyn_cast<IntrinsicInst>(&I))
1762 return II->isAssumeLikeIntrinsic();
1763 return false;
1764 };
1765
1766 auto IsImpactedInRange = [&](Instruction *FromI, Instruction *ToI) {
1767 // Check if the assumption and the load are executed together without
1768 // memory modification.
1769 do {
1770 if (FromI->mayWriteToMemory() && !IsAssumption(*FromI))
1771 return true;
1772 FromI = FromI->getNextNode();
1773 } while (FromI && FromI != ToI);
1774 return false;
1775 };
1776
1777 BasicBlock *BB = LoadI->getParent();
1778 auto IsValidAssume = [&](IntrinsicInst &IntrI) {
1779 if (IntrI.getIntrinsicID() != Intrinsic::assume)
1780 return false;
1781 BasicBlock *IntrBB = IntrI.getParent();
1782 if (IntrI.getParent() == BB) {
1783 if (IsImpactedInRange(LoadI->getNextNode(), &IntrI))
1784 return false;
1785 } else {
1786 auto PredIt = pred_begin(IntrBB);
1787 if (PredIt == pred_end(IntrBB))
1788 return false;
1789 if ((*PredIt) != BB)
1790 return false;
1791 if (++PredIt != pred_end(IntrBB))
1792 return false;
1793 for (auto *SuccBB : successors(BB)) {
1794 if (SuccBB == IntrBB)
1795 continue;
1796 if (isa<UnreachableInst>(SuccBB->getTerminator()))
1797 continue;
1798 return false;
1799 }
1800 if (IsImpactedInRange(LoadI->getNextNode(), BB->getTerminator()))
1801 return false;
1802 if (IsImpactedInRange(&IntrBB->front(), &IntrI))
1803 return false;
1804 }
1805 return true;
1806 };
1807
1808 std::pair<Value *, IntrinsicInst *> Assumption;
1809 for (const Use &LoadU : LoadI->uses()) {
1810 if (auto *CmpI = dyn_cast<CmpInst>(LoadU.getUser())) {
1811 if (!CmpI->isEquality() || !CmpI->isTrueWhenEqual())
1812 continue;
1813 for (const Use &CmpU : CmpI->uses()) {
1814 if (auto *IntrI = dyn_cast<IntrinsicInst>(CmpU.getUser())) {
1815 if (!IsValidAssume(*IntrI))
1816 continue;
1817 int Idx = CmpI->getOperandUse(0) == LoadU;
1818 Assumption = {CmpI->getOperand(Idx), IntrI};
1819 break;
1820 }
1821 }
1822 }
1823 if (Assumption.first)
1824 break;
1825 }
1826
1827 // Check if we found an assumption associated with this load.
1828 if (!Assumption.first || !Assumption.second)
1829 return true;
1830
1831 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Assumption found "
1832 << *Assumption.second << ": " << *LoadI
1833 << " == " << *Assumption.first << "\n");
1834 bool UsedAssumedInformation = false;
1835 std::optional<Value *> Content = nullptr;
1836 if (Assumption.first)
1837 Content =
1838 A.getAssumedSimplified(*Assumption.first, *this,
1839 UsedAssumedInformation, AA::Interprocedural);
1840 return handleAccess(
1841 A, *Assumption.second, Content, AccessKind::AK_ASSUMPTION,
1842 OffsetInfoMap[CurPtr].Offsets, Changed, *LoadI->getType());
1843 }
1844
1845 auto HandleStoreLike = [&](Instruction &I, Value *ValueOp, Type &ValueTy,
1846 ArrayRef<Value *> OtherOps, AccessKind AK) {
1847 for (auto *OtherOp : OtherOps) {
1848 if (OtherOp == CurPtr) {
1849 LLVM_DEBUG(
1850 dbgs()
1851 << "[AAPointerInfo] Escaping use in store like instruction " << I
1852 << "\n");
1853 return false;
1854 }
1855 }
1856
1857 // If the access is to a pointer that may or may not be the associated
1858 // value, e.g. due to a PHI, we cannot assume it will be written.
1859 if (getUnderlyingObject(CurPtr) == &AssociatedValue)
1860 AK = AccessKind(AK | AccessKind::AK_MUST);
1861 else
1862 AK = AccessKind(AK | AccessKind::AK_MAY);
1863 bool UsedAssumedInformation = false;
1864 std::optional<Value *> Content = nullptr;
1865 if (ValueOp)
1866 Content = A.getAssumedSimplified(
1867 *ValueOp, *this, UsedAssumedInformation, AA::Interprocedural);
1868 return handleAccess(A, I, Content, AK, OffsetInfoMap[CurPtr].Offsets,
1869 Changed, ValueTy);
1870 };
1871
1872 if (auto *StoreI = dyn_cast<StoreInst>(Usr))
1873 return HandleStoreLike(*StoreI, StoreI->getValueOperand(),
1874 *StoreI->getValueOperand()->getType(),
1875 {StoreI->getValueOperand()}, AccessKind::AK_W);
1876 if (auto *RMWI = dyn_cast<AtomicRMWInst>(Usr))
1877 return HandleStoreLike(*RMWI, nullptr, *RMWI->getValOperand()->getType(),
1878 {RMWI->getValOperand()}, AccessKind::AK_RW);
1879 if (auto *CXI = dyn_cast<AtomicCmpXchgInst>(Usr))
1880 return HandleStoreLike(
1881 *CXI, nullptr, *CXI->getNewValOperand()->getType(),
1882 {CXI->getCompareOperand(), CXI->getNewValOperand()},
1883 AccessKind::AK_RW);
1884
1885 if (auto *CB = dyn_cast<CallBase>(Usr)) {
1886 if (CB->isLifetimeStartOrEnd())
1887 return true;
1888 const auto *TLI =
1889 A.getInfoCache().getTargetLibraryInfoForFunction(*CB->getFunction());
1890 if (getFreedOperand(CB, TLI) == U)
1891 return true;
1892 if (CB->isArgOperand(&U)) {
1893 unsigned ArgNo = CB->getArgOperandNo(&U);
1894 const auto *CSArgPI = A.getAAFor<AAPointerInfo>(
1895 *this, IRPosition::callsite_argument(*CB, ArgNo),
1897 if (!CSArgPI)
1898 return false;
1899 bool IsArgMustAcc = (getUnderlyingObject(CurPtr) == &AssociatedValue);
1900 Changed = translateAndAddState(A, *CSArgPI, OffsetInfoMap[CurPtr], *CB,
1901 IsArgMustAcc) |
1902 Changed;
1903 if (!CSArgPI->reachesReturn())
1904 return isValidState();
1905
1907 if (!Callee || Callee->arg_size() <= ArgNo)
1908 return false;
1909 bool UsedAssumedInformation = false;
1910 auto ReturnedValue = A.getAssumedSimplified(
1911 IRPosition::returned(*Callee), *this, UsedAssumedInformation,
1913 auto *ReturnedArg =
1914 dyn_cast_or_null<Argument>(ReturnedValue.value_or(nullptr));
1915 auto *Arg = Callee->getArg(ArgNo);
1916 if (ReturnedArg && Arg != ReturnedArg)
1917 return true;
1918 bool IsRetMustAcc = IsArgMustAcc && (ReturnedArg == Arg);
1919 const auto *CSRetPI = A.getAAFor<AAPointerInfo>(
1921 if (!CSRetPI)
1922 return false;
1923 OffsetInfo OI = OffsetInfoMap[CurPtr];
1924 CSArgPI->addReturnedOffsetsTo(OI);
1925 Changed =
1926 translateAndAddState(A, *CSRetPI, OI, *CB, IsRetMustAcc) | Changed;
1927 return isValidState();
1928 }
1929 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Call user not handled " << *CB
1930 << "\n");
1931 return false;
1932 }
1933
1934 LLVM_DEBUG(dbgs() << "[AAPointerInfo] User not handled " << *Usr << "\n");
1935 return false;
1936 };
1937 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) {
1938 assert(OffsetInfoMap.count(OldU) && "Old use should be known already!");
1939 assert(!OffsetInfoMap[OldU].isUnassigned() && "Old use should be assinged");
1940 if (OffsetInfoMap.count(NewU)) {
1941 LLVM_DEBUG({
1942 if (!(OffsetInfoMap[NewU] == OffsetInfoMap[OldU])) {
1943 dbgs() << "[AAPointerInfo] Equivalent use callback failed: "
1944 << OffsetInfoMap[NewU] << " vs " << OffsetInfoMap[OldU]
1945 << "\n";
1946 }
1947 });
1948 return OffsetInfoMap[NewU] == OffsetInfoMap[OldU];
1949 }
1950 bool Unused;
1951 return HandlePassthroughUser(NewU.get(), OldU.get(), Unused);
1952 };
1953 if (!A.checkForAllUses(UsePred, *this, AssociatedValue,
1954 /* CheckBBLivenessOnly */ true, DepClassTy::OPTIONAL,
1955 /* IgnoreDroppableUses */ true, EquivalentUseCB)) {
1956 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Check for all uses failed, abort!\n");
1957 return indicatePessimisticFixpoint();
1958 }
1959
1960 LLVM_DEBUG({
1961 dbgs() << "Accesses by bin after update:\n";
1962 dumpState(dbgs());
1963 });
1964
1965 return Changed;
1966}
1967
1968struct AAPointerInfoReturned final : AAPointerInfoImpl {
1969 AAPointerInfoReturned(const IRPosition &IRP, Attributor &A)
1970 : AAPointerInfoImpl(IRP, A) {}
1971
1972 /// See AbstractAttribute::updateImpl(...).
1973 ChangeStatus updateImpl(Attributor &A) override {
1974 return indicatePessimisticFixpoint();
1975 }
1976
1977 /// See AbstractAttribute::trackStatistics()
1978 void trackStatistics() const override {
1979 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
1980 }
1981};
1982
1983struct AAPointerInfoArgument final : AAPointerInfoFloating {
1984 AAPointerInfoArgument(const IRPosition &IRP, Attributor &A)
1985 : AAPointerInfoFloating(IRP, A) {}
1986
1987 /// See AbstractAttribute::trackStatistics()
1988 void trackStatistics() const override {
1989 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
1990 }
1991};
1992
1993struct AAPointerInfoCallSiteArgument final : AAPointerInfoFloating {
1994 AAPointerInfoCallSiteArgument(const IRPosition &IRP, Attributor &A)
1995 : AAPointerInfoFloating(IRP, A) {}
1996
1997 /// See AbstractAttribute::updateImpl(...).
1998 ChangeStatus updateImpl(Attributor &A) override {
1999 using namespace AA::PointerInfo;
2000 // We handle memory intrinsics explicitly, at least the first (=
2001 // destination) and second (=source) arguments as we know how they are
2002 // accessed.
2003 if (auto *MI = dyn_cast_or_null<MemIntrinsic>(getCtxI())) {
2004 int64_t LengthVal = AA::RangeTy::Unknown;
2005 if (auto Length = MI->getLengthInBytes())
2006 LengthVal = Length->getSExtValue();
2007 unsigned ArgNo = getIRPosition().getCallSiteArgNo();
2008 ChangeStatus Changed = ChangeStatus::UNCHANGED;
2009 if (ArgNo > 1) {
2010 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Unhandled memory intrinsic "
2011 << *MI << "\n");
2012 return indicatePessimisticFixpoint();
2013 } else {
2014 auto Kind =
2015 ArgNo == 0 ? AccessKind::AK_MUST_WRITE : AccessKind::AK_MUST_READ;
2016 Changed =
2017 Changed | addAccess(A, {0, LengthVal}, *MI, nullptr, Kind, nullptr);
2018 }
2019 LLVM_DEBUG({
2020 dbgs() << "Accesses by bin after update:\n";
2021 dumpState(dbgs());
2022 });
2023
2024 return Changed;
2025 }
2026
2027 // TODO: Once we have call site specific value information we can provide
2028 // call site specific liveness information and then it makes
2029 // sense to specialize attributes for call sites arguments instead of
2030 // redirecting requests to the callee argument.
2031 Argument *Arg = getAssociatedArgument();
2032 if (Arg) {
2033 const IRPosition &ArgPos = IRPosition::argument(*Arg);
2034 auto *ArgAA =
2035 A.getAAFor<AAPointerInfo>(*this, ArgPos, DepClassTy::REQUIRED);
2036 if (ArgAA && ArgAA->getState().isValidState())
2037 return translateAndAddStateFromCallee(A, *ArgAA,
2038 *cast<CallBase>(getCtxI()));
2039 if (!Arg->getParent()->isDeclaration())
2040 return indicatePessimisticFixpoint();
2041 }
2042
2043 bool IsKnownNoCapture;
2045 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNoCapture))
2046 return indicatePessimisticFixpoint();
2047
2048 bool IsKnown = false;
2049 if (AA::isAssumedReadNone(A, getIRPosition(), *this, IsKnown))
2050 return ChangeStatus::UNCHANGED;
2051 bool ReadOnly = AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown);
2052 auto Kind =
2053 ReadOnly ? AccessKind::AK_MAY_READ : AccessKind::AK_MAY_READ_WRITE;
2054 return addAccess(A, AA::RangeTy::getUnknown(), *getCtxI(), nullptr, Kind,
2055 nullptr);
2056 }
2057
2058 /// See AbstractAttribute::trackStatistics()
2059 void trackStatistics() const override {
2060 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
2061 }
2062};
2063
2064struct AAPointerInfoCallSiteReturned final : AAPointerInfoFloating {
2065 AAPointerInfoCallSiteReturned(const IRPosition &IRP, Attributor &A)
2066 : AAPointerInfoFloating(IRP, A) {}
2067
2068 /// See AbstractAttribute::trackStatistics()
2069 void trackStatistics() const override {
2070 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
2071 }
2072};
2073} // namespace
2074
2075/// -----------------------NoUnwind Function Attribute--------------------------
2076
2077namespace {
2078struct AANoUnwindImpl : AANoUnwind {
2079 AANoUnwindImpl(const IRPosition &IRP, Attributor &A) : AANoUnwind(IRP, A) {}
2080
2081 /// See AbstractAttribute::initialize(...).
2082 void initialize(Attributor &A) override {
2083 bool IsKnown;
2085 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
2086 (void)IsKnown;
2087 }
2088
2089 const std::string getAsStr(Attributor *A) const override {
2090 return getAssumed() ? "nounwind" : "may-unwind";
2091 }
2092
2093 /// See AbstractAttribute::updateImpl(...).
2094 ChangeStatus updateImpl(Attributor &A) override {
2095 auto Opcodes = {
2096 (unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,
2097 (unsigned)Instruction::Call, (unsigned)Instruction::CleanupRet,
2098 (unsigned)Instruction::CatchSwitch, (unsigned)Instruction::Resume};
2099
2100 auto CheckForNoUnwind = [&](Instruction &I) {
2101 if (!I.mayThrow(/* IncludePhaseOneUnwind */ true))
2102 return true;
2103
2104 if (const auto *CB = dyn_cast<CallBase>(&I)) {
2105 bool IsKnownNoUnwind;
2107 A, this, IRPosition::callsite_function(*CB), DepClassTy::REQUIRED,
2108 IsKnownNoUnwind);
2109 }
2110 return false;
2111 };
2112
2113 bool UsedAssumedInformation = false;
2114 if (!A.checkForAllInstructions(CheckForNoUnwind, *this, Opcodes,
2115 UsedAssumedInformation))
2116 return indicatePessimisticFixpoint();
2117
2118 return ChangeStatus::UNCHANGED;
2119 }
2120};
2121
2122struct AANoUnwindFunction final : public AANoUnwindImpl {
2123 AANoUnwindFunction(const IRPosition &IRP, Attributor &A)
2124 : AANoUnwindImpl(IRP, A) {}
2125
2126 /// See AbstractAttribute::trackStatistics()
2127 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nounwind) }
2128};
2129
2130/// NoUnwind attribute deduction for a call sites.
2131struct AANoUnwindCallSite final
2132 : AACalleeToCallSite<AANoUnwind, AANoUnwindImpl> {
2133 AANoUnwindCallSite(const IRPosition &IRP, Attributor &A)
2134 : AACalleeToCallSite<AANoUnwind, AANoUnwindImpl>(IRP, A) {}
2135
2136 /// See AbstractAttribute::trackStatistics()
2137 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nounwind); }
2138};
2139} // namespace
2140
2141/// ------------------------ NoSync Function Attribute -------------------------
2142
2143bool AANoSync::isAlignedBarrier(const CallBase &CB, bool ExecutedAligned) {
2144 switch (CB.getIntrinsicID()) {
2145 case Intrinsic::nvvm_barrier_cta_sync_aligned_all:
2146 case Intrinsic::nvvm_barrier_cta_sync_aligned_count:
2147 case Intrinsic::nvvm_barrier_cta_red_and_aligned_all:
2148 case Intrinsic::nvvm_barrier_cta_red_and_aligned_count:
2149 case Intrinsic::nvvm_barrier_cta_red_or_aligned_all:
2150 case Intrinsic::nvvm_barrier_cta_red_or_aligned_count:
2151 case Intrinsic::nvvm_barrier_cta_red_popc_aligned_all:
2152 case Intrinsic::nvvm_barrier_cta_red_popc_aligned_count:
2153 return true;
2154 case Intrinsic::amdgcn_s_barrier:
2155 if (ExecutedAligned)
2156 return true;
2157 break;
2158 default:
2159 break;
2160 }
2161 return hasAssumption(CB, KnownAssumptionString("ompx_aligned_barrier"));
2162}
2163
2165 if (!I->isAtomic())
2166 return false;
2167
2168 if (auto *FI = dyn_cast<FenceInst>(I))
2169 // All legal orderings for fence are stronger than monotonic.
2170 return FI->getSyncScopeID() != SyncScope::SingleThread;
2171 if (auto *AI = dyn_cast<AtomicCmpXchgInst>(I)) {
2172 // Unordered is not a legal ordering for cmpxchg.
2173 return (AI->getSuccessOrdering() != AtomicOrdering::Monotonic ||
2174 AI->getFailureOrdering() != AtomicOrdering::Monotonic);
2175 }
2176
2177 AtomicOrdering Ordering;
2178 switch (I->getOpcode()) {
2179 case Instruction::AtomicRMW:
2180 Ordering = cast<AtomicRMWInst>(I)->getOrdering();
2181 break;
2182 case Instruction::Store:
2183 Ordering = cast<StoreInst>(I)->getOrdering();
2184 break;
2185 case Instruction::Load:
2186 Ordering = cast<LoadInst>(I)->getOrdering();
2187 break;
2188 default:
2190 "New atomic operations need to be known in the attributor.");
2191 }
2192
2193 return (Ordering != AtomicOrdering::Unordered &&
2194 Ordering != AtomicOrdering::Monotonic);
2195}
2196
2197namespace {
2198struct AANoSyncImpl : AANoSync {
2199 AANoSyncImpl(const IRPosition &IRP, Attributor &A) : AANoSync(IRP, A) {}
2200
2201 /// See AbstractAttribute::initialize(...).
2202 void initialize(Attributor &A) override {
2203 bool IsKnown;
2204 assert(!AA::hasAssumedIRAttr<Attribute::NoSync>(A, nullptr, getIRPosition(),
2205 DepClassTy::NONE, IsKnown));
2206 (void)IsKnown;
2207 }
2208
2209 const std::string getAsStr(Attributor *A) const override {
2210 return getAssumed() ? "nosync" : "may-sync";
2211 }
2212
2213 /// See AbstractAttribute::updateImpl(...).
2214 ChangeStatus updateImpl(Attributor &A) override;
2215};
2216
2217ChangeStatus AANoSyncImpl::updateImpl(Attributor &A) {
2218
2219 auto CheckRWInstForNoSync = [&](Instruction &I) {
2220 return AA::isNoSyncInst(A, I, *this);
2221 };
2222
2223 auto CheckForNoSync = [&](Instruction &I) {
2224 // At this point we handled all read/write effects and they are all
2225 // nosync, so they can be skipped.
2226 if (I.mayReadOrWriteMemory())
2227 return true;
2228
2229 bool IsKnown;
2230 CallBase &CB = cast<CallBase>(I);
2233 IsKnown))
2234 return true;
2235
2236 // non-convergent and readnone imply nosync.
2237 return !CB.isConvergent();
2238 };
2239
2240 bool UsedAssumedInformation = false;
2241 if (!A.checkForAllReadWriteInstructions(CheckRWInstForNoSync, *this,
2242 UsedAssumedInformation) ||
2243 !A.checkForAllCallLikeInstructions(CheckForNoSync, *this,
2244 UsedAssumedInformation))
2245 return indicatePessimisticFixpoint();
2246
2248}
2249
2250struct AANoSyncFunction final : public AANoSyncImpl {
2251 AANoSyncFunction(const IRPosition &IRP, Attributor &A)
2252 : AANoSyncImpl(IRP, A) {}
2253
2254 /// See AbstractAttribute::trackStatistics()
2255 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nosync) }
2256};
2257
2258/// NoSync attribute deduction for a call sites.
2259struct AANoSyncCallSite final : AACalleeToCallSite<AANoSync, AANoSyncImpl> {
2260 AANoSyncCallSite(const IRPosition &IRP, Attributor &A)
2261 : AACalleeToCallSite<AANoSync, AANoSyncImpl>(IRP, A) {}
2262
2263 /// See AbstractAttribute::trackStatistics()
2264 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nosync); }
2265};
2266} // namespace
2267
2268/// ------------------------ No-Free Attributes ----------------------------
2269
2270namespace {
2271struct AANoFreeImpl : public AANoFree {
2272 AANoFreeImpl(const IRPosition &IRP, Attributor &A) : AANoFree(IRP, A) {}
2273
2274 /// See AbstractAttribute::initialize(...).
2275 void initialize(Attributor &A) override {
2276 bool IsKnown;
2277 assert(!AA::hasAssumedIRAttr<Attribute::NoFree>(A, nullptr, getIRPosition(),
2278 DepClassTy::NONE, IsKnown));
2279 (void)IsKnown;
2280 }
2281
2282 /// See AbstractAttribute::updateImpl(...).
2283 ChangeStatus updateImpl(Attributor &A) override {
2284 auto CheckForNoFree = [&](Instruction &I) {
2285 if (auto *CB = dyn_cast<CallBase>(&I)) {
2286 bool IsKnown;
2288 A, this, IRPosition::callsite_function(*CB), DepClassTy::REQUIRED,
2289 IsKnown);
2290 }
2291 // Make sure that synchronization cannot establish happens-before with a
2292 // free on another thread.
2293 return AA::isNoSyncInst(A, I, *this);
2294 };
2295
2296 bool UsedAssumedInformation = false;
2297 if (!A.checkForAllReadWriteInstructions(CheckForNoFree, *this,
2298 UsedAssumedInformation) ||
2299 !A.checkForAllCallLikeInstructions(CheckForNoFree, *this,
2300 UsedAssumedInformation))
2301 return indicatePessimisticFixpoint();
2302
2303 return ChangeStatus::UNCHANGED;
2304 }
2305
2306 /// See AbstractAttribute::getAsStr().
2307 const std::string getAsStr(Attributor *A) const override {
2308 return getAssumed() ? "nofree" : "may-free";
2309 }
2310};
2311
2312struct AANoFreeFunction final : public AANoFreeImpl {
2313 AANoFreeFunction(const IRPosition &IRP, Attributor &A)
2314 : AANoFreeImpl(IRP, A) {}
2315
2316 /// See AbstractAttribute::trackStatistics()
2317 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nofree) }
2318};
2319
2320/// NoFree attribute deduction for a call sites.
2321struct AANoFreeCallSite final : AACalleeToCallSite<AANoFree, AANoFreeImpl> {
2322 AANoFreeCallSite(const IRPosition &IRP, Attributor &A)
2323 : AACalleeToCallSite<AANoFree, AANoFreeImpl>(IRP, A) {}
2324
2325 /// See AbstractAttribute::trackStatistics()
2326 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nofree); }
2327};
2328
2329/// NoFree attribute for floating values.
2330struct AANoFreeFloating : AANoFreeImpl {
2331 AANoFreeFloating(const IRPosition &IRP, Attributor &A)
2332 : AANoFreeImpl(IRP, A) {}
2333
2334 /// See AbstractAttribute::trackStatistics()
2335 void trackStatistics() const override{STATS_DECLTRACK_FLOATING_ATTR(nofree)}
2336
2337 /// See Abstract Attribute::updateImpl(...).
2338 ChangeStatus updateImpl(Attributor &A) override {
2339 const IRPosition &IRP = getIRPosition();
2340
2341 bool IsKnown;
2344 DepClassTy::OPTIONAL, IsKnown))
2345 return ChangeStatus::UNCHANGED;
2346
2347 Value &AssociatedValue = getIRPosition().getAssociatedValue();
2348 auto Pred = [&](const Use &U, bool &Follow) -> bool {
2349 Instruction *UserI = cast<Instruction>(U.getUser());
2350 if (auto *CB = dyn_cast<CallBase>(UserI)) {
2351 if (CB->isBundleOperand(&U))
2352 return false;
2353 if (!CB->isArgOperand(&U))
2354 return true;
2355 unsigned ArgNo = CB->getArgOperandNo(&U);
2356
2357 // Even if the argument is nofree, we still need to check for nocapture,
2358 // as the call may capture the argument without freeing it, and the
2359 // captured argument is freed later.
2360 bool IsKnown;
2362 A, this, IRPosition::callsite_argument(*CB, ArgNo),
2363 DepClassTy::REQUIRED, IsKnown))
2364 return false;
2365
2366 const AANoCapture *NoCaptureAA = nullptr;
2368 A, this, IRPosition::callsite_argument(*CB, ArgNo),
2369 DepClassTy::REQUIRED, IsKnown,
2370 /*IgnoreSubsumingPositions=*/false, &NoCaptureAA)) {
2371 if (NoCaptureAA && NoCaptureAA->isAssumedNoCaptureMaybeReturned()) {
2372 Follow = true;
2373 return true;
2374 }
2375 return false;
2376 }
2377
2378 return true;
2379 }
2380
2381 UseCaptureInfo CI = DetermineUseCaptureKind(U, /*Base=*/nullptr);
2382 if (!capturesAnyProvenance(CI))
2383 return true;
2385 Follow = true;
2386 return true;
2387 }
2388
2389 if (isa<ReturnInst>(UserI) && getIRPosition().isArgumentPosition())
2390 return true;
2391
2392 // Capturing user.
2393 return false;
2394 };
2395 if (!A.checkForAllUses(Pred, *this, AssociatedValue))
2396 return indicatePessimisticFixpoint();
2397
2398 return ChangeStatus::UNCHANGED;
2399 }
2400};
2401
2402/// NoFree attribute for a call site argument.
2403struct AANoFreeArgument final : AANoFreeFloating {
2404 AANoFreeArgument(const IRPosition &IRP, Attributor &A)
2405 : AANoFreeFloating(IRP, A) {}
2406
2407 /// See AbstractAttribute::trackStatistics()
2408 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nofree) }
2409};
2410
2411/// NoFree attribute for call site arguments.
2412struct AANoFreeCallSiteArgument final : AANoFreeFloating {
2413 AANoFreeCallSiteArgument(const IRPosition &IRP, Attributor &A)
2414 : AANoFreeFloating(IRP, A) {}
2415
2416 /// See AbstractAttribute::updateImpl(...).
2417 ChangeStatus updateImpl(Attributor &A) override {
2418 // TODO: Once we have call site specific value information we can provide
2419 // call site specific liveness information and then it makes
2420 // sense to specialize attributes for call sites arguments instead of
2421 // redirecting requests to the callee argument.
2422 Argument *Arg = getAssociatedArgument();
2423 if (!Arg)
2424 return indicatePessimisticFixpoint();
2425 const IRPosition &ArgPos = IRPosition::argument(*Arg);
2426 bool IsKnown;
2428 DepClassTy::REQUIRED, IsKnown))
2429 return ChangeStatus::UNCHANGED;
2430 return indicatePessimisticFixpoint();
2431 }
2432
2433 /// See AbstractAttribute::trackStatistics()
2434 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(nofree) };
2435};
2436
2437/// NoFree attribute for function return value.
2438struct AANoFreeReturned final : AANoFreeFloating {
2439 AANoFreeReturned(const IRPosition &IRP, Attributor &A)
2440 : AANoFreeFloating(IRP, A) {
2441 llvm_unreachable("NoFree is not applicable to function returns!");
2442 }
2443
2444 /// See AbstractAttribute::initialize(...).
2445 void initialize(Attributor &A) override {
2446 llvm_unreachable("NoFree is not applicable to function returns!");
2447 }
2448
2449 /// See AbstractAttribute::updateImpl(...).
2450 ChangeStatus updateImpl(Attributor &A) override {
2451 llvm_unreachable("NoFree is not applicable to function returns!");
2452 }
2453
2454 /// See AbstractAttribute::trackStatistics()
2455 void trackStatistics() const override {}
2456};
2457
2458/// NoFree attribute deduction for a call site return value.
2459struct AANoFreeCallSiteReturned final : AANoFreeFloating {
2460 AANoFreeCallSiteReturned(const IRPosition &IRP, Attributor &A)
2461 : AANoFreeFloating(IRP, A) {}
2462
2463 ChangeStatus manifest(Attributor &A) override {
2464 return ChangeStatus::UNCHANGED;
2465 }
2466 /// See AbstractAttribute::trackStatistics()
2467 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(nofree) }
2468};
2469} // namespace
2470
2471/// ------------------------ NonNull Argument Attribute ------------------------
2472
2474 Attribute::AttrKind ImpliedAttributeKind,
2475 bool IgnoreSubsumingPositions) {
2477 AttrKinds.push_back(Attribute::NonNull);
2480 AttrKinds.push_back(Attribute::Dereferenceable);
2481 if (A.hasAttr(IRP, AttrKinds, IgnoreSubsumingPositions, Attribute::NonNull))
2482 return true;
2483
2484 DominatorTree *DT = nullptr;
2485 AssumptionCache *AC = nullptr;
2486 InformationCache &InfoCache = A.getInfoCache();
2487 if (const Function *Fn = IRP.getAnchorScope()) {
2488 if (!Fn->isDeclaration()) {
2491 }
2492 }
2493
2495 if (IRP.getPositionKind() != IRP_RETURNED) {
2496 Worklist.push_back({IRP.getAssociatedValue(), IRP.getCtxI()});
2497 } else {
2498 bool UsedAssumedInformation = false;
2499 if (!A.checkForAllInstructions(
2500 [&](Instruction &I) {
2501 Worklist.push_back({*cast<ReturnInst>(I).getReturnValue(), &I});
2502 return true;
2503 },
2504 IRP.getAssociatedFunction(), nullptr, {Instruction::Ret},
2505 UsedAssumedInformation, false, /*CheckPotentiallyDead=*/true))
2506 return false;
2507 }
2508
2509 if (llvm::any_of(Worklist, [&](AA::ValueAndContext VAC) {
2510 return !isKnownNonZero(
2511 VAC.getValue(),
2512 SimplifyQuery(A.getDataLayout(), DT, AC, VAC.getCtxI()));
2513 }))
2514 return false;
2515
2516 A.manifestAttrs(IRP, {Attribute::get(IRP.getAnchorValue().getContext(),
2517 Attribute::NonNull)});
2518 return true;
2519}
2520
2521namespace {
2522static int64_t getKnownNonNullAndDerefBytesForUse(
2523 Attributor &A, const AbstractAttribute &QueryingAA, Value &AssociatedValue,
2524 const Use *U, const Instruction *I, bool &IsNonNull, bool &TrackUse) {
2525 TrackUse = false;
2526
2527 const Value *UseV = U->get();
2528 if (!UseV->getType()->isPointerTy())
2529 return 0;
2530
2531 // We need to follow common pointer manipulation uses to the accesses they
2532 // feed into. We can try to be smart to avoid looking through things we do not
2533 // like for now, e.g., non-inbounds GEPs.
2534 if (isa<CastInst>(I)) {
2535 TrackUse = true;
2536 return 0;
2537 }
2538
2540 TrackUse = true;
2541 return 0;
2542 }
2543
2544 Type *PtrTy = UseV->getType();
2545 const Function *F = I->getFunction();
2548 const DataLayout &DL = A.getInfoCache().getDL();
2549 if (const auto *CB = dyn_cast<CallBase>(I)) {
2550 if (CB->isBundleOperand(U)) {
2551 if (RetainedKnowledge RK = getKnowledgeFromUse(
2552 U, {Attribute::NonNull, Attribute::Dereferenceable})) {
2553 IsNonNull |=
2554 (RK.AttrKind == Attribute::NonNull || !NullPointerIsDefined);
2555 return RK.ArgValue;
2556 }
2557 return 0;
2558 }
2559
2560 if (CB->isCallee(U)) {
2561 IsNonNull |= !NullPointerIsDefined;
2562 return 0;
2563 }
2564
2565 unsigned ArgNo = CB->getArgOperandNo(U);
2566 IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo);
2567 // As long as we only use known information there is no need to track
2568 // dependences here.
2569 bool IsKnownNonNull;
2571 DepClassTy::NONE, IsKnownNonNull);
2572 IsNonNull |= IsKnownNonNull;
2573 auto *DerefAA =
2574 A.getAAFor<AADereferenceable>(QueryingAA, IRP, DepClassTy::NONE);
2575 return DerefAA ? DerefAA->getKnownDereferenceableBytes() : 0;
2576 }
2577
2578 std::optional<MemoryLocation> Loc = MemoryLocation::getOrNone(I);
2579 if (!Loc || Loc->Ptr != UseV || !Loc->Size.isPrecise() ||
2580 Loc->Size.isScalable() || I->isVolatile())
2581 return 0;
2582
2583 int64_t Offset;
2584 const Value *Base =
2585 getMinimalBaseOfPointer(A, QueryingAA, Loc->Ptr, Offset, DL);
2586 if (Base && Base == &AssociatedValue) {
2587 int64_t DerefBytes = Loc->Size.getValue() + Offset;
2588 IsNonNull |= !NullPointerIsDefined;
2589 return std::max(int64_t(0), DerefBytes);
2590 }
2591
2592 /// Corner case when an offset is 0.
2594 /*AllowNonInbounds*/ true);
2595 if (Base && Base == &AssociatedValue && Offset == 0) {
2596 int64_t DerefBytes = Loc->Size.getValue();
2597 IsNonNull |= !NullPointerIsDefined;
2598 return std::max(int64_t(0), DerefBytes);
2599 }
2600
2601 return 0;
2602}
2603
2604struct AANonNullImpl : AANonNull {
2605 AANonNullImpl(const IRPosition &IRP, Attributor &A) : AANonNull(IRP, A) {}
2606
2607 /// See AbstractAttribute::initialize(...).
2608 void initialize(Attributor &A) override {
2609 Value &V = *getAssociatedValue().stripPointerCasts();
2610 if (isa<ConstantPointerNull>(V)) {
2611 indicatePessimisticFixpoint();
2612 return;
2613 }
2614
2615 if (Instruction *CtxI = getCtxI())
2616 followUsesInMBEC(*this, A, getState(), *CtxI);
2617 }
2618
2619 /// See followUsesInMBEC
2620 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
2621 AANonNull::StateType &State) {
2622 bool IsNonNull = false;
2623 bool TrackUse = false;
2624 getKnownNonNullAndDerefBytesForUse(A, *this, getAssociatedValue(), U, I,
2625 IsNonNull, TrackUse);
2626 State.setKnown(IsNonNull);
2627 return TrackUse;
2628 }
2629
2630 /// See AbstractAttribute::getAsStr().
2631 const std::string getAsStr(Attributor *A) const override {
2632 return getAssumed() ? "nonnull" : "may-null";
2633 }
2634};
2635
2636/// NonNull attribute for a floating value.
2637struct AANonNullFloating : public AANonNullImpl {
2638 AANonNullFloating(const IRPosition &IRP, Attributor &A)
2639 : AANonNullImpl(IRP, A) {}
2640
2641 /// See AbstractAttribute::updateImpl(...).
2642 ChangeStatus updateImpl(Attributor &A) override {
2643 auto CheckIRP = [&](const IRPosition &IRP) {
2644 bool IsKnownNonNull;
2646 A, *this, IRP, DepClassTy::OPTIONAL, IsKnownNonNull);
2647 };
2648
2649 bool Stripped;
2650 bool UsedAssumedInformation = false;
2651 Value *AssociatedValue = &getAssociatedValue();
2653 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
2654 AA::AnyScope, UsedAssumedInformation))
2655 Stripped = false;
2656 else
2657 Stripped =
2658 Values.size() != 1 || Values.front().getValue() != AssociatedValue;
2659
2660 if (!Stripped) {
2661 bool IsKnown;
2662 if (auto *PHI = dyn_cast<PHINode>(AssociatedValue))
2663 if (llvm::all_of(PHI->incoming_values(), [&](Value *Op) {
2664 return AA::hasAssumedIRAttr<Attribute::NonNull>(
2665 A, this, IRPosition::value(*Op), DepClassTy::OPTIONAL,
2666 IsKnown);
2667 }))
2668 return ChangeStatus::UNCHANGED;
2669 if (auto *Select = dyn_cast<SelectInst>(AssociatedValue))
2671 A, this, IRPosition::value(*Select->getFalseValue()),
2672 DepClassTy::OPTIONAL, IsKnown) &&
2674 A, this, IRPosition::value(*Select->getTrueValue()),
2675 DepClassTy::OPTIONAL, IsKnown))
2676 return ChangeStatus::UNCHANGED;
2677
2678 // If we haven't stripped anything we might still be able to use a
2679 // different AA, but only if the IRP changes. Effectively when we
2680 // interpret this not as a call site value but as a floating/argument
2681 // value.
2682 const IRPosition AVIRP = IRPosition::value(*AssociatedValue);
2683 if (AVIRP == getIRPosition() || !CheckIRP(AVIRP))
2684 return indicatePessimisticFixpoint();
2685 return ChangeStatus::UNCHANGED;
2686 }
2687
2688 for (const auto &VAC : Values)
2689 if (!CheckIRP(IRPosition::value(*VAC.getValue())))
2690 return indicatePessimisticFixpoint();
2691
2692 return ChangeStatus::UNCHANGED;
2693 }
2694
2695 /// See AbstractAttribute::trackStatistics()
2696 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
2697};
2698
2699/// NonNull attribute for function return value.
2700struct AANonNullReturned final
2701 : AAReturnedFromReturnedValues<AANonNull, AANonNull, AANonNull::StateType,
2702 false, AANonNull::IRAttributeKind, false> {
2703 AANonNullReturned(const IRPosition &IRP, Attributor &A)
2704 : AAReturnedFromReturnedValues<AANonNull, AANonNull, AANonNull::StateType,
2705 false, Attribute::NonNull, false>(IRP, A) {
2706 }
2707
2708 /// See AbstractAttribute::getAsStr().
2709 const std::string getAsStr(Attributor *A) const override {
2710 return getAssumed() ? "nonnull" : "may-null";
2711 }
2712
2713 /// See AbstractAttribute::trackStatistics()
2714 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
2715};
2716
2717/// NonNull attribute for function argument.
2718struct AANonNullArgument final
2719 : AAArgumentFromCallSiteArguments<AANonNull, AANonNullImpl> {
2720 AANonNullArgument(const IRPosition &IRP, Attributor &A)
2721 : AAArgumentFromCallSiteArguments<AANonNull, AANonNullImpl>(IRP, A) {}
2722
2723 /// See AbstractAttribute::trackStatistics()
2724 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nonnull) }
2725};
2726
2727struct AANonNullCallSiteArgument final : AANonNullFloating {
2728 AANonNullCallSiteArgument(const IRPosition &IRP, Attributor &A)
2729 : AANonNullFloating(IRP, A) {}
2730
2731 /// See AbstractAttribute::trackStatistics()
2732 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(nonnull) }
2733};
2734
2735/// NonNull attribute for a call site return position.
2736struct AANonNullCallSiteReturned final
2737 : AACalleeToCallSite<AANonNull, AANonNullImpl> {
2738 AANonNullCallSiteReturned(const IRPosition &IRP, Attributor &A)
2739 : AACalleeToCallSite<AANonNull, AANonNullImpl>(IRP, A) {}
2740
2741 /// See AbstractAttribute::trackStatistics()
2742 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(nonnull) }
2743};
2744} // namespace
2745
2746/// ------------------------ Must-Progress Attributes --------------------------
2747namespace {
2748struct AAMustProgressImpl : public AAMustProgress {
2749 AAMustProgressImpl(const IRPosition &IRP, Attributor &A)
2750 : AAMustProgress(IRP, A) {}
2751
2752 /// See AbstractAttribute::initialize(...).
2753 void initialize(Attributor &A) override {
2754 bool IsKnown;
2756 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
2757 (void)IsKnown;
2758 }
2759
2760 /// See AbstractAttribute::getAsStr()
2761 const std::string getAsStr(Attributor *A) const override {
2762 return getAssumed() ? "mustprogress" : "may-not-progress";
2763 }
2764};
2765
2766struct AAMustProgressFunction final : AAMustProgressImpl {
2767 AAMustProgressFunction(const IRPosition &IRP, Attributor &A)
2768 : AAMustProgressImpl(IRP, A) {}
2769
2770 /// See AbstractAttribute::updateImpl(...).
2771 ChangeStatus updateImpl(Attributor &A) override {
2772 bool IsKnown;
2774 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnown)) {
2775 if (IsKnown)
2776 return indicateOptimisticFixpoint();
2777 return ChangeStatus::UNCHANGED;
2778 }
2779
2780 auto CheckForMustProgress = [&](AbstractCallSite ACS) {
2781 IRPosition IPos = IRPosition::callsite_function(*ACS.getInstruction());
2782 bool IsKnownMustProgress;
2784 A, this, IPos, DepClassTy::REQUIRED, IsKnownMustProgress,
2785 /* IgnoreSubsumingPositions */ true);
2786 };
2787
2788 bool AllCallSitesKnown = true;
2789 if (!A.checkForAllCallSites(CheckForMustProgress, *this,
2790 /* RequireAllCallSites */ true,
2791 AllCallSitesKnown))
2792 return indicatePessimisticFixpoint();
2793
2794 return ChangeStatus::UNCHANGED;
2795 }
2796
2797 /// See AbstractAttribute::trackStatistics()
2798 void trackStatistics() const override {
2799 STATS_DECLTRACK_FN_ATTR(mustprogress)
2800 }
2801};
2802
2803/// MustProgress attribute deduction for a call sites.
2804struct AAMustProgressCallSite final : AAMustProgressImpl {
2805 AAMustProgressCallSite(const IRPosition &IRP, Attributor &A)
2806 : AAMustProgressImpl(IRP, A) {}
2807
2808 /// See AbstractAttribute::updateImpl(...).
2809 ChangeStatus updateImpl(Attributor &A) override {
2810 // TODO: Once we have call site specific value information we can provide
2811 // call site specific liveness information and then it makes
2812 // sense to specialize attributes for call sites arguments instead of
2813 // redirecting requests to the callee argument.
2814 const IRPosition &FnPos = IRPosition::function(*getAnchorScope());
2815 bool IsKnownMustProgress;
2817 A, this, FnPos, DepClassTy::REQUIRED, IsKnownMustProgress))
2818 return indicatePessimisticFixpoint();
2819 return ChangeStatus::UNCHANGED;
2820 }
2821
2822 /// See AbstractAttribute::trackStatistics()
2823 void trackStatistics() const override {
2824 STATS_DECLTRACK_CS_ATTR(mustprogress);
2825 }
2826};
2827} // namespace
2828
2829/// ------------------------ No-Recurse Attributes ----------------------------
2830
2831namespace {
2832struct AANoRecurseImpl : public AANoRecurse {
2833 AANoRecurseImpl(const IRPosition &IRP, Attributor &A) : AANoRecurse(IRP, A) {}
2834
2835 /// See AbstractAttribute::initialize(...).
2836 void initialize(Attributor &A) override {
2837 bool IsKnown;
2839 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
2840 (void)IsKnown;
2841 }
2842
2843 /// See AbstractAttribute::getAsStr()
2844 const std::string getAsStr(Attributor *A) const override {
2845 return getAssumed() ? "norecurse" : "may-recurse";
2846 }
2847};
2848
2849struct AANoRecurseFunction final : AANoRecurseImpl {
2850 AANoRecurseFunction(const IRPosition &IRP, Attributor &A)
2851 : AANoRecurseImpl(IRP, A) {}
2852
2853 /// See AbstractAttribute::updateImpl(...).
2854 ChangeStatus updateImpl(Attributor &A) override {
2855
2856 // If all live call sites are known to be no-recurse, we are as well.
2857 auto CallSitePred = [&](AbstractCallSite ACS) {
2858 bool IsKnownNoRecurse;
2860 A, this,
2861 IRPosition::function(*ACS.getInstruction()->getFunction()),
2862 DepClassTy::NONE, IsKnownNoRecurse))
2863 return false;
2864 return IsKnownNoRecurse;
2865 };
2866 bool UsedAssumedInformation = false;
2867 if (A.checkForAllCallSites(CallSitePred, *this, true,
2868 UsedAssumedInformation)) {
2869 // If we know all call sites and all are known no-recurse, we are done.
2870 // If all known call sites, which might not be all that exist, are known
2871 // to be no-recurse, we are not done but we can continue to assume
2872 // no-recurse. If one of the call sites we have not visited will become
2873 // live, another update is triggered.
2874 if (!UsedAssumedInformation)
2875 indicateOptimisticFixpoint();
2876 return ChangeStatus::UNCHANGED;
2877 }
2878
2879 const AAInterFnReachability *EdgeReachability =
2880 A.getAAFor<AAInterFnReachability>(*this, getIRPosition(),
2881 DepClassTy::REQUIRED);
2882 if (EdgeReachability && EdgeReachability->canReach(A, *getAnchorScope()))
2883 return indicatePessimisticFixpoint();
2884 return ChangeStatus::UNCHANGED;
2885 }
2886
2887 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(norecurse) }
2888};
2889
2890/// NoRecurse attribute deduction for a call sites.
2891struct AANoRecurseCallSite final
2892 : AACalleeToCallSite<AANoRecurse, AANoRecurseImpl> {
2893 AANoRecurseCallSite(const IRPosition &IRP, Attributor &A)
2894 : AACalleeToCallSite<AANoRecurse, AANoRecurseImpl>(IRP, A) {}
2895
2896 /// See AbstractAttribute::trackStatistics()
2897 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(norecurse); }
2898};
2899} // namespace
2900
2901/// ------------------------ No-Convergent Attribute --------------------------
2902
2903namespace {
2904struct AANonConvergentImpl : public AANonConvergent {
2905 AANonConvergentImpl(const IRPosition &IRP, Attributor &A)
2906 : AANonConvergent(IRP, A) {}
2907
2908 /// See AbstractAttribute::getAsStr()
2909 const std::string getAsStr(Attributor *A) const override {
2910 return getAssumed() ? "non-convergent" : "may-be-convergent";
2911 }
2912};
2913
2914struct AANonConvergentFunction final : AANonConvergentImpl {
2915 AANonConvergentFunction(const IRPosition &IRP, Attributor &A)
2916 : AANonConvergentImpl(IRP, A) {}
2917
2918 /// See AbstractAttribute::updateImpl(...).
2919 ChangeStatus updateImpl(Attributor &A) override {
2920 // If all function calls are known to not be convergent, we are not
2921 // convergent.
2922 auto CalleeIsNotConvergent = [&](Instruction &Inst) {
2923 CallBase &CB = cast<CallBase>(Inst);
2925 if (!Callee || Callee->isIntrinsic()) {
2926 return false;
2927 }
2928 if (Callee->isDeclaration()) {
2929 return !Callee->hasFnAttribute(Attribute::Convergent);
2930 }
2931 const auto *ConvergentAA = A.getAAFor<AANonConvergent>(
2932 *this, IRPosition::function(*Callee), DepClassTy::REQUIRED);
2933 return ConvergentAA && ConvergentAA->isAssumedNotConvergent();
2934 };
2935
2936 bool UsedAssumedInformation = false;
2937 if (!A.checkForAllCallLikeInstructions(CalleeIsNotConvergent, *this,
2938 UsedAssumedInformation)) {
2939 return indicatePessimisticFixpoint();
2940 }
2941 return ChangeStatus::UNCHANGED;
2942 }
2943
2944 ChangeStatus manifest(Attributor &A) override {
2945 if (isKnownNotConvergent() &&
2946 A.hasAttr(getIRPosition(), Attribute::Convergent)) {
2947 A.removeAttrs(getIRPosition(), {Attribute::Convergent});
2948 return ChangeStatus::CHANGED;
2949 }
2950 return ChangeStatus::UNCHANGED;
2951 }
2952
2953 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(convergent) }
2954};
2955} // namespace
2956
2957/// -------------------- Undefined-Behavior Attributes ------------------------
2958
2959namespace {
2960struct AAUndefinedBehaviorImpl : public AAUndefinedBehavior {
2961 AAUndefinedBehaviorImpl(const IRPosition &IRP, Attributor &A)
2962 : AAUndefinedBehavior(IRP, A) {}
2963
2964 /// See AbstractAttribute::updateImpl(...).
2965 // through a pointer (i.e. also branches etc.)
2966 ChangeStatus updateImpl(Attributor &A) override {
2967 const size_t UBPrevSize = KnownUBInsts.size();
2968 const size_t NoUBPrevSize = AssumedNoUBInsts.size();
2969
2970 auto InspectMemAccessInstForUB = [&](Instruction &I) {
2971 // Volatile accesses on null are not necessarily UB.
2972 if (I.isVolatile())
2973 return true;
2974
2975 // Skip instructions that are already saved.
2976 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
2977 return true;
2978
2979 // If we reach here, we know we have an instruction
2980 // that accesses memory through a pointer operand,
2981 // for which getPointerOperand() should give it to us.
2982 Value *PtrOp =
2983 const_cast<Value *>(getPointerOperand(&I, /* AllowVolatile */ true));
2984 assert(PtrOp &&
2985 "Expected pointer operand of memory accessing instruction");
2986
2987 // Either we stopped and the appropriate action was taken,
2988 // or we got back a simplified value to continue.
2989 std::optional<Value *> SimplifiedPtrOp =
2990 stopOnUndefOrAssumed(A, PtrOp, &I);
2991 if (!SimplifiedPtrOp || !*SimplifiedPtrOp)
2992 return true;
2993 const Value *PtrOpVal = *SimplifiedPtrOp;
2994
2995 // A memory access through a pointer is considered UB
2996 // only if the pointer has constant null value.
2997 // TODO: Expand it to not only check constant values.
2998 if (!isa<ConstantPointerNull>(PtrOpVal)) {
2999 AssumedNoUBInsts.insert(&I);
3000 return true;
3001 }
3002 const Type *PtrTy = PtrOpVal->getType();
3003
3004 // Because we only consider instructions inside functions,
3005 // assume that a parent function exists.
3006 const Function *F = I.getFunction();
3007
3008 // A memory access using constant null pointer is only considered UB
3009 // if null pointer is _not_ defined for the target platform.
3011 AssumedNoUBInsts.insert(&I);
3012 else
3013 KnownUBInsts.insert(&I);
3014 return true;
3015 };
3016
3017 auto InspectBrInstForUB = [&](Instruction &I) {
3018 // A conditional branch instruction is considered UB if it has `undef`
3019 // condition.
3020
3021 // Skip instructions that are already saved.
3022 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
3023 return true;
3024
3025 // We know we have a branch instruction.
3026 auto *BrInst = cast<CondBrInst>(&I);
3027
3028 // Either we stopped and the appropriate action was taken,
3029 // or we got back a simplified value to continue.
3030 std::optional<Value *> SimplifiedCond =
3031 stopOnUndefOrAssumed(A, BrInst->getCondition(), BrInst);
3032 if (!SimplifiedCond || !*SimplifiedCond)
3033 return true;
3034 AssumedNoUBInsts.insert(&I);
3035 return true;
3036 };
3037
3038 auto InspectCallSiteForUB = [&](Instruction &I) {
3039 // Check whether a callsite always cause UB or not
3040
3041 // Skip instructions that are already saved.
3042 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
3043 return true;
3044
3045 // Check nonnull and noundef argument attribute violation for each
3046 // callsite.
3047 CallBase &CB = cast<CallBase>(I);
3049 if (!Callee)
3050 return true;
3051 for (unsigned idx = 0; idx < CB.arg_size(); idx++) {
3052 // If current argument is known to be simplified to null pointer and the
3053 // corresponding argument position is known to have nonnull attribute,
3054 // the argument is poison. Furthermore, if the argument is poison and
3055 // the position is known to have noundef attriubte, this callsite is
3056 // considered UB.
3057 if (idx >= Callee->arg_size())
3058 break;
3059 Value *ArgVal = CB.getArgOperand(idx);
3060 if (!ArgVal)
3061 continue;
3062 // Here, we handle three cases.
3063 // (1) Not having a value means it is dead. (we can replace the value
3064 // with undef)
3065 // (2) Simplified to undef. The argument violate noundef attriubte.
3066 // (3) Simplified to null pointer where known to be nonnull.
3067 // The argument is a poison value and violate noundef attribute.
3068 IRPosition CalleeArgumentIRP = IRPosition::callsite_argument(CB, idx);
3069 bool IsKnownNoUndef;
3071 A, this, CalleeArgumentIRP, DepClassTy::NONE, IsKnownNoUndef);
3072 if (!IsKnownNoUndef)
3073 continue;
3074 bool UsedAssumedInformation = false;
3075 std::optional<Value *> SimplifiedVal =
3076 A.getAssumedSimplified(IRPosition::value(*ArgVal), *this,
3077 UsedAssumedInformation, AA::Interprocedural);
3078 if (UsedAssumedInformation)
3079 continue;
3080 if (SimplifiedVal && !*SimplifiedVal)
3081 return true;
3082 if (!SimplifiedVal || isa<UndefValue>(**SimplifiedVal)) {
3083 KnownUBInsts.insert(&I);
3084 continue;
3085 }
3086 if (!ArgVal->getType()->isPointerTy() ||
3087 !isa<ConstantPointerNull>(**SimplifiedVal))
3088 continue;
3089 bool IsKnownNonNull;
3091 A, this, CalleeArgumentIRP, DepClassTy::NONE, IsKnownNonNull);
3092 if (IsKnownNonNull)
3093 KnownUBInsts.insert(&I);
3094 }
3095 return true;
3096 };
3097
3098 auto InspectReturnInstForUB = [&](Instruction &I) {
3099 auto &RI = cast<ReturnInst>(I);
3100 // Either we stopped and the appropriate action was taken,
3101 // or we got back a simplified return value to continue.
3102 std::optional<Value *> SimplifiedRetValue =
3103 stopOnUndefOrAssumed(A, RI.getReturnValue(), &I);
3104 if (!SimplifiedRetValue || !*SimplifiedRetValue)
3105 return true;
3106
3107 // Check if a return instruction always cause UB or not
3108 // Note: It is guaranteed that the returned position of the anchor
3109 // scope has noundef attribute when this is called.
3110 // We also ensure the return position is not "assumed dead"
3111 // because the returned value was then potentially simplified to
3112 // `undef` in AAReturnedValues without removing the `noundef`
3113 // attribute yet.
3114
3115 // When the returned position has noundef attriubte, UB occurs in the
3116 // following cases.
3117 // (1) Returned value is known to be undef.
3118 // (2) The value is known to be a null pointer and the returned
3119 // position has nonnull attribute (because the returned value is
3120 // poison).
3121 if (isa<ConstantPointerNull>(*SimplifiedRetValue)) {
3122 bool IsKnownNonNull;
3124 A, this, IRPosition::returned(*getAnchorScope()), DepClassTy::NONE,
3125 IsKnownNonNull);
3126 if (IsKnownNonNull)
3127 KnownUBInsts.insert(&I);
3128 }
3129
3130 return true;
3131 };
3132
3133 bool UsedAssumedInformation = false;
3134 A.checkForAllInstructions(InspectMemAccessInstForUB, *this,
3135 {Instruction::Load, Instruction::Store,
3136 Instruction::AtomicCmpXchg,
3137 Instruction::AtomicRMW},
3138 UsedAssumedInformation,
3139 /* CheckBBLivenessOnly */ true);
3140 A.checkForAllInstructions(InspectBrInstForUB, *this, {Instruction::CondBr},
3141 UsedAssumedInformation,
3142 /* CheckBBLivenessOnly */ true);
3143 A.checkForAllCallLikeInstructions(InspectCallSiteForUB, *this,
3144 UsedAssumedInformation);
3145
3146 // If the returned position of the anchor scope has noundef attriubte, check
3147 // all returned instructions.
3148 if (!getAnchorScope()->getReturnType()->isVoidTy()) {
3149 const IRPosition &ReturnIRP = IRPosition::returned(*getAnchorScope());
3150 if (!A.isAssumedDead(ReturnIRP, this, nullptr, UsedAssumedInformation)) {
3151 bool IsKnownNoUndef;
3153 A, this, ReturnIRP, DepClassTy::NONE, IsKnownNoUndef);
3154 if (IsKnownNoUndef)
3155 A.checkForAllInstructions(InspectReturnInstForUB, *this,
3156 {Instruction::Ret}, UsedAssumedInformation,
3157 /* CheckBBLivenessOnly */ true);
3158 }
3159 }
3160
3161 if (NoUBPrevSize != AssumedNoUBInsts.size() ||
3162 UBPrevSize != KnownUBInsts.size())
3163 return ChangeStatus::CHANGED;
3164 return ChangeStatus::UNCHANGED;
3165 }
3166
3167 bool isKnownToCauseUB(Instruction *I) const override {
3168 return KnownUBInsts.count(I);
3169 }
3170
3171 bool isAssumedToCauseUB(Instruction *I) const override {
3172 // In simple words, if an instruction is not in the assumed to _not_
3173 // cause UB, then it is assumed UB (that includes those
3174 // in the KnownUBInsts set). The rest is boilerplate
3175 // is to ensure that it is one of the instructions we test
3176 // for UB.
3177
3178 switch (I->getOpcode()) {
3179 case Instruction::Load:
3180 case Instruction::Store:
3181 case Instruction::AtomicCmpXchg:
3182 case Instruction::AtomicRMW:
3183 case Instruction::CondBr:
3184 return !AssumedNoUBInsts.count(I);
3185 default:
3186 return false;
3187 }
3188 return false;
3189 }
3190
3191 ChangeStatus manifest(Attributor &A) override {
3192 if (KnownUBInsts.empty())
3193 return ChangeStatus::UNCHANGED;
3194 for (Instruction *I : KnownUBInsts)
3195 A.changeToUnreachableAfterManifest(I);
3196 return ChangeStatus::CHANGED;
3197 }
3198
3199 /// See AbstractAttribute::getAsStr()
3200 const std::string getAsStr(Attributor *A) const override {
3201 return getAssumed() ? "undefined-behavior" : "no-ub";
3202 }
3203
3204 /// Note: The correctness of this analysis depends on the fact that the
3205 /// following 2 sets will stop changing after some point.
3206 /// "Change" here means that their size changes.
3207 /// The size of each set is monotonically increasing
3208 /// (we only add items to them) and it is upper bounded by the number of
3209 /// instructions in the processed function (we can never save more
3210 /// elements in either set than this number). Hence, at some point,
3211 /// they will stop increasing.
3212 /// Consequently, at some point, both sets will have stopped
3213 /// changing, effectively making the analysis reach a fixpoint.
3214
3215 /// Note: These 2 sets are disjoint and an instruction can be considered
3216 /// one of 3 things:
3217 /// 1) Known to cause UB (AAUndefinedBehavior could prove it) and put it in
3218 /// the KnownUBInsts set.
3219 /// 2) Assumed to cause UB (in every updateImpl, AAUndefinedBehavior
3220 /// has a reason to assume it).
3221 /// 3) Assumed to not cause UB. very other instruction - AAUndefinedBehavior
3222 /// could not find a reason to assume or prove that it can cause UB,
3223 /// hence it assumes it doesn't. We have a set for these instructions
3224 /// so that we don't reprocess them in every update.
3225 /// Note however that instructions in this set may cause UB.
3226
3227protected:
3228 /// A set of all live instructions _known_ to cause UB.
3229 SmallPtrSet<Instruction *, 8> KnownUBInsts;
3230
3231private:
3232 /// A set of all the (live) instructions that are assumed to _not_ cause UB.
3233 SmallPtrSet<Instruction *, 8> AssumedNoUBInsts;
3234
3235 // Should be called on updates in which if we're processing an instruction
3236 // \p I that depends on a value \p V, one of the following has to happen:
3237 // - If the value is assumed, then stop.
3238 // - If the value is known but undef, then consider it UB.
3239 // - Otherwise, do specific processing with the simplified value.
3240 // We return std::nullopt in the first 2 cases to signify that an appropriate
3241 // action was taken and the caller should stop.
3242 // Otherwise, we return the simplified value that the caller should
3243 // use for specific processing.
3244 std::optional<Value *> stopOnUndefOrAssumed(Attributor &A, Value *V,
3245 Instruction *I) {
3246 bool UsedAssumedInformation = false;
3247 std::optional<Value *> SimplifiedV =
3248 A.getAssumedSimplified(IRPosition::value(*V), *this,
3249 UsedAssumedInformation, AA::Interprocedural);
3250 if (!UsedAssumedInformation) {
3251 // Don't depend on assumed values.
3252 if (!SimplifiedV) {
3253 // If it is known (which we tested above) but it doesn't have a value,
3254 // then we can assume `undef` and hence the instruction is UB.
3255 KnownUBInsts.insert(I);
3256 return std::nullopt;
3257 }
3258 if (!*SimplifiedV)
3259 return nullptr;
3260 V = *SimplifiedV;
3261 }
3262 if (isa<UndefValue>(V)) {
3263 KnownUBInsts.insert(I);
3264 return std::nullopt;
3265 }
3266 return V;
3267 }
3268};
3269
3270struct AAUndefinedBehaviorFunction final : AAUndefinedBehaviorImpl {
3271 AAUndefinedBehaviorFunction(const IRPosition &IRP, Attributor &A)
3272 : AAUndefinedBehaviorImpl(IRP, A) {}
3273
3274 /// See AbstractAttribute::trackStatistics()
3275 void trackStatistics() const override {
3276 STATS_DECL(UndefinedBehaviorInstruction, Instruction,
3277 "Number of instructions known to have UB");
3278 BUILD_STAT_NAME(UndefinedBehaviorInstruction, Instruction) +=
3279 KnownUBInsts.size();
3280 }
3281};
3282} // namespace
3283
3284/// ------------------------ Will-Return Attributes ----------------------------
3285
3286namespace {
3287// Helper function that checks whether a function has any cycle which we don't
3288// know if it is bounded or not.
3289// Loops with maximum trip count are considered bounded, any other cycle not.
3290static bool mayContainUnboundedCycle(Function &F, Attributor &A) {
3291 ScalarEvolution *SE =
3292 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(F);
3293 LoopInfo *LI = A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(F);
3294 // If either SCEV or LoopInfo is not available for the function then we assume
3295 // any cycle to be unbounded cycle.
3296 // We use scc_iterator which uses Tarjan algorithm to find all the maximal
3297 // SCCs.To detect if there's a cycle, we only need to find the maximal ones.
3298 if (!SE || !LI) {
3299 for (scc_iterator<Function *> SCCI = scc_begin(&F); !SCCI.isAtEnd(); ++SCCI)
3300 if (SCCI.hasCycle())
3301 return true;
3302 return false;
3303 }
3304
3305 // If there's irreducible control, the function may contain non-loop cycles.
3307 return true;
3308
3309 // Any loop that does not have a max trip count is considered unbounded cycle.
3310 for (auto *L : LI->getLoopsInPreorder()) {
3311 if (!SE->getSmallConstantMaxTripCount(L))
3312 return true;
3313 }
3314 return false;
3315}
3316
3317struct AAWillReturnImpl : public AAWillReturn {
3318 AAWillReturnImpl(const IRPosition &IRP, Attributor &A)
3319 : AAWillReturn(IRP, A) {}
3320
3321 /// See AbstractAttribute::initialize(...).
3322 void initialize(Attributor &A) override {
3323 bool IsKnown;
3325 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
3326 (void)IsKnown;
3327 }
3328
3329 /// Check for `mustprogress` and `readonly` as they imply `willreturn`.
3330 bool isImpliedByMustprogressAndReadonly(Attributor &A, bool KnownOnly) {
3331 if (!A.hasAttr(getIRPosition(), {Attribute::MustProgress}))
3332 return false;
3333
3334 bool IsKnown;
3335 if (AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown))
3336 return IsKnown || !KnownOnly;
3337 return false;
3338 }
3339
3340 /// See AbstractAttribute::updateImpl(...).
3341 ChangeStatus updateImpl(Attributor &A) override {
3342 if (isImpliedByMustprogressAndReadonly(A, /* KnownOnly */ false))
3343 return ChangeStatus::UNCHANGED;
3344
3345 auto CheckForWillReturn = [&](Instruction &I) {
3347 bool IsKnown;
3349 A, this, IPos, DepClassTy::REQUIRED, IsKnown)) {
3350 if (IsKnown)
3351 return true;
3352 } else {
3353 return false;
3354 }
3355 bool IsKnownNoRecurse;
3357 A, this, IPos, DepClassTy::REQUIRED, IsKnownNoRecurse);
3358 };
3359
3360 bool UsedAssumedInformation = false;
3361 if (!A.checkForAllCallLikeInstructions(CheckForWillReturn, *this,
3362 UsedAssumedInformation))
3363 return indicatePessimisticFixpoint();
3364
3365 auto CheckForVolatile = [&](Instruction &I) {
3366 // Volatile operations are not willreturn.
3367 return !I.isVolatile();
3368 };
3369 if (!A.checkForAllInstructions(CheckForVolatile, *this,
3370 {Instruction::Load, Instruction::Store,
3371 Instruction::AtomicCmpXchg,
3372 Instruction::AtomicRMW},
3373 UsedAssumedInformation))
3374 return indicatePessimisticFixpoint();
3375
3376 return ChangeStatus::UNCHANGED;
3377 }
3378
3379 /// See AbstractAttribute::getAsStr()
3380 const std::string getAsStr(Attributor *A) const override {
3381 return getAssumed() ? "willreturn" : "may-noreturn";
3382 }
3383};
3384
3385struct AAWillReturnFunction final : AAWillReturnImpl {
3386 AAWillReturnFunction(const IRPosition &IRP, Attributor &A)
3387 : AAWillReturnImpl(IRP, A) {}
3388
3389 /// See AbstractAttribute::initialize(...).
3390 void initialize(Attributor &A) override {
3391 AAWillReturnImpl::initialize(A);
3392
3393 Function *F = getAnchorScope();
3394 assert(F && "Did expect an anchor function");
3395 if (F->isDeclaration() || mayContainUnboundedCycle(*F, A))
3396 indicatePessimisticFixpoint();
3397 }
3398
3399 /// See AbstractAttribute::trackStatistics()
3400 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(willreturn) }
3401};
3402
3403/// WillReturn attribute deduction for a call sites.
3404struct AAWillReturnCallSite final
3405 : AACalleeToCallSite<AAWillReturn, AAWillReturnImpl> {
3406 AAWillReturnCallSite(const IRPosition &IRP, Attributor &A)
3407 : AACalleeToCallSite<AAWillReturn, AAWillReturnImpl>(IRP, A) {}
3408
3409 /// See AbstractAttribute::updateImpl(...).
3410 ChangeStatus updateImpl(Attributor &A) override {
3411 if (isImpliedByMustprogressAndReadonly(A, /* KnownOnly */ false))
3412 return ChangeStatus::UNCHANGED;
3413
3414 return AACalleeToCallSite::updateImpl(A);
3415 }
3416
3417 /// See AbstractAttribute::trackStatistics()
3418 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(willreturn); }
3419};
3420} // namespace
3421
3422/// -------------------AAIntraFnReachability Attribute--------------------------
3423
3424/// All information associated with a reachability query. This boilerplate code
3425/// is used by both AAIntraFnReachability and AAInterFnReachability, with
3426/// different \p ToTy values.
3427template <typename ToTy> struct ReachabilityQueryInfo {
3428 enum class Reachable {
3431 };
3432
3433 /// Start here,
3434 const Instruction *From = nullptr;
3435 /// reach this place,
3436 const ToTy *To = nullptr;
3437 /// without going through any of these instructions,
3439 /// and remember if it worked:
3441
3442 /// Precomputed hash for this RQI.
3443 unsigned Hash = 0;
3444
3445 unsigned computeHashValue() const {
3446 assert(Hash == 0 && "Computed hash twice!");
3449 return const_cast<ReachabilityQueryInfo<ToTy> *>(this)->Hash =
3450 detail::combineHashValue(PairDMI ::getHashValue({From, To}),
3451 InstSetDMI::getHashValue(ExclusionSet));
3452 }
3453
3455 : From(From), To(To) {}
3456
3457 /// Constructor replacement to ensure unique and stable sets are used for the
3458 /// cache.
3460 const AA::InstExclusionSetTy *ES, bool MakeUnique)
3461 : From(&From), To(&To), ExclusionSet(ES) {
3462
3463 if (!ES || ES->empty()) {
3464 ExclusionSet = nullptr;
3465 } else if (MakeUnique) {
3466 ExclusionSet = A.getInfoCache().getOrCreateUniqueBlockExecutionSet(ES);
3467 }
3468 }
3469
3472};
3473
3474namespace llvm {
3475template <typename ToTy> struct DenseMapInfo<ReachabilityQueryInfo<ToTy> *> {
3478
3481
3484 return &TombstoneKey;
3485 }
3486 static unsigned getHashValue(const ReachabilityQueryInfo<ToTy> *RQI) {
3487 return RQI->Hash ? RQI->Hash : RQI->computeHashValue();
3488 }
3489 static bool isEqual(const ReachabilityQueryInfo<ToTy> *LHS,
3490 const ReachabilityQueryInfo<ToTy> *RHS) {
3491 if (!PairDMI::isEqual({LHS->From, LHS->To}, {RHS->From, RHS->To}))
3492 return false;
3493 return InstSetDMI::isEqual(LHS->ExclusionSet, RHS->ExclusionSet);
3494 }
3495};
3496
3497#define DefineKeys(ToTy) \
3498 template <> \
3499 ReachabilityQueryInfo<ToTy> \
3500 DenseMapInfo<ReachabilityQueryInfo<ToTy> *>::EmptyKey = \
3501 ReachabilityQueryInfo<ToTy>( \
3502 DenseMapInfo<const Instruction *>::getEmptyKey(), \
3503 DenseMapInfo<const ToTy *>::getEmptyKey()); \
3504 template <> \
3505 ReachabilityQueryInfo<ToTy> \
3506 DenseMapInfo<ReachabilityQueryInfo<ToTy> *>::TombstoneKey = \
3507 ReachabilityQueryInfo<ToTy>( \
3508 DenseMapInfo<const Instruction *>::getTombstoneKey(), \
3509 DenseMapInfo<const ToTy *>::getTombstoneKey());
3510
3512#undef DefineKeys
3513
3514} // namespace llvm
3515
3516namespace {
3517
3518template <typename BaseTy, typename ToTy>
3519struct CachedReachabilityAA : public BaseTy {
3520 using RQITy = ReachabilityQueryInfo<ToTy>;
3521
3522 CachedReachabilityAA(const IRPosition &IRP, Attributor &A) : BaseTy(IRP, A) {}
3523
3524 /// See AbstractAttribute::isQueryAA.
3525 bool isQueryAA() const override { return true; }
3526
3527 /// See AbstractAttribute::updateImpl(...).
3528 ChangeStatus updateImpl(Attributor &A) override {
3529 ChangeStatus Changed = ChangeStatus::UNCHANGED;
3530 for (unsigned u = 0, e = QueryVector.size(); u < e; ++u) {
3531 RQITy *RQI = QueryVector[u];
3532 if (RQI->Result == RQITy::Reachable::No &&
3533 isReachableImpl(A, *RQI, /*IsTemporaryRQI=*/false))
3534 Changed = ChangeStatus::CHANGED;
3535 }
3536 return Changed;
3537 }
3538
3539 virtual bool isReachableImpl(Attributor &A, RQITy &RQI,
3540 bool IsTemporaryRQI) = 0;
3541
3542 bool rememberResult(Attributor &A, typename RQITy::Reachable Result,
3543 RQITy &RQI, bool UsedExclusionSet, bool IsTemporaryRQI) {
3544 RQI.Result = Result;
3545
3546 // Remove the temporary RQI from the cache.
3547 if (IsTemporaryRQI)
3548 QueryCache.erase(&RQI);
3549
3550 // Insert a plain RQI (w/o exclusion set) if that makes sense. Two options:
3551 // 1) If it is reachable, it doesn't matter if we have an exclusion set for
3552 // this query. 2) We did not use the exclusion set, potentially because
3553 // there is none.
3554 if (Result == RQITy::Reachable::Yes || !UsedExclusionSet) {
3555 RQITy PlainRQI(RQI.From, RQI.To);
3556 if (!QueryCache.count(&PlainRQI)) {
3557 RQITy *RQIPtr = new (A.Allocator) RQITy(RQI.From, RQI.To);
3558 RQIPtr->Result = Result;
3559 QueryVector.push_back(RQIPtr);
3560 QueryCache.insert(RQIPtr);
3561 }
3562 }
3563
3564 // Check if we need to insert a new permanent RQI with the exclusion set.
3565 if (IsTemporaryRQI && Result != RQITy::Reachable::Yes && UsedExclusionSet) {
3566 assert((!RQI.ExclusionSet || !RQI.ExclusionSet->empty()) &&
3567 "Did not expect empty set!");
3568 RQITy *RQIPtr = new (A.Allocator)
3569 RQITy(A, *RQI.From, *RQI.To, RQI.ExclusionSet, true);
3570 assert(RQIPtr->Result == RQITy::Reachable::No && "Already reachable?");
3571 RQIPtr->Result = Result;
3572 assert(!QueryCache.count(RQIPtr));
3573 QueryVector.push_back(RQIPtr);
3574 QueryCache.insert(RQIPtr);
3575 }
3576
3577 if (Result == RQITy::Reachable::No && IsTemporaryRQI)
3578 A.registerForUpdate(*this);
3579 return Result == RQITy::Reachable::Yes;
3580 }
3581
3582 const std::string getAsStr(Attributor *A) const override {
3583 // TODO: Return the number of reachable queries.
3584 return "#queries(" + std::to_string(QueryVector.size()) + ")";
3585 }
3586
3587 bool checkQueryCache(Attributor &A, RQITy &StackRQI,
3588 typename RQITy::Reachable &Result) {
3589 if (!this->getState().isValidState()) {
3590 Result = RQITy::Reachable::Yes;
3591 return true;
3592 }
3593
3594 // If we have an exclusion set we might be able to find our answer by
3595 // ignoring it first.
3596 if (StackRQI.ExclusionSet) {
3597 RQITy PlainRQI(StackRQI.From, StackRQI.To);
3598 auto It = QueryCache.find(&PlainRQI);
3599 if (It != QueryCache.end() && (*It)->Result == RQITy::Reachable::No) {
3600 Result = RQITy::Reachable::No;
3601 return true;
3602 }
3603 }
3604
3605 auto It = QueryCache.find(&StackRQI);
3606 if (It != QueryCache.end()) {
3607 Result = (*It)->Result;
3608 return true;
3609 }
3610
3611 // Insert a temporary for recursive queries. We will replace it with a
3612 // permanent entry later.
3613 QueryCache.insert(&StackRQI);
3614 return false;
3615 }
3616
3617private:
3618 SmallVector<RQITy *> QueryVector;
3619 DenseSet<RQITy *> QueryCache;
3620};
3621
3622struct AAIntraFnReachabilityFunction final
3623 : public CachedReachabilityAA<AAIntraFnReachability, Instruction> {
3624 using Base = CachedReachabilityAA<AAIntraFnReachability, Instruction>;
3625 AAIntraFnReachabilityFunction(const IRPosition &IRP, Attributor &A)
3626 : Base(IRP, A) {
3627 DT = A.getInfoCache().getAnalysisResultForFunction<DominatorTreeAnalysis>(
3628 *IRP.getAssociatedFunction());
3629 }
3630
3631 bool isAssumedReachable(
3632 Attributor &A, const Instruction &From, const Instruction &To,
3633 const AA::InstExclusionSetTy *ExclusionSet) const override {
3634 auto *NonConstThis = const_cast<AAIntraFnReachabilityFunction *>(this);
3635 if (&From == &To)
3636 return true;
3637
3638 RQITy StackRQI(A, From, To, ExclusionSet, false);
3639 RQITy::Reachable Result;
3640 if (!NonConstThis->checkQueryCache(A, StackRQI, Result))
3641 return NonConstThis->isReachableImpl(A, StackRQI,
3642 /*IsTemporaryRQI=*/true);
3643 return Result == RQITy::Reachable::Yes;
3644 }
3645
3646 ChangeStatus updateImpl(Attributor &A) override {
3647 // We only depend on liveness. DeadEdges is all we care about, check if any
3648 // of them changed.
3649 auto *LivenessAA =
3650 A.getAAFor<AAIsDead>(*this, getIRPosition(), DepClassTy::OPTIONAL);
3651 if (LivenessAA &&
3652 llvm::all_of(DeadEdges,
3653 [&](const auto &DeadEdge) {
3654 return LivenessAA->isEdgeDead(DeadEdge.first,
3655 DeadEdge.second);
3656 }) &&
3657 llvm::all_of(DeadBlocks, [&](const BasicBlock *BB) {
3658 return LivenessAA->isAssumedDead(BB);
3659 })) {
3660 return ChangeStatus::UNCHANGED;
3661 }
3662 DeadEdges.clear();
3663 DeadBlocks.clear();
3664 return Base::updateImpl(A);
3665 }
3666
3667 bool isReachableImpl(Attributor &A, RQITy &RQI,
3668 bool IsTemporaryRQI) override {
3669 const Instruction *Origin = RQI.From;
3670 bool UsedExclusionSet = false;
3671
3672 auto WillReachInBlock = [&](const Instruction &From, const Instruction &To,
3673 const AA::InstExclusionSetTy *ExclusionSet) {
3674 const Instruction *IP = &From;
3675 while (IP && IP != &To) {
3676 if (ExclusionSet && IP != Origin && ExclusionSet->count(IP)) {
3677 UsedExclusionSet = true;
3678 break;
3679 }
3680 IP = IP->getNextNode();
3681 }
3682 return IP == &To;
3683 };
3684
3685 const BasicBlock *FromBB = RQI.From->getParent();
3686 const BasicBlock *ToBB = RQI.To->getParent();
3687 assert(FromBB->getParent() == ToBB->getParent() &&
3688 "Not an intra-procedural query!");
3689
3690 // Check intra-block reachability, however, other reaching paths are still
3691 // possible.
3692 if (FromBB == ToBB &&
3693 WillReachInBlock(*RQI.From, *RQI.To, RQI.ExclusionSet))
3694 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
3695 IsTemporaryRQI);
3696
3697 // Check if reaching the ToBB block is sufficient or if even that would not
3698 // ensure reaching the target. In the latter case we are done.
3699 if (!WillReachInBlock(ToBB->front(), *RQI.To, RQI.ExclusionSet))
3700 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
3701 IsTemporaryRQI);
3702
3703 const Function *Fn = FromBB->getParent();
3704 SmallPtrSet<const BasicBlock *, 16> ExclusionBlocks;
3705 if (RQI.ExclusionSet)
3706 for (auto *I : *RQI.ExclusionSet)
3707 if (I->getFunction() == Fn)
3708 ExclusionBlocks.insert(I->getParent());
3709
3710 // Check if we make it out of the FromBB block at all.
3711 if (ExclusionBlocks.count(FromBB) &&
3712 !WillReachInBlock(*RQI.From, *FromBB->getTerminator(),
3713 RQI.ExclusionSet))
3714 return rememberResult(A, RQITy::Reachable::No, RQI, true, IsTemporaryRQI);
3715
3716 auto *LivenessAA =
3717 A.getAAFor<AAIsDead>(*this, getIRPosition(), DepClassTy::OPTIONAL);
3718 if (LivenessAA && LivenessAA->isAssumedDead(ToBB)) {
3719 DeadBlocks.insert(ToBB);
3720 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
3721 IsTemporaryRQI);
3722 }
3723
3724 SmallPtrSet<const BasicBlock *, 16> Visited;
3726 Worklist.push_back(FromBB);
3727
3728 DenseSet<std::pair<const BasicBlock *, const BasicBlock *>> LocalDeadEdges;
3729 while (!Worklist.empty()) {
3730 const BasicBlock *BB = Worklist.pop_back_val();
3731 if (!Visited.insert(BB).second)
3732 continue;
3733 for (const BasicBlock *SuccBB : successors(BB)) {
3734 if (LivenessAA && LivenessAA->isEdgeDead(BB, SuccBB)) {
3735 LocalDeadEdges.insert({BB, SuccBB});
3736 continue;
3737 }
3738 // We checked before if we just need to reach the ToBB block.
3739 if (SuccBB == ToBB)
3740 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
3741 IsTemporaryRQI);
3742 if (DT && ExclusionBlocks.empty() && DT->dominates(BB, ToBB))
3743 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
3744 IsTemporaryRQI);
3745
3746 if (ExclusionBlocks.count(SuccBB)) {
3747 UsedExclusionSet = true;
3748 continue;
3749 }
3750 Worklist.push_back(SuccBB);
3751 }
3752 }
3753
3754 DeadEdges.insert_range(LocalDeadEdges);
3755 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
3756 IsTemporaryRQI);
3757 }
3758
3759 /// See AbstractAttribute::trackStatistics()
3760 void trackStatistics() const override {}
3761
3762private:
3763 // Set of assumed dead blocks we used in the last query. If any changes we
3764 // update the state.
3765 DenseSet<const BasicBlock *> DeadBlocks;
3766
3767 // Set of assumed dead edges we used in the last query. If any changes we
3768 // update the state.
3769 DenseSet<std::pair<const BasicBlock *, const BasicBlock *>> DeadEdges;
3770
3771 /// The dominator tree of the function to short-circuit reasoning.
3772 const DominatorTree *DT = nullptr;
3773};
3774} // namespace
3775
3776/// ------------------------ NoAlias Argument Attribute ------------------------
3777
3779 Attribute::AttrKind ImpliedAttributeKind,
3780 bool IgnoreSubsumingPositions) {
3781 assert(ImpliedAttributeKind == Attribute::NoAlias &&
3782 "Unexpected attribute kind");
3783 Value *Val = &IRP.getAssociatedValue();
3785 if (isa<AllocaInst>(Val))
3786 return true;
3787 } else {
3788 IgnoreSubsumingPositions = true;
3789 }
3790
3791 if (isa<UndefValue>(Val))
3792 return true;
3793
3794 if (isa<ConstantPointerNull>(Val) &&
3797 return true;
3798
3799 if (A.hasAttr(IRP, {Attribute::ByVal, Attribute::NoAlias},
3800 IgnoreSubsumingPositions, Attribute::NoAlias))
3801 return true;
3802
3803 return false;
3804}
3805
3806namespace {
3807struct AANoAliasImpl : AANoAlias {
3808 AANoAliasImpl(const IRPosition &IRP, Attributor &A) : AANoAlias(IRP, A) {
3809 assert(getAssociatedType()->isPointerTy() &&
3810 "Noalias is a pointer attribute");
3811 }
3812
3813 const std::string getAsStr(Attributor *A) const override {
3814 return getAssumed() ? "noalias" : "may-alias";
3815 }
3816};
3817
3818/// NoAlias attribute for a floating value.
3819struct AANoAliasFloating final : AANoAliasImpl {
3820 AANoAliasFloating(const IRPosition &IRP, Attributor &A)
3821 : AANoAliasImpl(IRP, A) {}
3822
3823 /// See AbstractAttribute::updateImpl(...).
3824 ChangeStatus updateImpl(Attributor &A) override {
3825 // TODO: Implement this.
3826 return indicatePessimisticFixpoint();
3827 }
3828
3829 /// See AbstractAttribute::trackStatistics()
3830 void trackStatistics() const override {
3832 }
3833};
3834
3835/// NoAlias attribute for an argument.
3836struct AANoAliasArgument final
3837 : AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl> {
3838 using Base = AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl>;
3839 AANoAliasArgument(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {}
3840
3841 /// See AbstractAttribute::update(...).
3842 ChangeStatus updateImpl(Attributor &A) override {
3843 // We have to make sure no-alias on the argument does not break
3844 // synchronization when this is a callback argument, see also [1] below.
3845 // If synchronization cannot be affected, we delegate to the base updateImpl
3846 // function, otherwise we give up for now.
3847
3848 // If the function is no-sync, no-alias cannot break synchronization.
3849 bool IsKnownNoSycn;
3851 A, this, IRPosition::function_scope(getIRPosition()),
3852 DepClassTy::OPTIONAL, IsKnownNoSycn))
3853 return Base::updateImpl(A);
3854
3855 // If the argument is read-only, no-alias cannot break synchronization.
3856 bool IsKnown;
3857 if (AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown))
3858 return Base::updateImpl(A);
3859
3860 // If the argument is never passed through callbacks, no-alias cannot break
3861 // synchronization.
3862 bool UsedAssumedInformation = false;
3863 if (A.checkForAllCallSites(
3864 [](AbstractCallSite ACS) { return !ACS.isCallbackCall(); }, *this,
3865 true, UsedAssumedInformation))
3866 return Base::updateImpl(A);
3867
3868 // TODO: add no-alias but make sure it doesn't break synchronization by
3869 // introducing fake uses. See:
3870 // [1] Compiler Optimizations for OpenMP, J. Doerfert and H. Finkel,
3871 // International Workshop on OpenMP 2018,
3872 // http://compilers.cs.uni-saarland.de/people/doerfert/par_opt18.pdf
3873
3874 return indicatePessimisticFixpoint();
3875 }
3876
3877 /// See AbstractAttribute::trackStatistics()
3878 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noalias) }
3879};
3880
3881struct AANoAliasCallSiteArgument final : AANoAliasImpl {
3882 AANoAliasCallSiteArgument(const IRPosition &IRP, Attributor &A)
3883 : AANoAliasImpl(IRP, A) {}
3884
3885 /// Determine if the underlying value may alias with the call site argument
3886 /// \p OtherArgNo of \p ICS (= the underlying call site).
3887 bool mayAliasWithArgument(Attributor &A, AAResults *&AAR,
3888 const AAMemoryBehavior &MemBehaviorAA,
3889 const CallBase &CB, unsigned OtherArgNo) {
3890 // We do not need to worry about aliasing with the underlying IRP.
3891 if (this->getCalleeArgNo() == (int)OtherArgNo)
3892 return false;
3893
3894 // If it is not a pointer or pointer vector we do not alias.
3895 const Value *ArgOp = CB.getArgOperand(OtherArgNo);
3896 if (!ArgOp->getType()->isPtrOrPtrVectorTy())
3897 return false;
3898
3899 auto *CBArgMemBehaviorAA = A.getAAFor<AAMemoryBehavior>(
3900 *this, IRPosition::callsite_argument(CB, OtherArgNo), DepClassTy::NONE);
3901
3902 // If the argument is readnone, there is no read-write aliasing.
3903 if (CBArgMemBehaviorAA && CBArgMemBehaviorAA->isAssumedReadNone()) {
3904 A.recordDependence(*CBArgMemBehaviorAA, *this, DepClassTy::OPTIONAL);
3905 return false;
3906 }
3907
3908 // If the argument is readonly and the underlying value is readonly, there
3909 // is no read-write aliasing.
3910 bool IsReadOnly = MemBehaviorAA.isAssumedReadOnly();
3911 if (CBArgMemBehaviorAA && CBArgMemBehaviorAA->isAssumedReadOnly() &&
3912 IsReadOnly) {
3913 A.recordDependence(MemBehaviorAA, *this, DepClassTy::OPTIONAL);
3914 A.recordDependence(*CBArgMemBehaviorAA, *this, DepClassTy::OPTIONAL);
3915 return false;
3916 }
3917
3918 // We have to utilize actual alias analysis queries so we need the object.
3919 if (!AAR)
3920 AAR = A.getInfoCache().getAnalysisResultForFunction<AAManager>(
3921 *getAnchorScope());
3922
3923 // Try to rule it out at the call site.
3924 bool IsAliasing = !AAR || !AAR->isNoAlias(&getAssociatedValue(), ArgOp);
3925 LLVM_DEBUG(dbgs() << "[NoAliasCSArg] Check alias between "
3926 "callsite arguments: "
3927 << getAssociatedValue() << " " << *ArgOp << " => "
3928 << (IsAliasing ? "" : "no-") << "alias \n");
3929
3930 return IsAliasing;
3931 }
3932
3933 bool isKnownNoAliasDueToNoAliasPreservation(
3934 Attributor &A, AAResults *&AAR, const AAMemoryBehavior &MemBehaviorAA) {
3935 // We can deduce "noalias" if the following conditions hold.
3936 // (i) Associated value is assumed to be noalias in the definition.
3937 // (ii) Associated value is assumed to be no-capture in all the uses
3938 // possibly executed before this callsite.
3939 // (iii) There is no other pointer argument which could alias with the
3940 // value.
3941
3942 const IRPosition &VIRP = IRPosition::value(getAssociatedValue());
3943 const Function *ScopeFn = VIRP.getAnchorScope();
3944 // Check whether the value is captured in the scope using AANoCapture.
3945 // Look at CFG and check only uses possibly executed before this
3946 // callsite.
3947 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
3948 Instruction *UserI = cast<Instruction>(U.getUser());
3949
3950 // If UserI is the curr instruction and there is a single potential use of
3951 // the value in UserI we allow the use.
3952 // TODO: We should inspect the operands and allow those that cannot alias
3953 // with the value.
3954 if (UserI == getCtxI() && UserI->getNumOperands() == 1)
3955 return true;
3956
3957 if (ScopeFn) {
3958 if (auto *CB = dyn_cast<CallBase>(UserI)) {
3959 if (CB->isArgOperand(&U)) {
3960
3961 unsigned ArgNo = CB->getArgOperandNo(&U);
3962
3963 bool IsKnownNoCapture;
3965 A, this, IRPosition::callsite_argument(*CB, ArgNo),
3966 DepClassTy::OPTIONAL, IsKnownNoCapture))
3967 return true;
3968 }
3969 }
3970
3972 A, *UserI, *getCtxI(), *this, /* ExclusionSet */ nullptr,
3973 [ScopeFn](const Function &Fn) { return &Fn != ScopeFn; }))
3974 return true;
3975 }
3976
3977 // TODO: We should track the capturing uses in AANoCapture but the problem
3978 // is CGSCC runs. For those we would need to "allow" AANoCapture for
3979 // a value in the module slice.
3980 // TODO(captures): Make this more precise.
3981 UseCaptureInfo CI = DetermineUseCaptureKind(U, /*Base=*/nullptr);
3982 if (capturesNothing(CI))
3983 return true;
3984 if (CI.isPassthrough()) {
3985 Follow = true;
3986 return true;
3987 }
3988 LLVM_DEBUG(dbgs() << "[AANoAliasCSArg] Unknown user: " << *UserI << "\n");
3989 return false;
3990 };
3991
3992 bool IsKnownNoCapture;
3993 const AANoCapture *NoCaptureAA = nullptr;
3994 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
3995 A, this, VIRP, DepClassTy::NONE, IsKnownNoCapture, false, &NoCaptureAA);
3996 if (!IsAssumedNoCapture &&
3997 (!NoCaptureAA || !NoCaptureAA->isAssumedNoCaptureMaybeReturned())) {
3998 if (!A.checkForAllUses(UsePred, *this, getAssociatedValue())) {
3999 LLVM_DEBUG(
4000 dbgs() << "[AANoAliasCSArg] " << getAssociatedValue()
4001 << " cannot be noalias as it is potentially captured\n");
4002 return false;
4003 }
4004 }
4005 if (NoCaptureAA)
4006 A.recordDependence(*NoCaptureAA, *this, DepClassTy::OPTIONAL);
4007
4008 // Check there is no other pointer argument which could alias with the
4009 // value passed at this call site.
4010 // TODO: AbstractCallSite
4011 const auto &CB = cast<CallBase>(getAnchorValue());
4012 for (unsigned OtherArgNo = 0; OtherArgNo < CB.arg_size(); OtherArgNo++)
4013 if (mayAliasWithArgument(A, AAR, MemBehaviorAA, CB, OtherArgNo))
4014 return false;
4015
4016 return true;
4017 }
4018
4019 /// See AbstractAttribute::updateImpl(...).
4020 ChangeStatus updateImpl(Attributor &A) override {
4021 // If the argument is readnone we are done as there are no accesses via the
4022 // argument.
4023 auto *MemBehaviorAA =
4024 A.getAAFor<AAMemoryBehavior>(*this, getIRPosition(), DepClassTy::NONE);
4025 if (MemBehaviorAA && MemBehaviorAA->isAssumedReadNone()) {
4026 A.recordDependence(*MemBehaviorAA, *this, DepClassTy::OPTIONAL);
4027 return ChangeStatus::UNCHANGED;
4028 }
4029
4030 bool IsKnownNoAlias;
4031 const IRPosition &VIRP = IRPosition::value(getAssociatedValue());
4033 A, this, VIRP, DepClassTy::REQUIRED, IsKnownNoAlias)) {
4034 LLVM_DEBUG(dbgs() << "[AANoAlias] " << getAssociatedValue()
4035 << " is not no-alias at the definition\n");
4036 return indicatePessimisticFixpoint();
4037 }
4038
4039 AAResults *AAR = nullptr;
4040 if (MemBehaviorAA &&
4041 isKnownNoAliasDueToNoAliasPreservation(A, AAR, *MemBehaviorAA)) {
4042 LLVM_DEBUG(
4043 dbgs() << "[AANoAlias] No-Alias deduced via no-alias preservation\n");
4044 return ChangeStatus::UNCHANGED;
4045 }
4046
4047 return indicatePessimisticFixpoint();
4048 }
4049
4050 /// See AbstractAttribute::trackStatistics()
4051 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(noalias) }
4052};
4053
4054/// NoAlias attribute for function return value.
4055struct AANoAliasReturned final : AANoAliasImpl {
4056 AANoAliasReturned(const IRPosition &IRP, Attributor &A)
4057 : AANoAliasImpl(IRP, A) {}
4058
4059 /// See AbstractAttribute::updateImpl(...).
4060 ChangeStatus updateImpl(Attributor &A) override {
4061
4062 auto CheckReturnValue = [&](Value &RV) -> bool {
4063 if (Constant *C = dyn_cast<Constant>(&RV))
4064 if (C->isNullValue() || isa<UndefValue>(C))
4065 return true;
4066
4067 /// For now, we can only deduce noalias if we have call sites.
4068 /// FIXME: add more support.
4069 if (!isa<CallBase>(&RV))
4070 return false;
4071
4072 const IRPosition &RVPos = IRPosition::value(RV);
4073 bool IsKnownNoAlias;
4075 A, this, RVPos, DepClassTy::REQUIRED, IsKnownNoAlias))
4076 return false;
4077
4078 bool IsKnownNoCapture;
4079 const AANoCapture *NoCaptureAA = nullptr;
4080 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
4081 A, this, RVPos, DepClassTy::REQUIRED, IsKnownNoCapture, false,
4082 &NoCaptureAA);
4083 return IsAssumedNoCapture ||
4084 (NoCaptureAA && NoCaptureAA->isAssumedNoCaptureMaybeReturned());
4085 };
4086
4087 if (!A.checkForAllReturnedValues(CheckReturnValue, *this))
4088 return indicatePessimisticFixpoint();
4089
4090 return ChangeStatus::UNCHANGED;
4091 }
4092
4093 /// See AbstractAttribute::trackStatistics()
4094 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noalias) }
4095};
4096
4097/// NoAlias attribute deduction for a call site return value.
4098struct AANoAliasCallSiteReturned final
4099 : AACalleeToCallSite<AANoAlias, AANoAliasImpl> {
4100 AANoAliasCallSiteReturned(const IRPosition &IRP, Attributor &A)
4101 : AACalleeToCallSite<AANoAlias, AANoAliasImpl>(IRP, A) {}
4102
4103 /// See AbstractAttribute::trackStatistics()
4104 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(noalias); }
4105};
4106} // namespace
4107
4108/// -------------------AAIsDead Function Attribute-----------------------
4109
4110namespace {
4111struct AAIsDeadValueImpl : public AAIsDead {
4112 AAIsDeadValueImpl(const IRPosition &IRP, Attributor &A) : AAIsDead(IRP, A) {}
4113
4114 /// See AAIsDead::isAssumedDead().
4115 bool isAssumedDead() const override { return isAssumed(IS_DEAD); }
4116
4117 /// See AAIsDead::isKnownDead().
4118 bool isKnownDead() const override { return isKnown(IS_DEAD); }
4119
4120 /// See AAIsDead::isAssumedDead(BasicBlock *).
4121 bool isAssumedDead(const BasicBlock *BB) const override { return false; }
4122
4123 /// See AAIsDead::isKnownDead(BasicBlock *).
4124 bool isKnownDead(const BasicBlock *BB) const override { return false; }
4125
4126 /// See AAIsDead::isAssumedDead(Instruction *I).
4127 bool isAssumedDead(const Instruction *I) const override {
4128 return I == getCtxI() && isAssumedDead();
4129 }
4130
4131 /// See AAIsDead::isKnownDead(Instruction *I).
4132 bool isKnownDead(const Instruction *I) const override {
4133 return isAssumedDead(I) && isKnownDead();
4134 }
4135
4136 /// See AbstractAttribute::getAsStr().
4137 const std::string getAsStr(Attributor *A) const override {
4138 return isAssumedDead() ? "assumed-dead" : "assumed-live";
4139 }
4140
4141 /// Check if all uses are assumed dead.
4142 bool areAllUsesAssumedDead(Attributor &A, Value &V) {
4143 // Callers might not check the type, void has no uses.
4144 if (V.getType()->isVoidTy() || V.use_empty())
4145 return true;
4146
4147 // If we replace a value with a constant there are no uses left afterwards.
4148 if (!isa<Constant>(V)) {
4149 if (auto *I = dyn_cast<Instruction>(&V))
4150 if (!A.isRunOn(*I->getFunction()))
4151 return false;
4152 bool UsedAssumedInformation = false;
4153 std::optional<Constant *> C =
4154 A.getAssumedConstant(V, *this, UsedAssumedInformation);
4155 if (!C || *C)
4156 return true;
4157 }
4158
4159 auto UsePred = [&](const Use &U, bool &Follow) { return false; };
4160 // Explicitly set the dependence class to required because we want a long
4161 // chain of N dependent instructions to be considered live as soon as one is
4162 // without going through N update cycles. This is not required for
4163 // correctness.
4164 return A.checkForAllUses(UsePred, *this, V, /* CheckBBLivenessOnly */ false,
4165 DepClassTy::REQUIRED,
4166 /* IgnoreDroppableUses */ false);
4167 }
4168
4169 /// Determine if \p I is assumed to be side-effect free.
4170 bool isAssumedSideEffectFree(Attributor &A, Instruction *I) {
4172 return true;
4173
4174 if (!I->isTerminator() && !I->mayHaveSideEffects())
4175 return true;
4176
4177 auto *CB = dyn_cast<CallBase>(I);
4178 if (!CB || isa<IntrinsicInst>(CB))
4179 return false;
4180
4181 const IRPosition &CallIRP = IRPosition::callsite_function(*CB);
4182
4183 bool IsKnownNoUnwind;
4185 A, this, CallIRP, DepClassTy::OPTIONAL, IsKnownNoUnwind))
4186 return false;
4187
4188 bool IsKnown;
4189 return AA::isAssumedReadOnly(A, CallIRP, *this, IsKnown);
4190 }
4191};
4192
4193struct AAIsDeadFloating : public AAIsDeadValueImpl {
4194 AAIsDeadFloating(const IRPosition &IRP, Attributor &A)
4195 : AAIsDeadValueImpl(IRP, A) {}
4196
4197 /// See AbstractAttribute::initialize(...).
4198 void initialize(Attributor &A) override {
4199 AAIsDeadValueImpl::initialize(A);
4200
4201 if (isa<UndefValue>(getAssociatedValue())) {
4202 indicatePessimisticFixpoint();
4203 return;
4204 }
4205
4206 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
4207 if (!isAssumedSideEffectFree(A, I)) {
4209 indicatePessimisticFixpoint();
4210 else
4211 removeAssumedBits(HAS_NO_EFFECT);
4212 }
4213 }
4214
4215 bool isDeadFence(Attributor &A, FenceInst &FI) {
4216 const auto *ExecDomainAA = A.lookupAAFor<AAExecutionDomain>(
4217 IRPosition::function(*FI.getFunction()), *this, DepClassTy::NONE);
4218 if (!ExecDomainAA || !ExecDomainAA->isNoOpFence(FI))
4219 return false;
4220 A.recordDependence(*ExecDomainAA, *this, DepClassTy::OPTIONAL);
4221 return true;
4222 }
4223
4224 bool isDeadStore(Attributor &A, StoreInst &SI,
4225 SmallSetVector<Instruction *, 8> *AssumeOnlyInst = nullptr) {
4226 // Lang ref now states volatile store is not UB/dead, let's skip them.
4227 if (SI.isVolatile())
4228 return false;
4229
4230 // If we are collecting assumes to be deleted we are in the manifest stage.
4231 // It's problematic to collect the potential copies again now so we use the
4232 // cached ones.
4233 bool UsedAssumedInformation = false;
4234 if (!AssumeOnlyInst) {
4235 PotentialCopies.clear();
4236 if (!AA::getPotentialCopiesOfStoredValue(A, SI, PotentialCopies, *this,
4237 UsedAssumedInformation)) {
4238 LLVM_DEBUG(
4239 dbgs()
4240 << "[AAIsDead] Could not determine potential copies of store!\n");
4241 return false;
4242 }
4243 }
4244 LLVM_DEBUG(dbgs() << "[AAIsDead] Store has " << PotentialCopies.size()
4245 << " potential copies.\n");
4246
4247 InformationCache &InfoCache = A.getInfoCache();
4248 return llvm::all_of(PotentialCopies, [&](Value *V) {
4249 if (A.isAssumedDead(IRPosition::value(*V), this, nullptr,
4250 UsedAssumedInformation))
4251 return true;
4252 if (auto *LI = dyn_cast<LoadInst>(V)) {
4253 if (llvm::all_of(LI->uses(), [&](const Use &U) {
4254 auto &UserI = cast<Instruction>(*U.getUser());
4255 if (InfoCache.isOnlyUsedByAssume(UserI)) {
4256 if (AssumeOnlyInst)
4257 AssumeOnlyInst->insert(&UserI);
4258 return true;
4259 }
4260 return A.isAssumedDead(U, this, nullptr, UsedAssumedInformation);
4261 })) {
4262 return true;
4263 }
4264 }
4265 LLVM_DEBUG(dbgs() << "[AAIsDead] Potential copy " << *V
4266 << " is assumed live!\n");
4267 return false;
4268 });
4269 }
4270
4271 /// See AbstractAttribute::getAsStr().
4272 const std::string getAsStr(Attributor *A) const override {
4273 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
4275 if (isValidState())
4276 return "assumed-dead-store";
4278 if (isValidState())
4279 return "assumed-dead-fence";
4280 return AAIsDeadValueImpl::getAsStr(A);
4281 }
4282
4283 /// See AbstractAttribute::updateImpl(...).
4284 ChangeStatus updateImpl(Attributor &A) override {
4285 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
4286 if (auto *SI = dyn_cast_or_null<StoreInst>(I)) {
4287 if (!isDeadStore(A, *SI))
4288 return indicatePessimisticFixpoint();
4289 } else if (auto *FI = dyn_cast_or_null<FenceInst>(I)) {
4290 if (!isDeadFence(A, *FI))
4291 return indicatePessimisticFixpoint();
4292 } else {
4293 if (!isAssumedSideEffectFree(A, I))
4294 return indicatePessimisticFixpoint();
4295 if (!areAllUsesAssumedDead(A, getAssociatedValue()))
4296 return indicatePessimisticFixpoint();
4297 }
4299 }
4300
4301 bool isRemovableStore() const override {
4302 return isAssumed(IS_REMOVABLE) && isa<StoreInst>(&getAssociatedValue());
4303 }
4304
4305 /// See AbstractAttribute::manifest(...).
4306 ChangeStatus manifest(Attributor &A) override {
4307 Value &V = getAssociatedValue();
4308 if (auto *I = dyn_cast<Instruction>(&V)) {
4309 // If we get here we basically know the users are all dead. We check if
4310 // isAssumedSideEffectFree returns true here again because it might not be
4311 // the case and only the users are dead but the instruction (=call) is
4312 // still needed.
4313 if (auto *SI = dyn_cast<StoreInst>(I)) {
4314 SmallSetVector<Instruction *, 8> AssumeOnlyInst;
4315 bool IsDead = isDeadStore(A, *SI, &AssumeOnlyInst);
4316 (void)IsDead;
4317 assert(IsDead && "Store was assumed to be dead!");
4318 A.deleteAfterManifest(*I);
4319 for (size_t i = 0; i < AssumeOnlyInst.size(); ++i) {
4320 Instruction *AOI = AssumeOnlyInst[i];
4321 for (auto *Usr : AOI->users())
4322 AssumeOnlyInst.insert(cast<Instruction>(Usr));
4323 A.deleteAfterManifest(*AOI);
4324 }
4325 return ChangeStatus::CHANGED;
4326 }
4327 if (auto *FI = dyn_cast<FenceInst>(I)) {
4328 assert(isDeadFence(A, *FI));
4329 A.deleteAfterManifest(*FI);
4330 return ChangeStatus::CHANGED;
4331 }
4332 if (isAssumedSideEffectFree(A, I) && !isa<InvokeInst>(I)) {
4333 A.deleteAfterManifest(*I);
4334 return ChangeStatus::CHANGED;
4335 }
4336 }
4338 }
4339
4340 /// See AbstractAttribute::trackStatistics()
4341 void trackStatistics() const override {
4343 }
4344
4345private:
4346 // The potential copies of a dead store, used for deletion during manifest.
4347 SmallSetVector<Value *, 4> PotentialCopies;
4348};
4349
4350struct AAIsDeadArgument : public AAIsDeadFloating {
4351 AAIsDeadArgument(const IRPosition &IRP, Attributor &A)
4352 : AAIsDeadFloating(IRP, A) {}
4353
4354 /// See AbstractAttribute::manifest(...).
4355 ChangeStatus manifest(Attributor &A) override {
4356 Argument &Arg = *getAssociatedArgument();
4357 if (A.isValidFunctionSignatureRewrite(Arg, /* ReplacementTypes */ {}))
4358 if (A.registerFunctionSignatureRewrite(
4359 Arg, /* ReplacementTypes */ {},
4362 return ChangeStatus::CHANGED;
4363 }
4364 return ChangeStatus::UNCHANGED;
4365 }
4366
4367 /// See AbstractAttribute::trackStatistics()
4368 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(IsDead) }
4369};
4370
4371struct AAIsDeadCallSiteArgument : public AAIsDeadValueImpl {
4372 AAIsDeadCallSiteArgument(const IRPosition &IRP, Attributor &A)
4373 : AAIsDeadValueImpl(IRP, A) {}
4374
4375 /// See AbstractAttribute::initialize(...).
4376 void initialize(Attributor &A) override {
4377 AAIsDeadValueImpl::initialize(A);
4378 if (isa<UndefValue>(getAssociatedValue()))
4379 indicatePessimisticFixpoint();
4380 }
4381
4382 /// See AbstractAttribute::updateImpl(...).
4383 ChangeStatus updateImpl(Attributor &A) override {
4384 // TODO: Once we have call site specific value information we can provide
4385 // call site specific liveness information and then it makes
4386 // sense to specialize attributes for call sites arguments instead of
4387 // redirecting requests to the callee argument.
4388 Argument *Arg = getAssociatedArgument();
4389 if (!Arg)
4390 return indicatePessimisticFixpoint();
4391 const IRPosition &ArgPos = IRPosition::argument(*Arg);
4392 auto *ArgAA = A.getAAFor<AAIsDead>(*this, ArgPos, DepClassTy::REQUIRED);
4393 if (!ArgAA)
4394 return indicatePessimisticFixpoint();
4395 return clampStateAndIndicateChange(getState(), ArgAA->getState());
4396 }
4397
4398 /// See AbstractAttribute::manifest(...).
4399 ChangeStatus manifest(Attributor &A) override {
4400 CallBase &CB = cast<CallBase>(getAnchorValue());
4401 Use &U = CB.getArgOperandUse(getCallSiteArgNo());
4402 assert(!isa<UndefValue>(U.get()) &&
4403 "Expected undef values to be filtered out!");
4404 UndefValue &UV = *UndefValue::get(U->getType());
4405 if (A.changeUseAfterManifest(U, UV))
4406 return ChangeStatus::CHANGED;
4407 return ChangeStatus::UNCHANGED;
4408 }
4409
4410 /// See AbstractAttribute::trackStatistics()
4411 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(IsDead) }
4412};
4413
4414struct AAIsDeadCallSiteReturned : public AAIsDeadFloating {
4415 AAIsDeadCallSiteReturned(const IRPosition &IRP, Attributor &A)
4416 : AAIsDeadFloating(IRP, A) {}
4417
4418 /// See AAIsDead::isAssumedDead().
4419 bool isAssumedDead() const override {
4420 return AAIsDeadFloating::isAssumedDead() && IsAssumedSideEffectFree;
4421 }
4422
4423 /// See AbstractAttribute::initialize(...).
4424 void initialize(Attributor &A) override {
4425 AAIsDeadFloating::initialize(A);
4426 if (isa<UndefValue>(getAssociatedValue())) {
4427 indicatePessimisticFixpoint();
4428 return;
4429 }
4430
4431 // We track this separately as a secondary state.
4432 IsAssumedSideEffectFree = isAssumedSideEffectFree(A, getCtxI());
4433 }
4434
4435 /// See AbstractAttribute::updateImpl(...).
4436 ChangeStatus updateImpl(Attributor &A) override {
4437 ChangeStatus Changed = ChangeStatus::UNCHANGED;
4438 if (IsAssumedSideEffectFree && !isAssumedSideEffectFree(A, getCtxI())) {
4439 IsAssumedSideEffectFree = false;
4440 Changed = ChangeStatus::CHANGED;
4441 }
4442 if (!areAllUsesAssumedDead(A, getAssociatedValue()))
4443 return indicatePessimisticFixpoint();
4444 return Changed;
4445 }
4446
4447 /// See AbstractAttribute::trackStatistics()
4448 void trackStatistics() const override {
4449 if (IsAssumedSideEffectFree)
4451 else
4452 STATS_DECLTRACK_CSRET_ATTR(UnusedResult)
4453 }
4454
4455 /// See AbstractAttribute::getAsStr().
4456 const std::string getAsStr(Attributor *A) const override {
4457 return isAssumedDead()
4458 ? "assumed-dead"
4459 : (getAssumed() ? "assumed-dead-users" : "assumed-live");
4460 }
4461
4462private:
4463 bool IsAssumedSideEffectFree = true;
4464};
4465
4466struct AAIsDeadReturned : public AAIsDeadValueImpl {
4467 AAIsDeadReturned(const IRPosition &IRP, Attributor &A)
4468 : AAIsDeadValueImpl(IRP, A) {}
4469
4470 /// See AbstractAttribute::updateImpl(...).
4471 ChangeStatus updateImpl(Attributor &A) override {
4472
4473 bool UsedAssumedInformation = false;
4474 A.checkForAllInstructions([](Instruction &) { return true; }, *this,
4475 {Instruction::Ret}, UsedAssumedInformation);
4476
4477 auto PredForCallSite = [&](AbstractCallSite ACS) {
4478 if (ACS.isCallbackCall() || !ACS.getInstruction())
4479 return false;
4480 return areAllUsesAssumedDead(A, *ACS.getInstruction());
4481 };
4482
4483 if (!A.checkForAllCallSites(PredForCallSite, *this, true,
4484 UsedAssumedInformation))
4485 return indicatePessimisticFixpoint();
4486
4487 return ChangeStatus::UNCHANGED;
4488 }
4489
4490 /// See AbstractAttribute::manifest(...).
4491 ChangeStatus manifest(Attributor &A) override {
4492 // TODO: Rewrite the signature to return void?
4493 bool AnyChange = false;
4494 UndefValue &UV = *UndefValue::get(getAssociatedFunction()->getReturnType());
4495 auto RetInstPred = [&](Instruction &I) {
4496 ReturnInst &RI = cast<ReturnInst>(I);
4498 AnyChange |= A.changeUseAfterManifest(RI.getOperandUse(0), UV);
4499 return true;
4500 };
4501 bool UsedAssumedInformation = false;
4502 A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret},
4503 UsedAssumedInformation);
4504 return AnyChange ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
4505 }
4506
4507 /// See AbstractAttribute::trackStatistics()
4508 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(IsDead) }
4509};
4510
4511struct AAIsDeadFunction : public AAIsDead {
4512 AAIsDeadFunction(const IRPosition &IRP, Attributor &A) : AAIsDead(IRP, A) {}
4513
4514 /// See AbstractAttribute::initialize(...).
4515 void initialize(Attributor &A) override {
4516 Function *F = getAnchorScope();
4517 assert(F && "Did expect an anchor function");
4518 if (!isAssumedDeadInternalFunction(A)) {
4519 ToBeExploredFrom.insert(&F->getEntryBlock().front());
4520 assumeLive(A, F->getEntryBlock());
4521 }
4522 }
4523
4524 bool isAssumedDeadInternalFunction(Attributor &A) {
4525 if (!getAnchorScope()->hasLocalLinkage())
4526 return false;
4527 bool UsedAssumedInformation = false;
4528 return A.checkForAllCallSites([](AbstractCallSite) { return false; }, *this,
4529 true, UsedAssumedInformation);
4530 }
4531
4532 /// See AbstractAttribute::getAsStr().
4533 const std::string getAsStr(Attributor *A) const override {
4534 return "Live[#BB " + std::to_string(AssumedLiveBlocks.size()) + "/" +
4535 std::to_string(getAnchorScope()->size()) + "][#TBEP " +
4536 std::to_string(ToBeExploredFrom.size()) + "][#KDE " +
4537 std::to_string(KnownDeadEnds.size()) + "]";
4538 }
4539
4540 /// See AbstractAttribute::manifest(...).
4541 ChangeStatus manifest(Attributor &A) override {
4542 assert(getState().isValidState() &&
4543 "Attempted to manifest an invalid state!");
4544
4545 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
4546 Function &F = *getAnchorScope();
4547
4548 if (AssumedLiveBlocks.empty()) {
4549 A.deleteAfterManifest(F);
4550 return ChangeStatus::CHANGED;
4551 }
4552
4553 // Flag to determine if we can change an invoke to a call assuming the
4554 // callee is nounwind. This is not possible if the personality of the
4555 // function allows to catch asynchronous exceptions.
4556 bool Invoke2CallAllowed = !mayCatchAsynchronousExceptions(F);
4557
4558 KnownDeadEnds.set_union(ToBeExploredFrom);
4559 for (const Instruction *DeadEndI : KnownDeadEnds) {
4560 auto *CB = dyn_cast<CallBase>(DeadEndI);
4561 if (!CB)
4562 continue;
4563 bool IsKnownNoReturn;
4565 A, this, IRPosition::callsite_function(*CB), DepClassTy::OPTIONAL,
4566 IsKnownNoReturn);
4567 if (MayReturn && (!Invoke2CallAllowed || !isa<InvokeInst>(CB)))
4568 continue;
4569
4570 if (auto *II = dyn_cast<InvokeInst>(DeadEndI))
4571 A.registerInvokeWithDeadSuccessor(const_cast<InvokeInst &>(*II));
4572 else
4573 A.changeToUnreachableAfterManifest(
4574 const_cast<Instruction *>(DeadEndI->getNextNode()));
4575 HasChanged = ChangeStatus::CHANGED;
4576 }
4577
4578 STATS_DECL(AAIsDead, BasicBlock, "Number of dead basic blocks deleted.");
4579 for (BasicBlock &BB : F)
4580 if (!AssumedLiveBlocks.count(&BB)) {
4581 A.deleteAfterManifest(BB);
4582 ++BUILD_STAT_NAME(AAIsDead, BasicBlock);
4583 HasChanged = ChangeStatus::CHANGED;
4584 }
4585
4586 return HasChanged;
4587 }
4588
4589 /// See AbstractAttribute::updateImpl(...).
4590 ChangeStatus updateImpl(Attributor &A) override;
4591
4592 bool isEdgeDead(const BasicBlock *From, const BasicBlock *To) const override {
4593 assert(From->getParent() == getAnchorScope() &&
4594 To->getParent() == getAnchorScope() &&
4595 "Used AAIsDead of the wrong function");
4596 return isValidState() && !AssumedLiveEdges.count(std::make_pair(From, To));
4597 }
4598
4599 /// See AbstractAttribute::trackStatistics()
4600 void trackStatistics() const override {}
4601
4602 /// Returns true if the function is assumed dead.
4603 bool isAssumedDead() const override { return false; }
4604
4605 /// See AAIsDead::isKnownDead().
4606 bool isKnownDead() const override { return false; }
4607
4608 /// See AAIsDead::isAssumedDead(BasicBlock *).
4609 bool isAssumedDead(const BasicBlock *BB) const override {
4610 assert(BB->getParent() == getAnchorScope() &&
4611 "BB must be in the same anchor scope function.");
4612
4613 if (!getAssumed())
4614 return false;
4615 return !AssumedLiveBlocks.count(BB);
4616 }
4617
4618 /// See AAIsDead::isKnownDead(BasicBlock *).
4619 bool isKnownDead(const BasicBlock *BB) const override {
4620 return getKnown() && isAssumedDead(BB);
4621 }
4622
4623 /// See AAIsDead::isAssumed(Instruction *I).
4624 bool isAssumedDead(const Instruction *I) const override {
4625 assert(I->getParent()->getParent() == getAnchorScope() &&
4626 "Instruction must be in the same anchor scope function.");
4627
4628 if (!getAssumed())
4629 return false;
4630
4631 // If it is not in AssumedLiveBlocks then it for sure dead.
4632 // Otherwise, it can still be after noreturn call in a live block.
4633 if (!AssumedLiveBlocks.count(I->getParent()))
4634 return true;
4635
4636 // If it is not after a liveness barrier it is live.
4637 const Instruction *PrevI = I->getPrevNode();
4638 while (PrevI) {
4639 if (KnownDeadEnds.count(PrevI) || ToBeExploredFrom.count(PrevI))
4640 return true;
4641 PrevI = PrevI->getPrevNode();
4642 }
4643 return false;
4644 }
4645
4646 /// See AAIsDead::isKnownDead(Instruction *I).
4647 bool isKnownDead(const Instruction *I) const override {
4648 return getKnown() && isAssumedDead(I);
4649 }
4650
4651 /// Assume \p BB is (partially) live now and indicate to the Attributor \p A
4652 /// that internal function called from \p BB should now be looked at.
4653 bool assumeLive(Attributor &A, const BasicBlock &BB) {
4654 if (!AssumedLiveBlocks.insert(&BB).second)
4655 return false;
4656
4657 // We assume that all of BB is (probably) live now and if there are calls to
4658 // internal functions we will assume that those are now live as well. This
4659 // is a performance optimization for blocks with calls to a lot of internal
4660 // functions. It can however cause dead functions to be treated as live.
4661 for (const Instruction &I : BB)
4662 if (const auto *CB = dyn_cast<CallBase>(&I))
4664 if (F->hasLocalLinkage())
4665 A.markLiveInternalFunction(*F);
4666 return true;
4667 }
4668
4669 /// Collection of instructions that need to be explored again, e.g., we
4670 /// did assume they do not transfer control to (one of their) successors.
4671 SmallSetVector<const Instruction *, 8> ToBeExploredFrom;
4672
4673 /// Collection of instructions that are known to not transfer control.
4674 SmallSetVector<const Instruction *, 8> KnownDeadEnds;
4675
4676 /// Collection of all assumed live edges
4677 DenseSet<std::pair<const BasicBlock *, const BasicBlock *>> AssumedLiveEdges;
4678
4679 /// Collection of all assumed live BasicBlocks.
4680 DenseSet<const BasicBlock *> AssumedLiveBlocks;
4681};
4682
4683static bool
4684identifyAliveSuccessors(Attributor &A, const CallBase &CB,
4685 AbstractAttribute &AA,
4686 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4687 const IRPosition &IPos = IRPosition::callsite_function(CB);
4688
4689 bool IsKnownNoReturn;
4691 A, &AA, IPos, DepClassTy::OPTIONAL, IsKnownNoReturn))
4692 return !IsKnownNoReturn;
4693 if (CB.isTerminator())
4694 AliveSuccessors.push_back(&CB.getSuccessor(0)->front());
4695 else
4696 AliveSuccessors.push_back(CB.getNextNode());
4697 return false;
4698}
4699
4700static bool
4701identifyAliveSuccessors(Attributor &A, const InvokeInst &II,
4702 AbstractAttribute &AA,
4703 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4704 bool UsedAssumedInformation =
4705 identifyAliveSuccessors(A, cast<CallBase>(II), AA, AliveSuccessors);
4706
4707 // First, determine if we can change an invoke to a call assuming the
4708 // callee is nounwind. This is not possible if the personality of the
4709 // function allows to catch asynchronous exceptions.
4710 if (AAIsDeadFunction::mayCatchAsynchronousExceptions(*II.getFunction())) {
4711 AliveSuccessors.push_back(&II.getUnwindDest()->front());
4712 } else {
4713 const IRPosition &IPos = IRPosition::callsite_function(II);
4714
4715 bool IsKnownNoUnwind;
4717 A, &AA, IPos, DepClassTy::OPTIONAL, IsKnownNoUnwind)) {
4718 UsedAssumedInformation |= !IsKnownNoUnwind;
4719 } else {
4720 AliveSuccessors.push_back(&II.getUnwindDest()->front());
4721 }
4722 }
4723 return UsedAssumedInformation;
4724}
4725
4726static bool
4727identifyAliveSuccessors(Attributor &, const UncondBrInst &BI,
4728 AbstractAttribute &,
4729 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4730 AliveSuccessors.push_back(&BI.getSuccessor()->front());
4731 return false;
4732}
4733
4734static bool
4735identifyAliveSuccessors(Attributor &A, const CondBrInst &BI,
4736 AbstractAttribute &AA,
4737 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4738 bool UsedAssumedInformation = false;
4739 std::optional<Constant *> C =
4740 A.getAssumedConstant(*BI.getCondition(), AA, UsedAssumedInformation);
4741 if (!C || isa_and_nonnull<UndefValue>(*C)) {
4742 // No value yet, assume both edges are dead.
4743 } else if (isa_and_nonnull<ConstantInt>(*C)) {
4744 const BasicBlock *SuccBB =
4745 BI.getSuccessor(1 - cast<ConstantInt>(*C)->getValue().getZExtValue());
4746 AliveSuccessors.push_back(&SuccBB->front());
4747 } else {
4748 AliveSuccessors.push_back(&BI.getSuccessor(0)->front());
4749 AliveSuccessors.push_back(&BI.getSuccessor(1)->front());
4750 UsedAssumedInformation = false;
4751 }
4752 return UsedAssumedInformation;
4753}
4754
4755static bool
4756identifyAliveSuccessors(Attributor &A, const SwitchInst &SI,
4757 AbstractAttribute &AA,
4758 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4759 bool UsedAssumedInformation = false;
4761 if (!A.getAssumedSimplifiedValues(IRPosition::value(*SI.getCondition()), &AA,
4762 Values, AA::AnyScope,
4763 UsedAssumedInformation)) {
4764 // Something went wrong, assume all successors are live.
4765 for (const BasicBlock *SuccBB : successors(SI.getParent()))
4766 AliveSuccessors.push_back(&SuccBB->front());
4767 return false;
4768 }
4769
4770 if (Values.empty() ||
4771 (Values.size() == 1 &&
4772 isa_and_nonnull<UndefValue>(Values.front().getValue()))) {
4773 // No valid value yet, assume all edges are dead.
4774 return UsedAssumedInformation;
4775 }
4776
4777 Type &Ty = *SI.getCondition()->getType();
4778 SmallPtrSet<ConstantInt *, 8> Constants;
4779 auto CheckForConstantInt = [&](Value *V) {
4780 if (auto *CI = dyn_cast_if_present<ConstantInt>(AA::getWithType(*V, Ty))) {
4781 Constants.insert(CI);
4782 return true;
4783 }
4784 return false;
4785 };
4786
4787 if (!all_of(Values, [&](AA::ValueAndContext &VAC) {
4788 return CheckForConstantInt(VAC.getValue());
4789 })) {
4790 for (const BasicBlock *SuccBB : successors(SI.getParent()))
4791 AliveSuccessors.push_back(&SuccBB->front());
4792 return UsedAssumedInformation;
4793 }
4794
4795 unsigned MatchedCases = 0;
4796 for (const auto &CaseIt : SI.cases()) {
4797 if (Constants.count(CaseIt.getCaseValue())) {
4798 ++MatchedCases;
4799 AliveSuccessors.push_back(&CaseIt.getCaseSuccessor()->front());
4800 }
4801 }
4802
4803 // If all potential values have been matched, we will not visit the default
4804 // case.
4805 if (MatchedCases < Constants.size())
4806 AliveSuccessors.push_back(&SI.getDefaultDest()->front());
4807 return UsedAssumedInformation;
4808}
4809
4810ChangeStatus AAIsDeadFunction::updateImpl(Attributor &A) {
4812
4813 if (AssumedLiveBlocks.empty()) {
4814 if (isAssumedDeadInternalFunction(A))
4816
4817 Function *F = getAnchorScope();
4818 ToBeExploredFrom.insert(&F->getEntryBlock().front());
4819 assumeLive(A, F->getEntryBlock());
4820 Change = ChangeStatus::CHANGED;
4821 }
4822
4823 LLVM_DEBUG(dbgs() << "[AAIsDead] Live [" << AssumedLiveBlocks.size() << "/"
4824 << getAnchorScope()->size() << "] BBs and "
4825 << ToBeExploredFrom.size() << " exploration points and "
4826 << KnownDeadEnds.size() << " known dead ends\n");
4827
4828 // Copy and clear the list of instructions we need to explore from. It is
4829 // refilled with instructions the next update has to look at.
4830 SmallVector<const Instruction *, 8> Worklist(ToBeExploredFrom.begin(),
4831 ToBeExploredFrom.end());
4832 decltype(ToBeExploredFrom) NewToBeExploredFrom;
4833
4835 while (!Worklist.empty()) {
4836 const Instruction *I = Worklist.pop_back_val();
4837 LLVM_DEBUG(dbgs() << "[AAIsDead] Exploration inst: " << *I << "\n");
4838
4839 // Fast forward for uninteresting instructions. We could look for UB here
4840 // though.
4841 while (!I->isTerminator() && !isa<CallBase>(I))
4842 I = I->getNextNode();
4843
4844 AliveSuccessors.clear();
4845
4846 bool UsedAssumedInformation = false;
4847 switch (I->getOpcode()) {
4848 // TODO: look for (assumed) UB to backwards propagate "deadness".
4849 default:
4850 assert(I->isTerminator() &&
4851 "Expected non-terminators to be handled already!");
4852 for (const BasicBlock *SuccBB : successors(I->getParent()))
4853 AliveSuccessors.push_back(&SuccBB->front());
4854 break;
4855 case Instruction::Call:
4856 UsedAssumedInformation = identifyAliveSuccessors(A, cast<CallInst>(*I),
4857 *this, AliveSuccessors);
4858 break;
4859 case Instruction::Invoke:
4860 UsedAssumedInformation = identifyAliveSuccessors(A, cast<InvokeInst>(*I),
4861 *this, AliveSuccessors);
4862 break;
4863 case Instruction::UncondBr:
4864 UsedAssumedInformation = identifyAliveSuccessors(
4865 A, cast<UncondBrInst>(*I), *this, AliveSuccessors);
4866 break;
4867 case Instruction::CondBr:
4868 UsedAssumedInformation = identifyAliveSuccessors(A, cast<CondBrInst>(*I),
4869 *this, AliveSuccessors);
4870 break;
4871 case Instruction::Switch:
4872 UsedAssumedInformation = identifyAliveSuccessors(A, cast<SwitchInst>(*I),
4873 *this, AliveSuccessors);
4874 break;
4875 }
4876
4877 if (UsedAssumedInformation) {
4878 NewToBeExploredFrom.insert(I);
4879 } else if (AliveSuccessors.empty() ||
4880 (I->isTerminator() &&
4881 AliveSuccessors.size() < I->getNumSuccessors())) {
4882 if (KnownDeadEnds.insert(I))
4883 Change = ChangeStatus::CHANGED;
4884 }
4885
4886 LLVM_DEBUG(dbgs() << "[AAIsDead] #AliveSuccessors: "
4887 << AliveSuccessors.size() << " UsedAssumedInformation: "
4888 << UsedAssumedInformation << "\n");
4889
4890 for (const Instruction *AliveSuccessor : AliveSuccessors) {
4891 if (!I->isTerminator()) {
4892 assert(AliveSuccessors.size() == 1 &&
4893 "Non-terminator expected to have a single successor!");
4894 Worklist.push_back(AliveSuccessor);
4895 } else {
4896 // record the assumed live edge
4897 auto Edge = std::make_pair(I->getParent(), AliveSuccessor->getParent());
4898 if (AssumedLiveEdges.insert(Edge).second)
4899 Change = ChangeStatus::CHANGED;
4900 if (assumeLive(A, *AliveSuccessor->getParent()))
4901 Worklist.push_back(AliveSuccessor);
4902 }
4903 }
4904 }
4905
4906 // Check if the content of ToBeExploredFrom changed, ignore the order.
4907 if (NewToBeExploredFrom.size() != ToBeExploredFrom.size() ||
4908 llvm::any_of(NewToBeExploredFrom, [&](const Instruction *I) {
4909 return !ToBeExploredFrom.count(I);
4910 })) {
4911 Change = ChangeStatus::CHANGED;
4912 ToBeExploredFrom = std::move(NewToBeExploredFrom);
4913 }
4914
4915 // If we know everything is live there is no need to query for liveness.
4916 // Instead, indicating a pessimistic fixpoint will cause the state to be
4917 // "invalid" and all queries to be answered conservatively without lookups.
4918 // To be in this state we have to (1) finished the exploration and (3) not
4919 // discovered any non-trivial dead end and (2) not ruled unreachable code
4920 // dead.
4921 if (ToBeExploredFrom.empty() &&
4922 getAnchorScope()->size() == AssumedLiveBlocks.size() &&
4923 llvm::all_of(KnownDeadEnds, [](const Instruction *DeadEndI) {
4924 return DeadEndI->isTerminator() && DeadEndI->getNumSuccessors() == 0;
4925 }))
4926 return indicatePessimisticFixpoint();
4927 return Change;
4928}
4929
4930/// Liveness information for a call sites.
4931struct AAIsDeadCallSite final : AAIsDeadFunction {
4932 AAIsDeadCallSite(const IRPosition &IRP, Attributor &A)
4933 : AAIsDeadFunction(IRP, A) {}
4934
4935 /// See AbstractAttribute::initialize(...).
4936 void initialize(Attributor &A) override {
4937 // TODO: Once we have call site specific value information we can provide
4938 // call site specific liveness information and then it makes
4939 // sense to specialize attributes for call sites instead of
4940 // redirecting requests to the callee.
4941 llvm_unreachable("Abstract attributes for liveness are not "
4942 "supported for call sites yet!");
4943 }
4944
4945 /// See AbstractAttribute::updateImpl(...).
4946 ChangeStatus updateImpl(Attributor &A) override {
4947 return indicatePessimisticFixpoint();
4948 }
4949
4950 /// See AbstractAttribute::trackStatistics()
4951 void trackStatistics() const override {}
4952};
4953} // namespace
4954
4955/// -------------------- Dereferenceable Argument Attribute --------------------
4956
4957namespace {
4958struct AADereferenceableImpl : AADereferenceable {
4959 AADereferenceableImpl(const IRPosition &IRP, Attributor &A)
4960 : AADereferenceable(IRP, A) {}
4961 using StateType = DerefState;
4962
4963 /// See AbstractAttribute::initialize(...).
4964 void initialize(Attributor &A) override {
4965 Value &V = *getAssociatedValue().stripPointerCasts();
4967 A.getAttrs(getIRPosition(),
4968 {Attribute::Dereferenceable, Attribute::DereferenceableOrNull},
4969 Attrs, /* IgnoreSubsumingPositions */ false);
4970 for (const Attribute &Attr : Attrs)
4971 takeKnownDerefBytesMaximum(Attr.getValueAsInt());
4972
4973 // Ensure we initialize the non-null AA (if necessary).
4974 bool IsKnownNonNull;
4976 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNonNull);
4977
4978 bool CanBeNull, CanBeFreed;
4979 takeKnownDerefBytesMaximum(V.getPointerDereferenceableBytes(
4980 A.getDataLayout(), CanBeNull, CanBeFreed));
4981
4982 if (Instruction *CtxI = getCtxI())
4983 followUsesInMBEC(*this, A, getState(), *CtxI);
4984 }
4985
4986 /// See AbstractAttribute::getState()
4987 /// {
4988 StateType &getState() override { return *this; }
4989 const StateType &getState() const override { return *this; }
4990 /// }
4991
4992 /// Helper function for collecting accessed bytes in must-be-executed-context
4993 void addAccessedBytesForUse(Attributor &A, const Use *U, const Instruction *I,
4994 DerefState &State) {
4995 const Value *UseV = U->get();
4996 if (!UseV->getType()->isPointerTy())
4997 return;
4998
4999 std::optional<MemoryLocation> Loc = MemoryLocation::getOrNone(I);
5000 if (!Loc || Loc->Ptr != UseV || !Loc->Size.isPrecise() || I->isVolatile())
5001 return;
5002
5003 int64_t Offset;
5005 Loc->Ptr, Offset, A.getDataLayout(), /*AllowNonInbounds*/ true);
5006 if (Base && Base == &getAssociatedValue())
5007 State.addAccessedBytes(Offset, Loc->Size.getValue());
5008 }
5009
5010 /// See followUsesInMBEC
5011 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
5012 AADereferenceable::StateType &State) {
5013 bool IsNonNull = false;
5014 bool TrackUse = false;
5015 int64_t DerefBytes = getKnownNonNullAndDerefBytesForUse(
5016 A, *this, getAssociatedValue(), U, I, IsNonNull, TrackUse);
5017 LLVM_DEBUG(dbgs() << "[AADereferenceable] Deref bytes: " << DerefBytes
5018 << " for instruction " << *I << "\n");
5019
5020 addAccessedBytesForUse(A, U, I, State);
5021 State.takeKnownDerefBytesMaximum(DerefBytes);
5022 return TrackUse;
5023 }
5024
5025 /// See AbstractAttribute::manifest(...).
5026 ChangeStatus manifest(Attributor &A) override {
5027 ChangeStatus Change = AADereferenceable::manifest(A);
5028 bool IsKnownNonNull;
5029 bool IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>(
5030 A, this, getIRPosition(), DepClassTy::NONE, IsKnownNonNull);
5031 if (IsAssumedNonNull &&
5032 A.hasAttr(getIRPosition(), Attribute::DereferenceableOrNull)) {
5033 A.removeAttrs(getIRPosition(), {Attribute::DereferenceableOrNull});
5034 return ChangeStatus::CHANGED;
5035 }
5036 return Change;
5037 }
5038
5039 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
5040 SmallVectorImpl<Attribute> &Attrs) const override {
5041 // TODO: Add *_globally support
5042 bool IsKnownNonNull;
5043 bool IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>(
5044 A, this, getIRPosition(), DepClassTy::NONE, IsKnownNonNull);
5045 if (IsAssumedNonNull)
5046 Attrs.emplace_back(Attribute::getWithDereferenceableBytes(
5047 Ctx, getAssumedDereferenceableBytes()));
5048 else
5049 Attrs.emplace_back(Attribute::getWithDereferenceableOrNullBytes(
5050 Ctx, getAssumedDereferenceableBytes()));
5051 }
5052
5053 /// See AbstractAttribute::getAsStr().
5054 const std::string getAsStr(Attributor *A) const override {
5055 if (!getAssumedDereferenceableBytes())
5056 return "unknown-dereferenceable";
5057 bool IsKnownNonNull;
5058 bool IsAssumedNonNull = false;
5059 if (A)
5061 *A, this, getIRPosition(), DepClassTy::NONE, IsKnownNonNull);
5062 return std::string("dereferenceable") +
5063 (IsAssumedNonNull ? "" : "_or_null") +
5064 (isAssumedGlobal() ? "_globally" : "") + "<" +
5065 std::to_string(getKnownDereferenceableBytes()) + "-" +
5066 std::to_string(getAssumedDereferenceableBytes()) + ">" +
5067 (!A ? " [non-null is unknown]" : "");
5068 }
5069};
5070
5071/// Dereferenceable attribute for a floating value.
5072struct AADereferenceableFloating : AADereferenceableImpl {
5073 AADereferenceableFloating(const IRPosition &IRP, Attributor &A)
5074 : AADereferenceableImpl(IRP, A) {}
5075
5076 /// See AbstractAttribute::updateImpl(...).
5077 ChangeStatus updateImpl(Attributor &A) override {
5078 bool Stripped;
5079 bool UsedAssumedInformation = false;
5081 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
5082 AA::AnyScope, UsedAssumedInformation)) {
5083 Values.push_back({getAssociatedValue(), getCtxI()});
5084 Stripped = false;
5085 } else {
5086 Stripped = Values.size() != 1 ||
5087 Values.front().getValue() != &getAssociatedValue();
5088 }
5089
5090 const DataLayout &DL = A.getDataLayout();
5091 DerefState T;
5092
5093 auto VisitValueCB = [&](const Value &V) -> bool {
5094 unsigned IdxWidth =
5095 DL.getIndexSizeInBits(V.getType()->getPointerAddressSpace());
5096 APInt Offset(IdxWidth, 0);
5098 A, *this, &V, DL, Offset, /* GetMinOffset */ false,
5099 /* AllowNonInbounds */ true);
5100
5101 const auto *AA = A.getAAFor<AADereferenceable>(
5102 *this, IRPosition::value(*Base), DepClassTy::REQUIRED);
5103 int64_t DerefBytes = 0;
5104 if (!AA || (!Stripped && this == AA)) {
5105 // Use IR information if we did not strip anything.
5106 // TODO: track globally.
5107 bool CanBeNull, CanBeFreed;
5108 DerefBytes =
5109 Base->getPointerDereferenceableBytes(DL, CanBeNull, CanBeFreed);
5110 T.GlobalState.indicatePessimisticFixpoint();
5111 } else {
5112 const DerefState &DS = AA->getState();
5113 DerefBytes = DS.DerefBytesState.getAssumed();
5114 T.GlobalState &= DS.GlobalState;
5115 }
5116
5117 // For now we do not try to "increase" dereferenceability due to negative
5118 // indices as we first have to come up with code to deal with loops and
5119 // for overflows of the dereferenceable bytes.
5120 int64_t OffsetSExt = Offset.getSExtValue();
5121 if (OffsetSExt < 0)
5122 OffsetSExt = 0;
5123
5124 T.takeAssumedDerefBytesMinimum(
5125 std::max(int64_t(0), DerefBytes - OffsetSExt));
5126
5127 if (this == AA) {
5128 if (!Stripped) {
5129 // If nothing was stripped IR information is all we got.
5130 T.takeKnownDerefBytesMaximum(
5131 std::max(int64_t(0), DerefBytes - OffsetSExt));
5132 T.indicatePessimisticFixpoint();
5133 } else if (OffsetSExt > 0) {
5134 // If something was stripped but there is circular reasoning we look
5135 // for the offset. If it is positive we basically decrease the
5136 // dereferenceable bytes in a circular loop now, which will simply
5137 // drive them down to the known value in a very slow way which we
5138 // can accelerate.
5139 T.indicatePessimisticFixpoint();
5140 }
5141 }
5142
5143 return T.isValidState();
5144 };
5145
5146 for (const auto &VAC : Values)
5147 if (!VisitValueCB(*VAC.getValue()))
5148 return indicatePessimisticFixpoint();
5149
5150 return clampStateAndIndicateChange(getState(), T);
5151 }
5152
5153 /// See AbstractAttribute::trackStatistics()
5154 void trackStatistics() const override {
5155 STATS_DECLTRACK_FLOATING_ATTR(dereferenceable)
5156 }
5157};
5158
5159/// Dereferenceable attribute for a return value.
5160struct AADereferenceableReturned final
5161 : AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl> {
5162 using Base =
5163 AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl>;
5164 AADereferenceableReturned(const IRPosition &IRP, Attributor &A)
5165 : Base(IRP, A) {}
5166
5167 /// See AbstractAttribute::trackStatistics()
5168 void trackStatistics() const override {
5169 STATS_DECLTRACK_FNRET_ATTR(dereferenceable)
5170 }
5171};
5172
5173/// Dereferenceable attribute for an argument
5174struct AADereferenceableArgument final
5175 : AAArgumentFromCallSiteArguments<AADereferenceable,
5176 AADereferenceableImpl> {
5177 using Base =
5178 AAArgumentFromCallSiteArguments<AADereferenceable, AADereferenceableImpl>;
5179 AADereferenceableArgument(const IRPosition &IRP, Attributor &A)
5180 : Base(IRP, A) {}
5181
5182 /// See AbstractAttribute::trackStatistics()
5183 void trackStatistics() const override {
5184 STATS_DECLTRACK_ARG_ATTR(dereferenceable)
5185 }
5186};
5187
5188/// Dereferenceable attribute for a call site argument.
5189struct AADereferenceableCallSiteArgument final : AADereferenceableFloating {
5190 AADereferenceableCallSiteArgument(const IRPosition &IRP, Attributor &A)
5191 : AADereferenceableFloating(IRP, A) {}
5192
5193 /// See AbstractAttribute::trackStatistics()
5194 void trackStatistics() const override {
5195 STATS_DECLTRACK_CSARG_ATTR(dereferenceable)
5196 }
5197};
5198
5199/// Dereferenceable attribute deduction for a call site return value.
5200struct AADereferenceableCallSiteReturned final
5201 : AACalleeToCallSite<AADereferenceable, AADereferenceableImpl> {
5202 using Base = AACalleeToCallSite<AADereferenceable, AADereferenceableImpl>;
5203 AADereferenceableCallSiteReturned(const IRPosition &IRP, Attributor &A)
5204 : Base(IRP, A) {}
5205
5206 /// See AbstractAttribute::trackStatistics()
5207 void trackStatistics() const override {
5208 STATS_DECLTRACK_CS_ATTR(dereferenceable);
5209 }
5210};
5211} // namespace
5212
5213// ------------------------ Align Argument Attribute ------------------------
5214
5215namespace {
5216
5217static unsigned getKnownAlignForUse(Attributor &A, AAAlign &QueryingAA,
5218 Value &AssociatedValue, const Use *U,
5219 const Instruction *I, bool &TrackUse) {
5220 // We need to follow common pointer manipulation uses to the accesses they
5221 // feed into.
5222 if (isa<CastInst>(I)) {
5223 // Follow all but ptr2int casts.
5224 TrackUse = !isa<PtrToIntInst>(I);
5225 return 0;
5226 }
5227 if (auto *GEP = dyn_cast<GetElementPtrInst>(I)) {
5228 if (GEP->hasAllConstantIndices())
5229 TrackUse = true;
5230 return 0;
5231 }
5232 if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(I))
5233 switch (II->getIntrinsicID()) {
5234 case Intrinsic::ptrmask: {
5235 // Is it appropriate to pull attribute in initialization?
5236 const auto *ConstVals = A.getAAFor<AAPotentialConstantValues>(
5237 QueryingAA, IRPosition::value(*II->getOperand(1)), DepClassTy::NONE);
5238 const auto *AlignAA = A.getAAFor<AAAlign>(
5239 QueryingAA, IRPosition::value(*II), DepClassTy::NONE);
5240 if (ConstVals && ConstVals->isValidState() && ConstVals->isAtFixpoint()) {
5241 unsigned ShiftValue = std::min(ConstVals->getAssumedMinTrailingZeros(),
5243 Align ConstAlign(UINT64_C(1) << ShiftValue);
5244 if (ConstAlign >= AlignAA->getKnownAlign())
5245 return Align(1).value();
5246 }
5247 if (AlignAA)
5248 return AlignAA->getKnownAlign().value();
5249 break;
5250 }
5251 case Intrinsic::amdgcn_make_buffer_rsrc: {
5252 const auto *AlignAA = A.getAAFor<AAAlign>(
5253 QueryingAA, IRPosition::value(*II), DepClassTy::NONE);
5254 if (AlignAA)
5255 return AlignAA->getKnownAlign().value();
5256 break;
5257 }
5258 default:
5259 break;
5260 }
5261
5262 MaybeAlign MA;
5263 if (const auto *CB = dyn_cast<CallBase>(I)) {
5264 if (CB->isBundleOperand(U) || CB->isCallee(U))
5265 return 0;
5266
5267 unsigned ArgNo = CB->getArgOperandNo(U);
5268 IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo);
5269 // As long as we only use known information there is no need to track
5270 // dependences here.
5271 auto *AlignAA = A.getAAFor<AAAlign>(QueryingAA, IRP, DepClassTy::NONE);
5272 if (AlignAA)
5273 MA = MaybeAlign(AlignAA->getKnownAlign());
5274 }
5275
5276 const DataLayout &DL = A.getDataLayout();
5277 const Value *UseV = U->get();
5278 if (auto *SI = dyn_cast<StoreInst>(I)) {
5279 if (SI->getPointerOperand() == UseV)
5280 MA = SI->getAlign();
5281 } else if (auto *LI = dyn_cast<LoadInst>(I)) {
5282 if (LI->getPointerOperand() == UseV)
5283 MA = LI->getAlign();
5284 } else if (auto *AI = dyn_cast<AtomicRMWInst>(I)) {
5285 if (AI->getPointerOperand() == UseV)
5286 MA = AI->getAlign();
5287 } else if (auto *AI = dyn_cast<AtomicCmpXchgInst>(I)) {
5288 if (AI->getPointerOperand() == UseV)
5289 MA = AI->getAlign();
5290 }
5291
5292 if (!MA || *MA <= QueryingAA.getKnownAlign())
5293 return 0;
5294
5295 unsigned Alignment = MA->value();
5296 int64_t Offset;
5297
5298 if (const Value *Base = GetPointerBaseWithConstantOffset(UseV, Offset, DL)) {
5299 if (Base == &AssociatedValue) {
5300 // BasePointerAddr + Offset = Alignment * Q for some integer Q.
5301 // So we can say that the maximum power of two which is a divisor of
5302 // gcd(Offset, Alignment) is an alignment.
5303
5304 uint32_t gcd = std::gcd(uint32_t(abs((int32_t)Offset)), Alignment);
5305 Alignment = llvm::bit_floor(gcd);
5306 }
5307 }
5308
5309 return Alignment;
5310}
5311
5312struct AAAlignImpl : AAAlign {
5313 AAAlignImpl(const IRPosition &IRP, Attributor &A) : AAAlign(IRP, A) {}
5314
5315 /// See AbstractAttribute::initialize(...).
5316 void initialize(Attributor &A) override {
5318 A.getAttrs(getIRPosition(), {Attribute::Alignment}, Attrs);
5319 for (const Attribute &Attr : Attrs)
5320 takeKnownMaximum(Attr.getValueAsInt());
5321
5322 Value &V = *getAssociatedValue().stripPointerCasts();
5323 takeKnownMaximum(V.getPointerAlignment(A.getDataLayout()).value());
5324
5325 if (Instruction *CtxI = getCtxI())
5326 followUsesInMBEC(*this, A, getState(), *CtxI);
5327 }
5328
5329 /// See AbstractAttribute::manifest(...).
5330 ChangeStatus manifest(Attributor &A) override {
5331 ChangeStatus InstrChanged = ChangeStatus::UNCHANGED;
5332
5333 // Check for users that allow alignment annotations.
5334 Value &AssociatedValue = getAssociatedValue();
5335 if (isa<ConstantData>(AssociatedValue))
5336 return ChangeStatus::UNCHANGED;
5337
5338 for (const Use &U : AssociatedValue.uses()) {
5339 if (auto *SI = dyn_cast<StoreInst>(U.getUser())) {
5340 if (SI->getPointerOperand() == &AssociatedValue)
5341 if (SI->getAlign() < getAssumedAlign()) {
5342 STATS_DECLTRACK(AAAlign, Store,
5343 "Number of times alignment added to a store");
5344 SI->setAlignment(getAssumedAlign());
5345 InstrChanged = ChangeStatus::CHANGED;
5346 }
5347 } else if (auto *LI = dyn_cast<LoadInst>(U.getUser())) {
5348 if (LI->getPointerOperand() == &AssociatedValue)
5349 if (LI->getAlign() < getAssumedAlign()) {
5350 LI->setAlignment(getAssumedAlign());
5351 STATS_DECLTRACK(AAAlign, Load,
5352 "Number of times alignment added to a load");
5353 InstrChanged = ChangeStatus::CHANGED;
5354 }
5355 } else if (auto *RMW = dyn_cast<AtomicRMWInst>(U.getUser())) {
5356 if (RMW->getPointerOperand() == &AssociatedValue) {
5357 if (RMW->getAlign() < getAssumedAlign()) {
5358 STATS_DECLTRACK(AAAlign, AtomicRMW,
5359 "Number of times alignment added to atomicrmw");
5360
5361 RMW->setAlignment(getAssumedAlign());
5362 InstrChanged = ChangeStatus::CHANGED;
5363 }
5364 }
5365 } else if (auto *CAS = dyn_cast<AtomicCmpXchgInst>(U.getUser())) {
5366 if (CAS->getPointerOperand() == &AssociatedValue) {
5367 if (CAS->getAlign() < getAssumedAlign()) {
5368 STATS_DECLTRACK(AAAlign, AtomicCmpXchg,
5369 "Number of times alignment added to cmpxchg");
5370 CAS->setAlignment(getAssumedAlign());
5371 InstrChanged = ChangeStatus::CHANGED;
5372 }
5373 }
5374 }
5375 }
5376
5377 ChangeStatus Changed = AAAlign::manifest(A);
5378
5379 Align InheritAlign =
5380 getAssociatedValue().getPointerAlignment(A.getDataLayout());
5381 if (InheritAlign >= getAssumedAlign())
5382 return InstrChanged;
5383 return Changed | InstrChanged;
5384 }
5385
5386 // TODO: Provide a helper to determine the implied ABI alignment and check in
5387 // the existing manifest method and a new one for AAAlignImpl that value
5388 // to avoid making the alignment explicit if it did not improve.
5389
5390 /// See AbstractAttribute::getDeducedAttributes
5391 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
5392 SmallVectorImpl<Attribute> &Attrs) const override {
5393 if (getAssumedAlign() > 1)
5394 Attrs.emplace_back(
5395 Attribute::getWithAlignment(Ctx, Align(getAssumedAlign())));
5396 }
5397
5398 /// See followUsesInMBEC
5399 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
5400 AAAlign::StateType &State) {
5401 bool TrackUse = false;
5402
5403 unsigned int KnownAlign =
5404 getKnownAlignForUse(A, *this, getAssociatedValue(), U, I, TrackUse);
5405 State.takeKnownMaximum(KnownAlign);
5406
5407 return TrackUse;
5408 }
5409
5410 /// See AbstractAttribute::getAsStr().
5411 const std::string getAsStr(Attributor *A) const override {
5412 return "align<" + std::to_string(getKnownAlign().value()) + "-" +
5413 std::to_string(getAssumedAlign().value()) + ">";
5414 }
5415};
5416
5417/// Align attribute for a floating value.
5418struct AAAlignFloating : AAAlignImpl {
5419 AAAlignFloating(const IRPosition &IRP, Attributor &A) : AAAlignImpl(IRP, A) {}
5420
5421 /// See AbstractAttribute::updateImpl(...).
5422 ChangeStatus updateImpl(Attributor &A) override {
5423 const DataLayout &DL = A.getDataLayout();
5424
5425 bool Stripped;
5426 bool UsedAssumedInformation = false;
5428 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
5429 AA::AnyScope, UsedAssumedInformation)) {
5430 Values.push_back({getAssociatedValue(), getCtxI()});
5431 Stripped = false;
5432 } else {
5433 Stripped = Values.size() != 1 ||
5434 Values.front().getValue() != &getAssociatedValue();
5435 }
5436
5437 StateType T;
5438 auto VisitValueCB = [&](Value &V) -> bool {
5440 return true;
5441 const auto *AA = A.getAAFor<AAAlign>(*this, IRPosition::value(V),
5442 DepClassTy::REQUIRED);
5443 if (!AA || (!Stripped && this == AA)) {
5444 int64_t Offset;
5445 unsigned Alignment = 1;
5446 if (const Value *Base =
5448 // TODO: Use AAAlign for the base too.
5449 Align PA = Base->getPointerAlignment(DL);
5450 // BasePointerAddr + Offset = Alignment * Q for some integer Q.
5451 // So we can say that the maximum power of two which is a divisor of
5452 // gcd(Offset, Alignment) is an alignment.
5453
5454 uint32_t gcd =
5455 std::gcd(uint32_t(abs((int32_t)Offset)), uint32_t(PA.value()));
5456 Alignment = llvm::bit_floor(gcd);
5457 } else {
5458 Alignment = V.getPointerAlignment(DL).value();
5459 }
5460 // Use only IR information if we did not strip anything.
5461 T.takeKnownMaximum(Alignment);
5462 T.indicatePessimisticFixpoint();
5463 } else {
5464 // Use abstract attribute information.
5465 const AAAlign::StateType &DS = AA->getState();
5466 T ^= DS;
5467 }
5468 return T.isValidState();
5469 };
5470
5471 for (const auto &VAC : Values) {
5472 if (!VisitValueCB(*VAC.getValue()))
5473 return indicatePessimisticFixpoint();
5474 }
5475
5476 // TODO: If we know we visited all incoming values, thus no are assumed
5477 // dead, we can take the known information from the state T.
5478 return clampStateAndIndicateChange(getState(), T);
5479 }
5480
5481 /// See AbstractAttribute::trackStatistics()
5482 void trackStatistics() const override { STATS_DECLTRACK_FLOATING_ATTR(align) }
5483};
5484
5485/// Align attribute for function return value.
5486struct AAAlignReturned final
5487 : AAReturnedFromReturnedValues<AAAlign, AAAlignImpl> {
5488 using Base = AAReturnedFromReturnedValues<AAAlign, AAAlignImpl>;
5489 AAAlignReturned(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {}
5490
5491 /// See AbstractAttribute::trackStatistics()
5492 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(aligned) }
5493};
5494
5495/// Align attribute for function argument.
5496struct AAAlignArgument final
5497 : AAArgumentFromCallSiteArguments<AAAlign, AAAlignImpl> {
5498 using Base = AAArgumentFromCallSiteArguments<AAAlign, AAAlignImpl>;
5499 AAAlignArgument(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {}
5500
5501 /// See AbstractAttribute::manifest(...).
5502 ChangeStatus manifest(Attributor &A) override {
5503 // If the associated argument is involved in a must-tail call we give up
5504 // because we would need to keep the argument alignments of caller and
5505 // callee in-sync. Just does not seem worth the trouble right now.
5506 if (A.getInfoCache().isInvolvedInMustTailCall(*getAssociatedArgument()))
5507 return ChangeStatus::UNCHANGED;
5508 return Base::manifest(A);
5509 }
5510
5511 /// See AbstractAttribute::trackStatistics()
5512 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(aligned) }
5513};
5514
5515struct AAAlignCallSiteArgument final : AAAlignFloating {
5516 AAAlignCallSiteArgument(const IRPosition &IRP, Attributor &A)
5517 : AAAlignFloating(IRP, A) {}
5518
5519 /// See AbstractAttribute::manifest(...).
5520 ChangeStatus manifest(Attributor &A) override {
5521 // If the associated argument is involved in a must-tail call we give up
5522 // because we would need to keep the argument alignments of caller and
5523 // callee in-sync. Just does not seem worth the trouble right now.
5524 if (Argument *Arg = getAssociatedArgument())
5525 if (A.getInfoCache().isInvolvedInMustTailCall(*Arg))
5526 return ChangeStatus::UNCHANGED;
5527 ChangeStatus Changed = AAAlignImpl::manifest(A);
5528 Align InheritAlign =
5529 getAssociatedValue().getPointerAlignment(A.getDataLayout());
5530 if (InheritAlign >= getAssumedAlign())
5531 Changed = ChangeStatus::UNCHANGED;
5532 return Changed;
5533 }
5534
5535 /// See AbstractAttribute::updateImpl(Attributor &A).
5536 ChangeStatus updateImpl(Attributor &A) override {
5537 ChangeStatus Changed = AAAlignFloating::updateImpl(A);
5538 if (Argument *Arg = getAssociatedArgument()) {
5539 // We only take known information from the argument
5540 // so we do not need to track a dependence.
5541 const auto *ArgAlignAA = A.getAAFor<AAAlign>(
5542 *this, IRPosition::argument(*Arg), DepClassTy::NONE);
5543 if (ArgAlignAA)
5544 takeKnownMaximum(ArgAlignAA->getKnownAlign().value());
5545 }
5546 return Changed;
5547 }
5548
5549 /// See AbstractAttribute::trackStatistics()
5550 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(aligned) }
5551};
5552
5553/// Align attribute deduction for a call site return value.
5554struct AAAlignCallSiteReturned final
5555 : AACalleeToCallSite<AAAlign, AAAlignImpl> {
5556 using Base = AACalleeToCallSite<AAAlign, AAAlignImpl>;
5557 AAAlignCallSiteReturned(const IRPosition &IRP, Attributor &A)
5558 : Base(IRP, A) {}
5559
5560 ChangeStatus updateImpl(Attributor &A) override {
5561 Instruction *I = getIRPosition().getCtxI();
5562 if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) {
5563 switch (II->getIntrinsicID()) {
5564 case Intrinsic::ptrmask: {
5565 Align Alignment;
5566 bool Valid = false;
5567
5568 const auto *ConstVals = A.getAAFor<AAPotentialConstantValues>(
5569 *this, IRPosition::value(*II->getOperand(1)), DepClassTy::REQUIRED);
5570 if (ConstVals && ConstVals->isValidState()) {
5571 unsigned ShiftValue =
5572 std::min(ConstVals->getAssumedMinTrailingZeros(),
5573 Value::MaxAlignmentExponent);
5574 Alignment = Align(UINT64_C(1) << ShiftValue);
5575 Valid = true;
5576 }
5577
5578 const auto *AlignAA =
5579 A.getAAFor<AAAlign>(*this, IRPosition::value(*(II->getOperand(0))),
5580 DepClassTy::REQUIRED);
5581 if (AlignAA) {
5582 Alignment = std::max(AlignAA->getAssumedAlign(), Alignment);
5583 Valid = true;
5584 }
5585
5586 if (Valid)
5588 this->getState(),
5589 std::min(this->getAssumedAlign(), Alignment).value());
5590 break;
5591 }
5592 // FIXME: Should introduce target specific sub-attributes and letting
5593 // getAAfor<AAAlign> lead to create sub-attribute to handle target
5594 // specific intrinsics.
5595 case Intrinsic::amdgcn_make_buffer_rsrc: {
5596 const auto *AlignAA =
5597 A.getAAFor<AAAlign>(*this, IRPosition::value(*(II->getOperand(0))),
5598 DepClassTy::REQUIRED);
5599 if (AlignAA)
5601 this->getState(), AlignAA->getAssumedAlign().value());
5602 break;
5603 }
5604 default:
5605 break;
5606 }
5607 }
5608 return Base::updateImpl(A);
5609 };
5610 /// See AbstractAttribute::trackStatistics()
5611 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(align); }
5612};
5613} // namespace
5614
5615/// ------------------ Function No-Return Attribute ----------------------------
5616namespace {
5617struct AANoReturnImpl : public AANoReturn {
5618 AANoReturnImpl(const IRPosition &IRP, Attributor &A) : AANoReturn(IRP, A) {}
5619
5620 /// See AbstractAttribute::initialize(...).
5621 void initialize(Attributor &A) override {
5622 bool IsKnown;
5624 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
5625 (void)IsKnown;
5626 }
5627
5628 /// See AbstractAttribute::getAsStr().
5629 const std::string getAsStr(Attributor *A) const override {
5630 return getAssumed() ? "noreturn" : "may-return";
5631 }
5632
5633 /// See AbstractAttribute::updateImpl(Attributor &A).
5634 ChangeStatus updateImpl(Attributor &A) override {
5635 auto CheckForNoReturn = [](Instruction &) { return false; };
5636 bool UsedAssumedInformation = false;
5637 if (!A.checkForAllInstructions(CheckForNoReturn, *this,
5638 {(unsigned)Instruction::Ret},
5639 UsedAssumedInformation))
5640 return indicatePessimisticFixpoint();
5641 return ChangeStatus::UNCHANGED;
5642 }
5643};
5644
5645struct AANoReturnFunction final : AANoReturnImpl {
5646 AANoReturnFunction(const IRPosition &IRP, Attributor &A)
5647 : AANoReturnImpl(IRP, A) {}
5648
5649 /// See AbstractAttribute::trackStatistics()
5650 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(noreturn) }
5651};
5652
5653/// NoReturn attribute deduction for a call sites.
5654struct AANoReturnCallSite final
5655 : AACalleeToCallSite<AANoReturn, AANoReturnImpl> {
5656 AANoReturnCallSite(const IRPosition &IRP, Attributor &A)
5657 : AACalleeToCallSite<AANoReturn, AANoReturnImpl>(IRP, A) {}
5658
5659 /// See AbstractAttribute::trackStatistics()
5660 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(noreturn); }
5661};
5662} // namespace
5663
5664/// ----------------------- Instance Info ---------------------------------
5665
5666namespace {
5667/// A class to hold the state of for no-capture attributes.
5668struct AAInstanceInfoImpl : public AAInstanceInfo {
5669 AAInstanceInfoImpl(const IRPosition &IRP, Attributor &A)
5670 : AAInstanceInfo(IRP, A) {}
5671
5672 /// See AbstractAttribute::initialize(...).
5673 void initialize(Attributor &A) override {
5674 Value &V = getAssociatedValue();
5675 if (auto *C = dyn_cast<Constant>(&V)) {
5676 if (C->isThreadDependent())
5677 indicatePessimisticFixpoint();
5678 else
5679 indicateOptimisticFixpoint();
5680 return;
5681 }
5682 if (auto *CB = dyn_cast<CallBase>(&V))
5683 if (CB->arg_size() == 0 && !CB->mayHaveSideEffects() &&
5684 !CB->mayReadFromMemory()) {
5685 indicateOptimisticFixpoint();
5686 return;
5687 }
5688 if (auto *I = dyn_cast<Instruction>(&V)) {
5689 const auto *CI =
5690 A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>(
5691 *I->getFunction());
5692 if (mayBeInCycle(CI, I, /* HeaderOnly */ false)) {
5693 indicatePessimisticFixpoint();
5694 return;
5695 }
5696 }
5697 }
5698
5699 /// See AbstractAttribute::updateImpl(...).
5700 ChangeStatus updateImpl(Attributor &A) override {
5701 ChangeStatus Changed = ChangeStatus::UNCHANGED;
5702
5703 Value &V = getAssociatedValue();
5704 const Function *Scope = nullptr;
5705 if (auto *I = dyn_cast<Instruction>(&V))
5706 Scope = I->getFunction();
5707 if (auto *A = dyn_cast<Argument>(&V)) {
5708 Scope = A->getParent();
5709 if (!Scope->hasLocalLinkage())
5710 return Changed;
5711 }
5712 if (!Scope)
5713 return indicateOptimisticFixpoint();
5714
5715 bool IsKnownNoRecurse;
5717 A, this, IRPosition::function(*Scope), DepClassTy::OPTIONAL,
5718 IsKnownNoRecurse))
5719 return Changed;
5720
5721 auto UsePred = [&](const Use &U, bool &Follow) {
5722 const Instruction *UserI = dyn_cast<Instruction>(U.getUser());
5723 if (!UserI || isa<GetElementPtrInst>(UserI) || isa<CastInst>(UserI) ||
5724 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) {
5725 Follow = true;
5726 return true;
5727 }
5728 if (isa<LoadInst>(UserI) || isa<CmpInst>(UserI) ||
5729 (isa<StoreInst>(UserI) &&
5730 cast<StoreInst>(UserI)->getValueOperand() != U.get()))
5731 return true;
5732 if (auto *CB = dyn_cast<CallBase>(UserI)) {
5733 // This check is not guaranteeing uniqueness but for now that we cannot
5734 // end up with two versions of \p U thinking it was one.
5736 if (!Callee || !Callee->hasLocalLinkage())
5737 return true;
5738 if (!CB->isArgOperand(&U))
5739 return false;
5740 const auto *ArgInstanceInfoAA = A.getAAFor<AAInstanceInfo>(
5742 DepClassTy::OPTIONAL);
5743 if (!ArgInstanceInfoAA ||
5744 !ArgInstanceInfoAA->isAssumedUniqueForAnalysis())
5745 return false;
5746 // If this call base might reach the scope again we might forward the
5747 // argument back here. This is very conservative.
5749 A, *CB, *Scope, *this, /* ExclusionSet */ nullptr,
5750 [Scope](const Function &Fn) { return &Fn != Scope; }))
5751 return false;
5752 return true;
5753 }
5754 return false;
5755 };
5756
5757 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) {
5758 if (auto *SI = dyn_cast<StoreInst>(OldU.getUser())) {
5759 auto *Ptr = SI->getPointerOperand()->stripPointerCasts();
5760 if ((isa<AllocaInst>(Ptr) || isNoAliasCall(Ptr)) &&
5761 AA::isDynamicallyUnique(A, *this, *Ptr))
5762 return true;
5763 }
5764 return false;
5765 };
5766
5767 if (!A.checkForAllUses(UsePred, *this, V, /* CheckBBLivenessOnly */ true,
5768 DepClassTy::OPTIONAL,
5769 /* IgnoreDroppableUses */ true, EquivalentUseCB))
5770 return indicatePessimisticFixpoint();
5771
5772 return Changed;
5773 }
5774
5775 /// See AbstractState::getAsStr().
5776 const std::string getAsStr(Attributor *A) const override {
5777 return isAssumedUniqueForAnalysis() ? "<unique [fAa]>" : "<unknown>";
5778 }
5779
5780 /// See AbstractAttribute::trackStatistics()
5781 void trackStatistics() const override {}
5782};
5783
5784/// InstanceInfo attribute for floating values.
5785struct AAInstanceInfoFloating : AAInstanceInfoImpl {
5786 AAInstanceInfoFloating(const IRPosition &IRP, Attributor &A)
5787 : AAInstanceInfoImpl(IRP, A) {}
5788};
5789
5790/// NoCapture attribute for function arguments.
5791struct AAInstanceInfoArgument final : AAInstanceInfoFloating {
5792 AAInstanceInfoArgument(const IRPosition &IRP, Attributor &A)
5793 : AAInstanceInfoFloating(IRP, A) {}
5794};
5795
5796/// InstanceInfo attribute for call site arguments.
5797struct AAInstanceInfoCallSiteArgument final : AAInstanceInfoImpl {
5798 AAInstanceInfoCallSiteArgument(const IRPosition &IRP, Attributor &A)
5799 : AAInstanceInfoImpl(IRP, A) {}
5800
5801 /// See AbstractAttribute::updateImpl(...).
5802 ChangeStatus updateImpl(Attributor &A) override {
5803 // TODO: Once we have call site specific value information we can provide
5804 // call site specific liveness information and then it makes
5805 // sense to specialize attributes for call sites arguments instead of
5806 // redirecting requests to the callee argument.
5807 Argument *Arg = getAssociatedArgument();
5808 if (!Arg)
5809 return indicatePessimisticFixpoint();
5810 const IRPosition &ArgPos = IRPosition::argument(*Arg);
5811 auto *ArgAA =
5812 A.getAAFor<AAInstanceInfo>(*this, ArgPos, DepClassTy::REQUIRED);
5813 if (!ArgAA)
5814 return indicatePessimisticFixpoint();
5815 return clampStateAndIndicateChange(getState(), ArgAA->getState());
5816 }
5817};
5818
5819/// InstanceInfo attribute for function return value.
5820struct AAInstanceInfoReturned final : AAInstanceInfoImpl {
5821 AAInstanceInfoReturned(const IRPosition &IRP, Attributor &A)
5822 : AAInstanceInfoImpl(IRP, A) {
5823 llvm_unreachable("InstanceInfo is not applicable to function returns!");
5824 }
5825
5826 /// See AbstractAttribute::initialize(...).
5827 void initialize(Attributor &A) override {
5828 llvm_unreachable("InstanceInfo is not applicable to function returns!");
5829 }
5830
5831 /// See AbstractAttribute::updateImpl(...).
5832 ChangeStatus updateImpl(Attributor &A) override {
5833 llvm_unreachable("InstanceInfo is not applicable to function returns!");
5834 }
5835};
5836
5837/// InstanceInfo attribute deduction for a call site return value.
5838struct AAInstanceInfoCallSiteReturned final : AAInstanceInfoFloating {
5839 AAInstanceInfoCallSiteReturned(const IRPosition &IRP, Attributor &A)
5840 : AAInstanceInfoFloating(IRP, A) {}
5841};
5842} // namespace
5843
5844/// ----------------------- Variable Capturing ---------------------------------
5846 Attribute::AttrKind ImpliedAttributeKind,
5847 bool IgnoreSubsumingPositions) {
5848 assert(ImpliedAttributeKind == Attribute::Captures &&
5849 "Unexpected attribute kind");
5850 Value &V = IRP.getAssociatedValue();
5851 if (!isa<Constant>(V) && !IRP.isArgumentPosition())
5852 return V.use_empty();
5853
5854 // You cannot "capture" null in the default address space.
5855 //
5856 // FIXME: This should use NullPointerIsDefined to account for the function
5857 // attribute.
5859 V.getType()->getPointerAddressSpace() == 0)) {
5860 return true;
5861 }
5862
5864 A.getAttrs(IRP, {Attribute::Captures}, Attrs,
5865 /* IgnoreSubsumingPositions */ true);
5866 for (const Attribute &Attr : Attrs)
5867 if (capturesNothing(Attr.getCaptureInfo()))
5868 return true;
5869
5871 if (Argument *Arg = IRP.getAssociatedArgument()) {
5873 A.getAttrs(IRPosition::argument(*Arg),
5874 {Attribute::Captures, Attribute::ByVal}, Attrs,
5875 /* IgnoreSubsumingPositions */ true);
5876 bool ArgNoCapture = any_of(Attrs, [](Attribute Attr) {
5877 return Attr.getKindAsEnum() == Attribute::ByVal ||
5879 });
5880 if (ArgNoCapture) {
5881 A.manifestAttrs(IRP, Attribute::getWithCaptureInfo(
5882 V.getContext(), CaptureInfo::none()));
5883 return true;
5884 }
5885 }
5886
5887 if (const Function *F = IRP.getAssociatedFunction()) {
5888 // Check what state the associated function can actually capture.
5891 if (State.isKnown(NO_CAPTURE)) {
5892 A.manifestAttrs(IRP, Attribute::getWithCaptureInfo(V.getContext(),
5894 return true;
5895 }
5896 }
5897
5898 return false;
5899}
5900
5901/// Set the NOT_CAPTURED_IN_MEM and NOT_CAPTURED_IN_RET bits in \p Known
5902/// depending on the ability of the function associated with \p IRP to capture
5903/// state in memory and through "returning/throwing", respectively.
5905 const Function &F,
5906 BitIntegerState &State) {
5907 // TODO: Once we have memory behavior attributes we should use them here.
5908
5909 // If we know we cannot communicate or write to memory, we do not care about
5910 // ptr2int anymore.
5911 bool ReadOnly = F.onlyReadsMemory();
5912 bool NoThrow = F.doesNotThrow();
5913 bool IsVoidReturn = F.getReturnType()->isVoidTy();
5914 if (ReadOnly && NoThrow && IsVoidReturn) {
5915 State.addKnownBits(NO_CAPTURE);
5916 return;
5917 }
5918
5919 // A function cannot capture state in memory if it only reads memory, it can
5920 // however return/throw state and the state might be influenced by the
5921 // pointer value, e.g., loading from a returned pointer might reveal a bit.
5922 if (ReadOnly)
5923 State.addKnownBits(NOT_CAPTURED_IN_MEM);
5924
5925 // A function cannot communicate state back if it does not through
5926 // exceptions and doesn not return values.
5927 if (NoThrow && IsVoidReturn)
5928 State.addKnownBits(NOT_CAPTURED_IN_RET);
5929
5930 // Check existing "returned" attributes.
5931 int ArgNo = IRP.getCalleeArgNo();
5932 if (!NoThrow || ArgNo < 0 ||
5933 !F.getAttributes().hasAttrSomewhere(Attribute::Returned))
5934 return;
5935
5936 for (unsigned U = 0, E = F.arg_size(); U < E; ++U)
5937 if (F.hasParamAttribute(U, Attribute::Returned)) {
5938 if (U == unsigned(ArgNo))
5939 State.removeAssumedBits(NOT_CAPTURED_IN_RET);
5940 else if (ReadOnly)
5941 State.addKnownBits(NO_CAPTURE);
5942 else
5943 State.addKnownBits(NOT_CAPTURED_IN_RET);
5944 break;
5945 }
5946}
5947
5948namespace {
5949/// A class to hold the state of for no-capture attributes.
5950struct AANoCaptureImpl : public AANoCapture {
5951 AANoCaptureImpl(const IRPosition &IRP, Attributor &A) : AANoCapture(IRP, A) {}
5952
5953 /// See AbstractAttribute::initialize(...).
5954 void initialize(Attributor &A) override {
5955 bool IsKnown;
5957 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
5958 (void)IsKnown;
5959 }
5960
5961 /// See AbstractAttribute::updateImpl(...).
5962 ChangeStatus updateImpl(Attributor &A) override;
5963
5964 /// see AbstractAttribute::isAssumedNoCaptureMaybeReturned(...).
5965 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
5966 SmallVectorImpl<Attribute> &Attrs) const override {
5967 if (!isAssumedNoCaptureMaybeReturned())
5968 return;
5969
5970 if (isArgumentPosition()) {
5971 if (isAssumedNoCapture())
5972 Attrs.emplace_back(Attribute::get(Ctx, Attribute::Captures));
5973 else if (ManifestInternal)
5974 Attrs.emplace_back(Attribute::get(Ctx, "no-capture-maybe-returned"));
5975 }
5976 }
5977
5978 /// See AbstractState::getAsStr().
5979 const std::string getAsStr(Attributor *A) const override {
5980 if (isKnownNoCapture())
5981 return "known not-captured";
5982 if (isAssumedNoCapture())
5983 return "assumed not-captured";
5984 if (isKnownNoCaptureMaybeReturned())
5985 return "known not-captured-maybe-returned";
5986 if (isAssumedNoCaptureMaybeReturned())
5987 return "assumed not-captured-maybe-returned";
5988 return "assumed-captured";
5989 }
5990
5991 /// Check the use \p U and update \p State accordingly. Return true if we
5992 /// should continue to update the state.
5993 bool checkUse(Attributor &A, AANoCapture::StateType &State, const Use &U,
5994 bool &Follow) {
5995 Instruction *UInst = cast<Instruction>(U.getUser());
5996 LLVM_DEBUG(dbgs() << "[AANoCapture] Check use: " << *U.get() << " in "
5997 << *UInst << "\n");
5998
5999 // Deal with ptr2int by following uses.
6000 if (isa<PtrToIntInst>(UInst)) {
6001 LLVM_DEBUG(dbgs() << " - ptr2int assume the worst!\n");
6002 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
6003 /* Return */ true);
6004 }
6005
6006 // For stores we already checked if we can follow them, if they make it
6007 // here we give up.
6008 if (isa<StoreInst>(UInst))
6009 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
6010 /* Return */ true);
6011
6012 // Explicitly catch return instructions.
6013 if (isa<ReturnInst>(UInst)) {
6014 if (UInst->getFunction() == getAnchorScope())
6015 return isCapturedIn(State, /* Memory */ false, /* Integer */ false,
6016 /* Return */ true);
6017 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
6018 /* Return */ true);
6019 }
6020
6021 // For now we only use special logic for call sites. However, the tracker
6022 // itself knows about a lot of other non-capturing cases already.
6023 auto *CB = dyn_cast<CallBase>(UInst);
6024 if (!CB || !CB->isArgOperand(&U))
6025 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
6026 /* Return */ true);
6027
6028 unsigned ArgNo = CB->getArgOperandNo(&U);
6029 const IRPosition &CSArgPos = IRPosition::callsite_argument(*CB, ArgNo);
6030 // If we have a abstract no-capture attribute for the argument we can use
6031 // it to justify a non-capture attribute here. This allows recursion!
6032 bool IsKnownNoCapture;
6033 const AANoCapture *ArgNoCaptureAA = nullptr;
6034 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
6035 A, this, CSArgPos, DepClassTy::REQUIRED, IsKnownNoCapture, false,
6036 &ArgNoCaptureAA);
6037 if (IsAssumedNoCapture)
6038 return isCapturedIn(State, /* Memory */ false, /* Integer */ false,
6039 /* Return */ false);
6040 if (ArgNoCaptureAA && ArgNoCaptureAA->isAssumedNoCaptureMaybeReturned()) {
6041 Follow = true;
6042 return isCapturedIn(State, /* Memory */ false, /* Integer */ false,
6043 /* Return */ false);
6044 }
6045
6046 // Lastly, we could not find a reason no-capture can be assumed so we don't.
6047 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
6048 /* Return */ true);
6049 }
6050
6051 /// Update \p State according to \p CapturedInMem, \p CapturedInInt, and
6052 /// \p CapturedInRet, then return true if we should continue updating the
6053 /// state.
6054 static bool isCapturedIn(AANoCapture::StateType &State, bool CapturedInMem,
6055 bool CapturedInInt, bool CapturedInRet) {
6056 LLVM_DEBUG(dbgs() << " - captures [Mem " << CapturedInMem << "|Int "
6057 << CapturedInInt << "|Ret " << CapturedInRet << "]\n");
6058 if (CapturedInMem)
6059 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_MEM);
6060 if (CapturedInInt)
6061 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_INT);
6062 if (CapturedInRet)
6063 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_RET);
6064 return State.isAssumed(AANoCapture::NO_CAPTURE_MAYBE_RETURNED);
6065 }
6066};
6067
6068ChangeStatus AANoCaptureImpl::updateImpl(Attributor &A) {
6069 const IRPosition &IRP = getIRPosition();
6070 Value *V = isArgumentPosition() ? IRP.getAssociatedArgument()
6071 : &IRP.getAssociatedValue();
6072 if (!V)
6073 return indicatePessimisticFixpoint();
6074
6075 const Function *F =
6076 isArgumentPosition() ? IRP.getAssociatedFunction() : IRP.getAnchorScope();
6077
6078 // TODO: Is the checkForAllUses below useful for constants?
6079 if (!F)
6080 return indicatePessimisticFixpoint();
6081
6083 const IRPosition &FnPos = IRPosition::function(*F);
6084
6085 // Readonly means we cannot capture through memory.
6086 bool IsKnown;
6087 if (AA::isAssumedReadOnly(A, FnPos, *this, IsKnown)) {
6088 T.addKnownBits(NOT_CAPTURED_IN_MEM);
6089 if (IsKnown)
6090 addKnownBits(NOT_CAPTURED_IN_MEM);
6091 }
6092
6093 // Make sure all returned values are different than the underlying value.
6094 // TODO: we could do this in a more sophisticated way inside
6095 // AAReturnedValues, e.g., track all values that escape through returns
6096 // directly somehow.
6097 auto CheckReturnedArgs = [&](bool &UsedAssumedInformation) {
6099 if (!A.getAssumedSimplifiedValues(IRPosition::returned(*F), this, Values,
6101 UsedAssumedInformation))
6102 return false;
6103 bool SeenConstant = false;
6104 for (const AA::ValueAndContext &VAC : Values) {
6105 if (isa<Constant>(VAC.getValue())) {
6106 if (SeenConstant)
6107 return false;
6108 SeenConstant = true;
6109 } else if (!isa<Argument>(VAC.getValue()) ||
6110 VAC.getValue() == getAssociatedArgument())
6111 return false;
6112 }
6113 return true;
6114 };
6115
6116 bool IsKnownNoUnwind;
6118 A, this, FnPos, DepClassTy::OPTIONAL, IsKnownNoUnwind)) {
6119 bool IsVoidTy = F->getReturnType()->isVoidTy();
6120 bool UsedAssumedInformation = false;
6121 if (IsVoidTy || CheckReturnedArgs(UsedAssumedInformation)) {
6122 T.addKnownBits(NOT_CAPTURED_IN_RET);
6123 if (T.isKnown(NOT_CAPTURED_IN_MEM))
6125 if (IsKnownNoUnwind && (IsVoidTy || !UsedAssumedInformation)) {
6126 addKnownBits(NOT_CAPTURED_IN_RET);
6127 if (isKnown(NOT_CAPTURED_IN_MEM))
6128 return indicateOptimisticFixpoint();
6129 }
6130 }
6131 }
6132
6133 auto UseCheck = [&](const Use &U, bool &Follow) -> bool {
6134 // TODO(captures): Make this more precise.
6135 UseCaptureInfo CI = DetermineUseCaptureKind(U, /*Base=*/nullptr);
6136 if (capturesNothing(CI))
6137 return true;
6138 if (CI.isPassthrough()) {
6139 Follow = true;
6140 return true;
6141 }
6142 return checkUse(A, T, U, Follow);
6143 };
6144
6145 if (!A.checkForAllUses(UseCheck, *this, *V))
6146 return indicatePessimisticFixpoint();
6147
6148 AANoCapture::StateType &S = getState();
6149 auto Assumed = S.getAssumed();
6150 S.intersectAssumedBits(T.getAssumed());
6151 if (!isAssumedNoCaptureMaybeReturned())
6152 return indicatePessimisticFixpoint();
6153 return Assumed == S.getAssumed() ? ChangeStatus::UNCHANGED
6155}
6156
6157/// NoCapture attribute for function arguments.
6158struct AANoCaptureArgument final : AANoCaptureImpl {
6159 AANoCaptureArgument(const IRPosition &IRP, Attributor &A)
6160 : AANoCaptureImpl(IRP, A) {}
6161
6162 /// See AbstractAttribute::trackStatistics()
6163 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nocapture) }
6164};
6165
6166/// NoCapture attribute for call site arguments.
6167struct AANoCaptureCallSiteArgument final : AANoCaptureImpl {
6168 AANoCaptureCallSiteArgument(const IRPosition &IRP, Attributor &A)
6169 : AANoCaptureImpl(IRP, A) {}
6170
6171 /// See AbstractAttribute::updateImpl(...).
6172 ChangeStatus updateImpl(Attributor &A) override {
6173 // TODO: Once we have call site specific value information we can provide
6174 // call site specific liveness information and then it makes
6175 // sense to specialize attributes for call sites arguments instead of
6176 // redirecting requests to the callee argument.
6177 Argument *Arg = getAssociatedArgument();
6178 if (!Arg)
6179 return indicatePessimisticFixpoint();
6180 const IRPosition &ArgPos = IRPosition::argument(*Arg);
6181 bool IsKnownNoCapture;
6182 const AANoCapture *ArgAA = nullptr;
6184 A, this, ArgPos, DepClassTy::REQUIRED, IsKnownNoCapture, false,
6185 &ArgAA))
6186 return ChangeStatus::UNCHANGED;
6187 if (!ArgAA || !ArgAA->isAssumedNoCaptureMaybeReturned())
6188 return indicatePessimisticFixpoint();
6189 return clampStateAndIndicateChange(getState(), ArgAA->getState());
6190 }
6191
6192 /// See AbstractAttribute::trackStatistics()
6193 void trackStatistics() const override {
6195 };
6196};
6197
6198/// NoCapture attribute for floating values.
6199struct AANoCaptureFloating final : AANoCaptureImpl {
6200 AANoCaptureFloating(const IRPosition &IRP, Attributor &A)
6201 : AANoCaptureImpl(IRP, A) {}
6202
6203 /// See AbstractAttribute::trackStatistics()
6204 void trackStatistics() const override {
6206 }
6207};
6208
6209/// NoCapture attribute for function return value.
6210struct AANoCaptureReturned final : AANoCaptureImpl {
6211 AANoCaptureReturned(const IRPosition &IRP, Attributor &A)
6212 : AANoCaptureImpl(IRP, A) {
6213 llvm_unreachable("NoCapture is not applicable to function returns!");
6214 }
6215
6216 /// See AbstractAttribute::initialize(...).
6217 void initialize(Attributor &A) override {
6218 llvm_unreachable("NoCapture is not applicable to function returns!");
6219 }
6220
6221 /// See AbstractAttribute::updateImpl(...).
6222 ChangeStatus updateImpl(Attributor &A) override {
6223 llvm_unreachable("NoCapture is not applicable to function returns!");
6224 }
6225
6226 /// See AbstractAttribute::trackStatistics()
6227 void trackStatistics() const override {}
6228};
6229
6230/// NoCapture attribute deduction for a call site return value.
6231struct AANoCaptureCallSiteReturned final : AANoCaptureImpl {
6232 AANoCaptureCallSiteReturned(const IRPosition &IRP, Attributor &A)
6233 : AANoCaptureImpl(IRP, A) {}
6234
6235 /// See AbstractAttribute::initialize(...).
6236 void initialize(Attributor &A) override {
6237 const Function *F = getAnchorScope();
6238 // Check what state the associated function can actually capture.
6239 determineFunctionCaptureCapabilities(getIRPosition(), *F, *this);
6240 }
6241
6242 /// See AbstractAttribute::trackStatistics()
6243 void trackStatistics() const override {
6245 }
6246};
6247} // namespace
6248
6249/// ------------------ Value Simplify Attribute ----------------------------
6250
6251bool ValueSimplifyStateType::unionAssumed(std::optional<Value *> Other) {
6252 // FIXME: Add a typecast support.
6255 if (SimplifiedAssociatedValue == std::optional<Value *>(nullptr))
6256 return false;
6257
6258 LLVM_DEBUG({
6260 dbgs() << "[ValueSimplify] is assumed to be "
6261 << **SimplifiedAssociatedValue << "\n";
6262 else
6263 dbgs() << "[ValueSimplify] is assumed to be <none>\n";
6264 });
6265 return true;
6266}
6267
6268namespace {
6269struct AAValueSimplifyImpl : AAValueSimplify {
6270 AAValueSimplifyImpl(const IRPosition &IRP, Attributor &A)
6271 : AAValueSimplify(IRP, A) {}
6272
6273 /// See AbstractAttribute::initialize(...).
6274 void initialize(Attributor &A) override {
6275 if (getAssociatedValue().getType()->isVoidTy())
6276 indicatePessimisticFixpoint();
6277 if (A.hasSimplificationCallback(getIRPosition()))
6278 indicatePessimisticFixpoint();
6279 }
6280
6281 /// See AbstractAttribute::getAsStr().
6282 const std::string getAsStr(Attributor *A) const override {
6283 LLVM_DEBUG({
6284 dbgs() << "SAV: " << (bool)SimplifiedAssociatedValue << " ";
6285 if (SimplifiedAssociatedValue && *SimplifiedAssociatedValue)
6286 dbgs() << "SAV: " << **SimplifiedAssociatedValue << " ";
6287 });
6288 return isValidState() ? (isAtFixpoint() ? "simplified" : "maybe-simple")
6289 : "not-simple";
6290 }
6291
6292 /// See AbstractAttribute::trackStatistics()
6293 void trackStatistics() const override {}
6294
6295 /// See AAValueSimplify::getAssumedSimplifiedValue()
6296 std::optional<Value *>
6297 getAssumedSimplifiedValue(Attributor &A) const override {
6298 return SimplifiedAssociatedValue;
6299 }
6300
6301 /// Ensure the return value is \p V with type \p Ty, if not possible return
6302 /// nullptr. If \p Check is true we will only verify such an operation would
6303 /// suceed and return a non-nullptr value if that is the case. No IR is
6304 /// generated or modified.
6305 static Value *ensureType(Attributor &A, Value &V, Type &Ty, Instruction *CtxI,
6306 bool Check) {
6307 if (auto *TypedV = AA::getWithType(V, Ty))
6308 return TypedV;
6309 if (CtxI && V.getType()->canLosslesslyBitCastTo(&Ty))
6310 return Check ? &V
6311 : BitCastInst::CreatePointerBitCastOrAddrSpaceCast(
6312 &V, &Ty, "", CtxI->getIterator());
6313 return nullptr;
6314 }
6315
6316 /// Reproduce \p I with type \p Ty or return nullptr if that is not posisble.
6317 /// If \p Check is true we will only verify such an operation would suceed and
6318 /// return a non-nullptr value if that is the case. No IR is generated or
6319 /// modified.
6320 static Value *reproduceInst(Attributor &A,
6321 const AbstractAttribute &QueryingAA,
6322 Instruction &I, Type &Ty, Instruction *CtxI,
6323 bool Check, ValueToValueMapTy &VMap) {
6324 assert(CtxI && "Cannot reproduce an instruction without context!");
6325 if (Check && (I.mayReadFromMemory() ||
6326 !isSafeToSpeculativelyExecute(&I, CtxI, /* DT */ nullptr,
6327 /* TLI */ nullptr)))
6328 return nullptr;
6329 for (Value *Op : I.operands()) {
6330 Value *NewOp = reproduceValue(A, QueryingAA, *Op, Ty, CtxI, Check, VMap);
6331 if (!NewOp) {
6332 assert(Check && "Manifest of new value unexpectedly failed!");
6333 return nullptr;
6334 }
6335 if (!Check)
6336 VMap[Op] = NewOp;
6337 }
6338 if (Check)
6339 return &I;
6340
6341 Instruction *CloneI = I.clone();
6342 // TODO: Try to salvage debug information here.
6343 CloneI->setDebugLoc(DebugLoc());
6344 VMap[&I] = CloneI;
6345 CloneI->insertBefore(CtxI->getIterator());
6346 RemapInstruction(CloneI, VMap);
6347 return CloneI;
6348 }
6349
6350 /// Reproduce \p V with type \p Ty or return nullptr if that is not posisble.
6351 /// If \p Check is true we will only verify such an operation would suceed and
6352 /// return a non-nullptr value if that is the case. No IR is generated or
6353 /// modified.
6354 static Value *reproduceValue(Attributor &A,
6355 const AbstractAttribute &QueryingAA, Value &V,
6356 Type &Ty, Instruction *CtxI, bool Check,
6357 ValueToValueMapTy &VMap) {
6358 if (const auto &NewV = VMap.lookup(&V))
6359 return NewV;
6360 bool UsedAssumedInformation = false;
6361 std::optional<Value *> SimpleV = A.getAssumedSimplified(
6362 V, QueryingAA, UsedAssumedInformation, AA::Interprocedural);
6363 if (!SimpleV.has_value())
6364 return PoisonValue::get(&Ty);
6365 Value *EffectiveV = &V;
6366 if (*SimpleV)
6367 EffectiveV = *SimpleV;
6368 if (auto *C = dyn_cast<Constant>(EffectiveV))
6369 return C;
6370 if (CtxI && AA::isValidAtPosition(AA::ValueAndContext(*EffectiveV, *CtxI),
6371 A.getInfoCache()))
6372 return ensureType(A, *EffectiveV, Ty, CtxI, Check);
6373 if (auto *I = dyn_cast<Instruction>(EffectiveV))
6374 if (Value *NewV = reproduceInst(A, QueryingAA, *I, Ty, CtxI, Check, VMap))
6375 return ensureType(A, *NewV, Ty, CtxI, Check);
6376 return nullptr;
6377 }
6378
6379 /// Return a value we can use as replacement for the associated one, or
6380 /// nullptr if we don't have one that makes sense.
6381 Value *manifestReplacementValue(Attributor &A, Instruction *CtxI) const {
6382 Value *NewV = SimplifiedAssociatedValue
6383 ? *SimplifiedAssociatedValue
6384 : UndefValue::get(getAssociatedType());
6385 if (NewV && NewV != &getAssociatedValue()) {
6386 ValueToValueMapTy VMap;
6387 // First verify we can reprduce the value with the required type at the
6388 // context location before we actually start modifying the IR.
6389 if (reproduceValue(A, *this, *NewV, *getAssociatedType(), CtxI,
6390 /* CheckOnly */ true, VMap))
6391 return reproduceValue(A, *this, *NewV, *getAssociatedType(), CtxI,
6392 /* CheckOnly */ false, VMap);
6393 }
6394 return nullptr;
6395 }
6396
6397 /// Helper function for querying AAValueSimplify and updating candidate.
6398 /// \param IRP The value position we are trying to unify with SimplifiedValue
6399 bool checkAndUpdate(Attributor &A, const AbstractAttribute &QueryingAA,
6400 const IRPosition &IRP, bool Simplify = true) {
6401 bool UsedAssumedInformation = false;
6402 std::optional<Value *> QueryingValueSimplified = &IRP.getAssociatedValue();
6403 if (Simplify)
6404 QueryingValueSimplified = A.getAssumedSimplified(
6405 IRP, QueryingAA, UsedAssumedInformation, AA::Interprocedural);
6406 return unionAssumed(QueryingValueSimplified);
6407 }
6408
6409 /// Returns a candidate is found or not
6410 template <typename AAType> bool askSimplifiedValueFor(Attributor &A) {
6411 if (!getAssociatedValue().getType()->isIntegerTy())
6412 return false;
6413
6414 // This will also pass the call base context.
6415 const auto *AA =
6416 A.getAAFor<AAType>(*this, getIRPosition(), DepClassTy::NONE);
6417 if (!AA)
6418 return false;
6419
6420 std::optional<Constant *> COpt = AA->getAssumedConstant(A);
6421
6422 if (!COpt) {
6423 SimplifiedAssociatedValue = std::nullopt;
6424 A.recordDependence(*AA, *this, DepClassTy::OPTIONAL);
6425 return true;
6426 }
6427 if (auto *C = *COpt) {
6428 SimplifiedAssociatedValue = C;
6429 A.recordDependence(*AA, *this, DepClassTy::OPTIONAL);
6430 return true;
6431 }
6432 return false;
6433 }
6434
6435 bool askSimplifiedValueForOtherAAs(Attributor &A) {
6436 if (askSimplifiedValueFor<AAValueConstantRange>(A))
6437 return true;
6438 if (askSimplifiedValueFor<AAPotentialConstantValues>(A))
6439 return true;
6440 return false;
6441 }
6442
6443 /// See AbstractAttribute::manifest(...).
6444 ChangeStatus manifest(Attributor &A) override {
6445 ChangeStatus Changed = ChangeStatus::UNCHANGED;
6446 for (auto &U : getAssociatedValue().uses()) {
6447 // Check if we need to adjust the insertion point to make sure the IR is
6448 // valid.
6449 Instruction *IP = dyn_cast<Instruction>(U.getUser());
6450 if (auto *PHI = dyn_cast_or_null<PHINode>(IP))
6451 IP = PHI->getIncomingBlock(U)->getTerminator();
6452 if (auto *NewV = manifestReplacementValue(A, IP)) {
6453 LLVM_DEBUG(dbgs() << "[ValueSimplify] " << getAssociatedValue()
6454 << " -> " << *NewV << " :: " << *this << "\n");
6455 if (A.changeUseAfterManifest(U, *NewV))
6456 Changed = ChangeStatus::CHANGED;
6457 }
6458 }
6459
6460 return Changed | AAValueSimplify::manifest(A);
6461 }
6462
6463 /// See AbstractState::indicatePessimisticFixpoint(...).
6464 ChangeStatus indicatePessimisticFixpoint() override {
6465 SimplifiedAssociatedValue = &getAssociatedValue();
6466 return AAValueSimplify::indicatePessimisticFixpoint();
6467 }
6468};
6469
6470struct AAValueSimplifyArgument final : AAValueSimplifyImpl {
6471 AAValueSimplifyArgument(const IRPosition &IRP, Attributor &A)
6472 : AAValueSimplifyImpl(IRP, A) {}
6473
6474 void initialize(Attributor &A) override {
6475 AAValueSimplifyImpl::initialize(A);
6476 if (A.hasAttr(getIRPosition(),
6477 {Attribute::InAlloca, Attribute::Preallocated,
6478 Attribute::StructRet, Attribute::Nest, Attribute::ByVal},
6479 /* IgnoreSubsumingPositions */ true))
6480 indicatePessimisticFixpoint();
6481 }
6482
6483 /// See AbstractAttribute::updateImpl(...).
6484 ChangeStatus updateImpl(Attributor &A) override {
6485 // Byval is only replacable if it is readonly otherwise we would write into
6486 // the replaced value and not the copy that byval creates implicitly.
6487 Argument *Arg = getAssociatedArgument();
6488 if (Arg->hasByValAttr()) {
6489 // TODO: We probably need to verify synchronization is not an issue, e.g.,
6490 // there is no race by not copying a constant byval.
6491 bool IsKnown;
6492 if (!AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown))
6493 return indicatePessimisticFixpoint();
6494 }
6495
6496 auto Before = SimplifiedAssociatedValue;
6497
6498 auto PredForCallSite = [&](AbstractCallSite ACS) {
6499 const IRPosition &ACSArgPos =
6500 IRPosition::callsite_argument(ACS, getCallSiteArgNo());
6501 // Check if a coresponding argument was found or if it is on not
6502 // associated (which can happen for callback calls).
6503 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
6504 return false;
6505
6506 // Simplify the argument operand explicitly and check if the result is
6507 // valid in the current scope. This avoids refering to simplified values
6508 // in other functions, e.g., we don't want to say a an argument in a
6509 // static function is actually an argument in a different function.
6510 bool UsedAssumedInformation = false;
6511 std::optional<Constant *> SimpleArgOp =
6512 A.getAssumedConstant(ACSArgPos, *this, UsedAssumedInformation);
6513 if (!SimpleArgOp)
6514 return true;
6515 if (!*SimpleArgOp)
6516 return false;
6517 if (!AA::isDynamicallyUnique(A, *this, **SimpleArgOp))
6518 return false;
6519 return unionAssumed(*SimpleArgOp);
6520 };
6521
6522 // Generate a answer specific to a call site context.
6523 bool Success;
6524 bool UsedAssumedInformation = false;
6525 if (hasCallBaseContext() &&
6526 getCallBaseContext()->getCalledOperand() == Arg->getParent())
6527 Success = PredForCallSite(
6528 AbstractCallSite(&getCallBaseContext()->getCalledOperandUse()));
6529 else
6530 Success = A.checkForAllCallSites(PredForCallSite, *this, true,
6531 UsedAssumedInformation);
6532
6533 if (!Success)
6534 if (!askSimplifiedValueForOtherAAs(A))
6535 return indicatePessimisticFixpoint();
6536
6537 // If a candidate was found in this update, return CHANGED.
6538 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED
6539 : ChangeStatus ::CHANGED;
6540 }
6541
6542 /// See AbstractAttribute::trackStatistics()
6543 void trackStatistics() const override {
6544 STATS_DECLTRACK_ARG_ATTR(value_simplify)
6545 }
6546};
6547
6548struct AAValueSimplifyReturned : AAValueSimplifyImpl {
6549 AAValueSimplifyReturned(const IRPosition &IRP, Attributor &A)
6550 : AAValueSimplifyImpl(IRP, A) {}
6551
6552 /// See AAValueSimplify::getAssumedSimplifiedValue()
6553 std::optional<Value *>
6554 getAssumedSimplifiedValue(Attributor &A) const override {
6555 if (!isValidState())
6556 return nullptr;
6557 return SimplifiedAssociatedValue;
6558 }
6559
6560 /// See AbstractAttribute::updateImpl(...).
6561 ChangeStatus updateImpl(Attributor &A) override {
6562 auto Before = SimplifiedAssociatedValue;
6563
6564 auto ReturnInstCB = [&](Instruction &I) {
6565 auto &RI = cast<ReturnInst>(I);
6566 return checkAndUpdate(
6567 A, *this,
6568 IRPosition::value(*RI.getReturnValue(), getCallBaseContext()));
6569 };
6570
6571 bool UsedAssumedInformation = false;
6572 if (!A.checkForAllInstructions(ReturnInstCB, *this, {Instruction::Ret},
6573 UsedAssumedInformation))
6574 if (!askSimplifiedValueForOtherAAs(A))
6575 return indicatePessimisticFixpoint();
6576
6577 // If a candidate was found in this update, return CHANGED.
6578 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED
6579 : ChangeStatus ::CHANGED;
6580 }
6581
6582 ChangeStatus manifest(Attributor &A) override {
6583 // We queried AAValueSimplify for the returned values so they will be
6584 // replaced if a simplified form was found. Nothing to do here.
6585 return ChangeStatus::UNCHANGED;
6586 }
6587
6588 /// See AbstractAttribute::trackStatistics()
6589 void trackStatistics() const override {
6590 STATS_DECLTRACK_FNRET_ATTR(value_simplify)
6591 }
6592};
6593
6594struct AAValueSimplifyFloating : AAValueSimplifyImpl {
6595 AAValueSimplifyFloating(const IRPosition &IRP, Attributor &A)
6596 : AAValueSimplifyImpl(IRP, A) {}
6597
6598 /// See AbstractAttribute::initialize(...).
6599 void initialize(Attributor &A) override {
6600 AAValueSimplifyImpl::initialize(A);
6601 Value &V = getAnchorValue();
6602
6603 // TODO: add other stuffs
6604 if (isa<Constant>(V))
6605 indicatePessimisticFixpoint();
6606 }
6607
6608 /// See AbstractAttribute::updateImpl(...).
6609 ChangeStatus updateImpl(Attributor &A) override {
6610 auto Before = SimplifiedAssociatedValue;
6611 if (!askSimplifiedValueForOtherAAs(A))
6612 return indicatePessimisticFixpoint();
6613
6614 // If a candidate was found in this update, return CHANGED.
6615 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED
6616 : ChangeStatus ::CHANGED;
6617 }
6618
6619 /// See AbstractAttribute::trackStatistics()
6620 void trackStatistics() const override {
6621 STATS_DECLTRACK_FLOATING_ATTR(value_simplify)
6622 }
6623};
6624
6625struct AAValueSimplifyFunction : AAValueSimplifyImpl {
6626 AAValueSimplifyFunction(const IRPosition &IRP, Attributor &A)
6627 : AAValueSimplifyImpl(IRP, A) {}
6628
6629 /// See AbstractAttribute::initialize(...).
6630 void initialize(Attributor &A) override {
6631 SimplifiedAssociatedValue = nullptr;
6632 indicateOptimisticFixpoint();
6633 }
6634 /// See AbstractAttribute::initialize(...).
6635 ChangeStatus updateImpl(Attributor &A) override {
6637 "AAValueSimplify(Function|CallSite)::updateImpl will not be called");
6638 }
6639 /// See AbstractAttribute::trackStatistics()
6640 void trackStatistics() const override {
6641 STATS_DECLTRACK_FN_ATTR(value_simplify)
6642 }
6643};
6644
6645struct AAValueSimplifyCallSite : AAValueSimplifyFunction {
6646 AAValueSimplifyCallSite(const IRPosition &IRP, Attributor &A)
6647 : AAValueSimplifyFunction(IRP, A) {}
6648 /// See AbstractAttribute::trackStatistics()
6649 void trackStatistics() const override {
6650 STATS_DECLTRACK_CS_ATTR(value_simplify)
6651 }
6652};
6653
6654struct AAValueSimplifyCallSiteReturned : AAValueSimplifyImpl {
6655 AAValueSimplifyCallSiteReturned(const IRPosition &IRP, Attributor &A)
6656 : AAValueSimplifyImpl(IRP, A) {}
6657
6658 void initialize(Attributor &A) override {
6659 AAValueSimplifyImpl::initialize(A);
6660 Function *Fn = getAssociatedFunction();
6661 assert(Fn && "Did expect an associted function");
6662 for (Argument &Arg : Fn->args()) {
6663 if (Arg.hasReturnedAttr()) {
6664 auto IRP = IRPosition::callsite_argument(*cast<CallBase>(getCtxI()),
6665 Arg.getArgNo());
6667 checkAndUpdate(A, *this, IRP))
6668 indicateOptimisticFixpoint();
6669 else
6670 indicatePessimisticFixpoint();
6671 return;
6672 }
6673 }
6674 }
6675
6676 /// See AbstractAttribute::updateImpl(...).
6677 ChangeStatus updateImpl(Attributor &A) override {
6678 return indicatePessimisticFixpoint();
6679 }
6680
6681 void trackStatistics() const override {
6682 STATS_DECLTRACK_CSRET_ATTR(value_simplify)
6683 }
6684};
6685
6686struct AAValueSimplifyCallSiteArgument : AAValueSimplifyFloating {
6687 AAValueSimplifyCallSiteArgument(const IRPosition &IRP, Attributor &A)
6688 : AAValueSimplifyFloating(IRP, A) {}
6689
6690 /// See AbstractAttribute::manifest(...).
6691 ChangeStatus manifest(Attributor &A) override {
6692 ChangeStatus Changed = ChangeStatus::UNCHANGED;
6693 // TODO: We should avoid simplification duplication to begin with.
6694 auto *FloatAA = A.lookupAAFor<AAValueSimplify>(
6695 IRPosition::value(getAssociatedValue()), this, DepClassTy::NONE);
6696 if (FloatAA && FloatAA->getState().isValidState())
6697 return Changed;
6698
6699 if (auto *NewV = manifestReplacementValue(A, getCtxI())) {
6700 Use &U = cast<CallBase>(&getAnchorValue())
6701 ->getArgOperandUse(getCallSiteArgNo());
6702 if (A.changeUseAfterManifest(U, *NewV))
6703 Changed = ChangeStatus::CHANGED;
6704 }
6705
6706 return Changed | AAValueSimplify::manifest(A);
6707 }
6708
6709 void trackStatistics() const override {
6710 STATS_DECLTRACK_CSARG_ATTR(value_simplify)
6711 }
6712};
6713} // namespace
6714
6715/// ----------------------- Heap-To-Stack Conversion ---------------------------
6716namespace {
6717struct AAHeapToStackFunction final : public AAHeapToStack {
6718
6719 static bool isGlobalizedLocal(const CallBase &CB) {
6720 Attribute A = CB.getFnAttr("alloc-family");
6721 return A.isValid() && A.getValueAsString() == "__kmpc_alloc_shared";
6722 }
6723
6724 struct AllocationInfo {
6725 /// The call that allocates the memory.
6726 CallBase *const CB;
6727
6728 /// Whether this allocation is an OpenMP globalized local variable.
6729 bool IsGlobalizedLocal = false;
6730
6731 /// The status wrt. a rewrite.
6732 enum {
6733 STACK_DUE_TO_USE,
6734 STACK_DUE_TO_FREE,
6735 INVALID,
6736 } Status = STACK_DUE_TO_USE;
6737
6738 /// Flag to indicate if we encountered a use that might free this allocation
6739 /// but which is not in the deallocation infos.
6740 bool HasPotentiallyFreeingUnknownUses = false;
6741
6742 /// Flag to indicate that we should place the new alloca in the function
6743 /// entry block rather than where the call site (CB) is.
6744 bool MoveAllocaIntoEntry = true;
6745
6746 /// The set of free calls that use this allocation.
6747 SmallSetVector<CallBase *, 1> PotentialFreeCalls{};
6748 };
6749
6750 struct DeallocationInfo {
6751 /// The call that deallocates the memory.
6752 CallBase *const CB;
6753 /// The value freed by the call.
6754 Value *FreedOp;
6755
6756 /// Flag to indicate if we don't know all objects this deallocation might
6757 /// free.
6758 bool MightFreeUnknownObjects = false;
6759
6760 /// The set of allocation calls that are potentially freed.
6761 SmallSetVector<CallBase *, 1> PotentialAllocationCalls{};
6762 };
6763
6764 AAHeapToStackFunction(const IRPosition &IRP, Attributor &A)
6765 : AAHeapToStack(IRP, A) {}
6766
6767 ~AAHeapToStackFunction() override {
6768 // Ensure we call the destructor so we release any memory allocated in the
6769 // sets.
6770 for (auto &It : AllocationInfos)
6771 It.second->~AllocationInfo();
6772 for (auto &It : DeallocationInfos)
6773 It.second->~DeallocationInfo();
6774 }
6775
6776 void initialize(Attributor &A) override {
6777 AAHeapToStack::initialize(A);
6778
6779 const Function *F = getAnchorScope();
6780 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
6781
6782 auto AllocationIdentifierCB = [&](Instruction &I) {
6783 CallBase *CB = dyn_cast<CallBase>(&I);
6784 if (!CB)
6785 return true;
6786 if (Value *FreedOp = getFreedOperand(CB, TLI)) {
6787 DeallocationInfos[CB] = new (A.Allocator) DeallocationInfo{CB, FreedOp};
6788 return true;
6789 }
6790 // To do heap to stack, we need to know that the allocation itself is
6791 // removable once uses are rewritten, and that we can initialize the
6792 // alloca to the same pattern as the original allocation result.
6793 if (isRemovableAlloc(CB, TLI)) {
6794 auto *I8Ty = Type::getInt8Ty(CB->getParent()->getContext());
6795 if (nullptr != getInitialValueOfAllocation(CB, TLI, I8Ty)) {
6796 AllocationInfo *AI = new (A.Allocator) AllocationInfo{CB};
6797 AllocationInfos[CB] = AI;
6798 AI->IsGlobalizedLocal = isGlobalizedLocal(*CB);
6799 }
6800 }
6801 return true;
6802 };
6803
6804 bool UsedAssumedInformation = false;
6805 bool Success = A.checkForAllCallLikeInstructions(
6806 AllocationIdentifierCB, *this, UsedAssumedInformation,
6807 /* CheckBBLivenessOnly */ false,
6808 /* CheckPotentiallyDead */ true);
6809 (void)Success;
6810 assert(Success && "Did not expect the call base visit callback to fail!");
6811
6813 [](const IRPosition &, const AbstractAttribute *,
6814 bool &) -> std::optional<Value *> { return nullptr; };
6815 for (const auto &It : AllocationInfos)
6816 A.registerSimplificationCallback(IRPosition::callsite_returned(*It.first),
6817 SCB);
6818 for (const auto &It : DeallocationInfos)
6819 A.registerSimplificationCallback(IRPosition::callsite_returned(*It.first),
6820 SCB);
6821 }
6822
6823 const std::string getAsStr(Attributor *A) const override {
6824 unsigned NumH2SMallocs = 0, NumInvalidMallocs = 0;
6825 for (const auto &It : AllocationInfos) {
6826 if (It.second->Status == AllocationInfo::INVALID)
6827 ++NumInvalidMallocs;
6828 else
6829 ++NumH2SMallocs;
6830 }
6831 return "[H2S] Mallocs Good/Bad: " + std::to_string(NumH2SMallocs) + "/" +
6832 std::to_string(NumInvalidMallocs);
6833 }
6834
6835 /// See AbstractAttribute::trackStatistics().
6836 void trackStatistics() const override {
6837 STATS_DECL(
6838 MallocCalls, Function,
6839 "Number of malloc/calloc/aligned_alloc calls converted to allocas");
6840 for (const auto &It : AllocationInfos)
6841 if (It.second->Status != AllocationInfo::INVALID)
6842 ++BUILD_STAT_NAME(MallocCalls, Function);
6843 }
6844
6845 bool isAssumedHeapToStack(const CallBase &CB) const override {
6846 if (isValidState())
6847 if (AllocationInfo *AI =
6848 AllocationInfos.lookup(const_cast<CallBase *>(&CB)))
6849 return AI->Status != AllocationInfo::INVALID;
6850 return false;
6851 }
6852
6853 bool isAssumedHeapToStackRemovedFree(CallBase &CB) const override {
6854 if (!isValidState())
6855 return false;
6856
6857 for (const auto &It : AllocationInfos) {
6858 AllocationInfo &AI = *It.second;
6859 if (AI.Status == AllocationInfo::INVALID)
6860 continue;
6861
6862 if (AI.PotentialFreeCalls.count(&CB))
6863 return true;
6864 }
6865
6866 return false;
6867 }
6868
6869 ChangeStatus manifest(Attributor &A) override {
6870 assert(getState().isValidState() &&
6871 "Attempted to manifest an invalid state!");
6872
6873 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
6874 Function *F = getAnchorScope();
6875 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
6876
6877 for (auto &It : AllocationInfos) {
6878 AllocationInfo &AI = *It.second;
6879 if (AI.Status == AllocationInfo::INVALID)
6880 continue;
6881
6882 for (CallBase *FreeCall : AI.PotentialFreeCalls) {
6883 LLVM_DEBUG(dbgs() << "H2S: Removing free call: " << *FreeCall << "\n");
6884 A.deleteAfterManifest(*FreeCall);
6885 HasChanged = ChangeStatus::CHANGED;
6886 }
6887
6888 LLVM_DEBUG(dbgs() << "H2S: Removing malloc-like call: " << *AI.CB
6889 << "\n");
6890
6891 auto Remark = [&](OptimizationRemark OR) {
6892 if (AI.IsGlobalizedLocal)
6893 return OR << "Moving globalized variable to the stack.";
6894 return OR << "Moving memory allocation from the heap to the stack.";
6895 };
6896 if (AI.IsGlobalizedLocal)
6897 A.emitRemark<OptimizationRemark>(AI.CB, "OMP110", Remark);
6898 else
6899 A.emitRemark<OptimizationRemark>(AI.CB, "HeapToStack", Remark);
6900
6901 const DataLayout &DL = A.getInfoCache().getDL();
6902 Value *Size;
6903 std::optional<APInt> SizeAPI = getSize(A, *this, AI);
6904 if (SizeAPI) {
6905 Size = ConstantInt::get(AI.CB->getContext(), *SizeAPI);
6906 } else {
6907 LLVMContext &Ctx = AI.CB->getContext();
6908 ObjectSizeOpts Opts;
6909 ObjectSizeOffsetEvaluator Eval(DL, TLI, Ctx, Opts);
6910 SizeOffsetValue SizeOffsetPair = Eval.compute(AI.CB);
6911 assert(SizeOffsetPair != ObjectSizeOffsetEvaluator::unknown() &&
6912 cast<ConstantInt>(SizeOffsetPair.Offset)->isZero());
6913 Size = SizeOffsetPair.Size;
6914 }
6915
6916 BasicBlock::iterator IP = AI.MoveAllocaIntoEntry
6917 ? F->getEntryBlock().begin()
6918 : AI.CB->getIterator();
6919
6920 Align Alignment(1);
6921 if (MaybeAlign RetAlign = AI.CB->getRetAlign())
6922 Alignment = std::max(Alignment, *RetAlign);
6923 if (Value *Align = getAllocAlignment(AI.CB, TLI)) {
6924 std::optional<APInt> AlignmentAPI = getAPInt(A, *this, *Align);
6925 assert(AlignmentAPI && AlignmentAPI->getZExtValue() > 0 &&
6926 "Expected an alignment during manifest!");
6927 Alignment =
6928 std::max(Alignment, assumeAligned(AlignmentAPI->getZExtValue()));
6929 }
6930
6931 // TODO: Hoist the alloca towards the function entry.
6932 unsigned AS = DL.getAllocaAddrSpace();
6933 Instruction *Alloca =
6934 new AllocaInst(Type::getInt8Ty(F->getContext()), AS, Size, Alignment,
6935 AI.CB->getName() + ".h2s", IP);
6936
6937 if (Alloca->getType() != AI.CB->getType())
6938 Alloca = BitCastInst::CreatePointerBitCastOrAddrSpaceCast(
6939 Alloca, AI.CB->getType(), "malloc_cast", AI.CB->getIterator());
6940
6941 auto *I8Ty = Type::getInt8Ty(F->getContext());
6942 auto *InitVal = getInitialValueOfAllocation(AI.CB, TLI, I8Ty);
6943 assert(InitVal &&
6944 "Must be able to materialize initial memory state of allocation");
6945
6946 A.changeAfterManifest(IRPosition::inst(*AI.CB), *Alloca);
6947
6948 if (auto *II = dyn_cast<InvokeInst>(AI.CB)) {
6949 auto *NBB = II->getNormalDest();
6950 UncondBrInst::Create(NBB, AI.CB->getParent());
6951 A.deleteAfterManifest(*AI.CB);
6952 } else {
6953 A.deleteAfterManifest(*AI.CB);
6954 }
6955
6956 // Initialize the alloca with the same value as used by the allocation
6957 // function. We can skip undef as the initial value of an alloc is
6958 // undef, and the memset would simply end up being DSEd.
6959 if (!isa<UndefValue>(InitVal)) {
6960 IRBuilder<> Builder(Alloca->getNextNode());
6961 // TODO: Use alignment above if align!=1
6962 Builder.CreateMemSet(Alloca, InitVal, Size, std::nullopt);
6963 }
6964 HasChanged = ChangeStatus::CHANGED;
6965 }
6966
6967 return HasChanged;
6968 }
6969
6970 std::optional<APInt> getAPInt(Attributor &A, const AbstractAttribute &AA,
6971 Value &V) {
6972 bool UsedAssumedInformation = false;
6973 std::optional<Constant *> SimpleV =
6974 A.getAssumedConstant(V, AA, UsedAssumedInformation);
6975 if (!SimpleV)
6976 return APInt(64, 0);
6977 if (auto *CI = dyn_cast_or_null<ConstantInt>(*SimpleV))
6978 return CI->getValue();
6979 return std::nullopt;
6980 }
6981
6982 std::optional<APInt> getSize(Attributor &A, const AbstractAttribute &AA,
6983 AllocationInfo &AI) {
6984 auto Mapper = [&](const Value *V) -> const Value * {
6985 bool UsedAssumedInformation = false;
6986 if (std::optional<Constant *> SimpleV =
6987 A.getAssumedConstant(*V, AA, UsedAssumedInformation))
6988 if (*SimpleV)
6989 return *SimpleV;
6990 return V;
6991 };
6992
6993 const Function *F = getAnchorScope();
6994 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
6995 return getAllocSize(AI.CB, TLI, Mapper);
6996 }
6997
6998 /// Collection of all malloc-like calls in a function with associated
6999 /// information.
7000 MapVector<CallBase *, AllocationInfo *> AllocationInfos;
7001
7002 /// Collection of all free-like calls in a function with associated
7003 /// information.
7004 MapVector<CallBase *, DeallocationInfo *> DeallocationInfos;
7005
7006 ChangeStatus updateImpl(Attributor &A) override;
7007};
7008
7009ChangeStatus AAHeapToStackFunction::updateImpl(Attributor &A) {
7011 const Function *F = getAnchorScope();
7012 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
7013
7014 const auto *LivenessAA =
7015 A.getAAFor<AAIsDead>(*this, IRPosition::function(*F), DepClassTy::NONE);
7016
7017 MustBeExecutedContextExplorer *Explorer =
7018 A.getInfoCache().getMustBeExecutedContextExplorer();
7019
7020 bool StackIsAccessibleByOtherThreads =
7021 A.getInfoCache().stackIsAccessibleByOtherThreads();
7022
7023 LoopInfo *LI =
7024 A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(*F);
7025 std::optional<bool> MayContainIrreducibleControl;
7026 auto IsInLoop = [&](BasicBlock &BB) {
7027 if (&F->getEntryBlock() == &BB)
7028 return false;
7029 if (!MayContainIrreducibleControl.has_value())
7030 MayContainIrreducibleControl = mayContainIrreducibleControl(*F, LI);
7031 if (*MayContainIrreducibleControl)
7032 return true;
7033 if (!LI)
7034 return true;
7035 return LI->getLoopFor(&BB) != nullptr;
7036 };
7037
7038 // Flag to ensure we update our deallocation information at most once per
7039 // updateImpl call and only if we use the free check reasoning.
7040 bool HasUpdatedFrees = false;
7041
7042 auto UpdateFrees = [&]() {
7043 HasUpdatedFrees = true;
7044
7045 for (auto &It : DeallocationInfos) {
7046 DeallocationInfo &DI = *It.second;
7047 // For now we cannot use deallocations that have unknown inputs, skip
7048 // them.
7049 if (DI.MightFreeUnknownObjects)
7050 continue;
7051
7052 // No need to analyze dead calls, ignore them instead.
7053 bool UsedAssumedInformation = false;
7054 if (A.isAssumedDead(*DI.CB, this, LivenessAA, UsedAssumedInformation,
7055 /* CheckBBLivenessOnly */ true))
7056 continue;
7057
7058 // Use the non-optimistic version to get the freed object.
7059 Value *Obj = getUnderlyingObject(DI.FreedOp);
7060 if (!Obj) {
7061 LLVM_DEBUG(dbgs() << "[H2S] Unknown underlying object for free!\n");
7062 DI.MightFreeUnknownObjects = true;
7063 continue;
7064 }
7065
7066 // Free of null and undef can be ignored as no-ops (or UB in the latter
7067 // case).
7069 continue;
7070
7071 CallBase *ObjCB = dyn_cast<CallBase>(Obj);
7072 if (!ObjCB) {
7073 LLVM_DEBUG(dbgs() << "[H2S] Free of a non-call object: " << *Obj
7074 << "\n");
7075 DI.MightFreeUnknownObjects = true;
7076 continue;
7077 }
7078
7079 AllocationInfo *AI = AllocationInfos.lookup(ObjCB);
7080 if (!AI) {
7081 LLVM_DEBUG(dbgs() << "[H2S] Free of a non-allocation object: " << *Obj
7082 << "\n");
7083 DI.MightFreeUnknownObjects = true;
7084 continue;
7085 }
7086
7087 DI.PotentialAllocationCalls.insert(ObjCB);
7088 }
7089 };
7090
7091 auto FreeCheck = [&](AllocationInfo &AI) {
7092 // If the stack is not accessible by other threads, the "must-free" logic
7093 // doesn't apply as the pointer could be shared and needs to be places in
7094 // "shareable" memory.
7095 if (!StackIsAccessibleByOtherThreads) {
7096 bool IsKnownNoSycn;
7098 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNoSycn)) {
7099 LLVM_DEBUG(
7100 dbgs() << "[H2S] found an escaping use, stack is not accessible by "
7101 "other threads and function is not nosync:\n");
7102 return false;
7103 }
7104 }
7105 if (!HasUpdatedFrees)
7106 UpdateFrees();
7107
7108 // TODO: Allow multi exit functions that have different free calls.
7109 if (AI.PotentialFreeCalls.size() != 1) {
7110 LLVM_DEBUG(dbgs() << "[H2S] did not find one free call but "
7111 << AI.PotentialFreeCalls.size() << "\n");
7112 return false;
7113 }
7114 CallBase *UniqueFree = *AI.PotentialFreeCalls.begin();
7115 DeallocationInfo *DI = DeallocationInfos.lookup(UniqueFree);
7116 if (!DI) {
7117 LLVM_DEBUG(
7118 dbgs() << "[H2S] unique free call was not known as deallocation call "
7119 << *UniqueFree << "\n");
7120 return false;
7121 }
7122 if (DI->MightFreeUnknownObjects) {
7123 LLVM_DEBUG(
7124 dbgs() << "[H2S] unique free call might free unknown allocations\n");
7125 return false;
7126 }
7127 if (DI->PotentialAllocationCalls.empty())
7128 return true;
7129 if (DI->PotentialAllocationCalls.size() > 1) {
7130 LLVM_DEBUG(dbgs() << "[H2S] unique free call might free "
7131 << DI->PotentialAllocationCalls.size()
7132 << " different allocations\n");
7133 return false;
7134 }
7135 if (*DI->PotentialAllocationCalls.begin() != AI.CB) {
7136 LLVM_DEBUG(
7137 dbgs()
7138 << "[H2S] unique free call not known to free this allocation but "
7139 << **DI->PotentialAllocationCalls.begin() << "\n");
7140 return false;
7141 }
7142
7143 // __kmpc_alloc_shared and __kmpc_free_shared are by construction matched.
7144 if (!AI.IsGlobalizedLocal) {
7145 Instruction *CtxI = isa<InvokeInst>(AI.CB) ? AI.CB : AI.CB->getNextNode();
7146 if (!Explorer || !Explorer->findInContextOf(UniqueFree, CtxI)) {
7147 LLVM_DEBUG(dbgs() << "[H2S] unique free call might not be executed "
7148 "with the allocation "
7149 << *UniqueFree << "\n");
7150 return false;
7151 }
7152 }
7153 return true;
7154 };
7155
7156 auto UsesCheck = [&](AllocationInfo &AI) {
7157 bool ValidUsesOnly = true;
7158
7159 auto Pred = [&](const Use &U, bool &Follow) -> bool {
7160 Instruction *UserI = cast<Instruction>(U.getUser());
7161 if (isa<LoadInst>(UserI))
7162 return true;
7163 if (auto *SI = dyn_cast<StoreInst>(UserI)) {
7164 if (SI->getValueOperand() == U.get()) {
7166 << "[H2S] escaping store to memory: " << *UserI << "\n");
7167 ValidUsesOnly = false;
7168 } else {
7169 // A store into the malloc'ed memory is fine.
7170 }
7171 return true;
7172 }
7173 if (auto *CB = dyn_cast<CallBase>(UserI)) {
7174 if (!CB->isArgOperand(&U) || CB->isLifetimeStartOrEnd())
7175 return true;
7176 if (DeallocationInfos.count(CB)) {
7177 AI.PotentialFreeCalls.insert(CB);
7178 return true;
7179 }
7180
7181 unsigned ArgNo = CB->getArgOperandNo(&U);
7182 auto CBIRP = IRPosition::callsite_argument(*CB, ArgNo);
7183
7184 bool IsKnownNoCapture;
7185 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
7186 A, this, CBIRP, DepClassTy::OPTIONAL, IsKnownNoCapture);
7187
7188 // If a call site argument use is nofree, we are fine.
7189 bool IsKnownNoFree;
7190 bool IsAssumedNoFree = AA::hasAssumedIRAttr<Attribute::NoFree>(
7191 A, this, CBIRP, DepClassTy::OPTIONAL, IsKnownNoFree);
7192
7193 if (!IsAssumedNoCapture ||
7194 (!AI.IsGlobalizedLocal && !IsAssumedNoFree)) {
7195 AI.HasPotentiallyFreeingUnknownUses |= !IsAssumedNoFree;
7196
7197 // Emit a missed remark if this is missed OpenMP globalization.
7198 auto Remark = [&](OptimizationRemarkMissed ORM) {
7199 return ORM
7200 << "Could not move globalized variable to the stack. "
7201 "Variable is potentially captured in call. Mark "
7202 "parameter as `__attribute__((noescape))` to override.";
7203 };
7204
7205 if (ValidUsesOnly && AI.IsGlobalizedLocal)
7206 A.emitRemark<OptimizationRemarkMissed>(CB, "OMP113", Remark);
7207
7208 LLVM_DEBUG(dbgs() << "[H2S] Bad user: " << *UserI << "\n");
7209 ValidUsesOnly = false;
7210 }
7211 return true;
7212 }
7213
7214 if (isa<GetElementPtrInst>(UserI) || isa<BitCastInst>(UserI) ||
7215 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) {
7216 Follow = true;
7217 return true;
7218 }
7219 // Unknown user for which we can not track uses further (in a way that
7220 // makes sense).
7221 LLVM_DEBUG(dbgs() << "[H2S] Unknown user: " << *UserI << "\n");
7222 ValidUsesOnly = false;
7223 return true;
7224 };
7225 if (!A.checkForAllUses(Pred, *this, *AI.CB, /* CheckBBLivenessOnly */ false,
7226 DepClassTy::OPTIONAL, /* IgnoreDroppableUses */ true,
7227 [&](const Use &OldU, const Use &NewU) {
7228 auto *SI = dyn_cast<StoreInst>(OldU.getUser());
7229 return !SI || StackIsAccessibleByOtherThreads ||
7230 AA::isAssumedThreadLocalObject(
7231 A, *SI->getPointerOperand(), *this);
7232 }))
7233 return false;
7234 return ValidUsesOnly;
7235 };
7236
7237 // The actual update starts here. We look at all allocations and depending on
7238 // their status perform the appropriate check(s).
7239 for (auto &It : AllocationInfos) {
7240 AllocationInfo &AI = *It.second;
7241 if (AI.Status == AllocationInfo::INVALID)
7242 continue;
7243
7244 if (Value *Align = getAllocAlignment(AI.CB, TLI)) {
7245 std::optional<APInt> APAlign = getAPInt(A, *this, *Align);
7246 if (!APAlign) {
7247 // Can't generate an alloca which respects the required alignment
7248 // on the allocation.
7249 LLVM_DEBUG(dbgs() << "[H2S] Unknown allocation alignment: " << *AI.CB
7250 << "\n");
7251 AI.Status = AllocationInfo::INVALID;
7253 continue;
7254 }
7255 if (APAlign->ugt(llvm::Value::MaximumAlignment) ||
7256 !APAlign->isPowerOf2()) {
7257 LLVM_DEBUG(dbgs() << "[H2S] Invalid allocation alignment: " << APAlign
7258 << "\n");
7259 AI.Status = AllocationInfo::INVALID;
7261 continue;
7262 }
7263 }
7264
7265 std::optional<APInt> Size = getSize(A, *this, AI);
7266 if (!AI.IsGlobalizedLocal && MaxHeapToStackSize != -1) {
7267 if (!Size || Size->ugt(MaxHeapToStackSize)) {
7268 LLVM_DEBUG({
7269 if (!Size)
7270 dbgs() << "[H2S] Unknown allocation size: " << *AI.CB << "\n";
7271 else
7272 dbgs() << "[H2S] Allocation size too large: " << *AI.CB << " vs. "
7273 << MaxHeapToStackSize << "\n";
7274 });
7275
7276 AI.Status = AllocationInfo::INVALID;
7278 continue;
7279 }
7280 }
7281
7282 switch (AI.Status) {
7283 case AllocationInfo::STACK_DUE_TO_USE:
7284 if (UsesCheck(AI))
7285 break;
7286 AI.Status = AllocationInfo::STACK_DUE_TO_FREE;
7287 [[fallthrough]];
7288 case AllocationInfo::STACK_DUE_TO_FREE:
7289 if (FreeCheck(AI))
7290 break;
7291 AI.Status = AllocationInfo::INVALID;
7293 break;
7294 case AllocationInfo::INVALID:
7295 llvm_unreachable("Invalid allocations should never reach this point!");
7296 };
7297
7298 // Check if we still think we can move it into the entry block. If the
7299 // alloca comes from a converted __kmpc_alloc_shared then we can usually
7300 // ignore the potential complications associated with loops.
7301 bool IsGlobalizedLocal = AI.IsGlobalizedLocal;
7302 if (AI.MoveAllocaIntoEntry &&
7303 (!Size.has_value() ||
7304 (!IsGlobalizedLocal && IsInLoop(*AI.CB->getParent()))))
7305 AI.MoveAllocaIntoEntry = false;
7306 }
7307
7308 return Changed;
7309}
7310} // namespace
7311
7312/// ----------------------- Privatizable Pointers ------------------------------
7313namespace {
7314struct AAPrivatizablePtrImpl : public AAPrivatizablePtr {
7315 AAPrivatizablePtrImpl(const IRPosition &IRP, Attributor &A)
7316 : AAPrivatizablePtr(IRP, A), PrivatizableType(std::nullopt) {}
7317
7318 ChangeStatus indicatePessimisticFixpoint() override {
7319 AAPrivatizablePtr::indicatePessimisticFixpoint();
7320 PrivatizableType = nullptr;
7321 return ChangeStatus::CHANGED;
7322 }
7323
7324 /// Identify the type we can chose for a private copy of the underlying
7325 /// argument. std::nullopt means it is not clear yet, nullptr means there is
7326 /// none.
7327 virtual std::optional<Type *> identifyPrivatizableType(Attributor &A) = 0;
7328
7329 /// Return a privatizable type that encloses both T0 and T1.
7330 /// TODO: This is merely a stub for now as we should manage a mapping as well.
7331 std::optional<Type *> combineTypes(std::optional<Type *> T0,
7332 std::optional<Type *> T1) {
7333 if (!T0)
7334 return T1;
7335 if (!T1)
7336 return T0;
7337 if (T0 == T1)
7338 return T0;
7339 return nullptr;
7340 }
7341
7342 std::optional<Type *> getPrivatizableType() const override {
7343 return PrivatizableType;
7344 }
7345
7346 const std::string getAsStr(Attributor *A) const override {
7347 return isAssumedPrivatizablePtr() ? "[priv]" : "[no-priv]";
7348 }
7349
7350protected:
7351 std::optional<Type *> PrivatizableType;
7352};
7353
7354// TODO: Do this for call site arguments (probably also other values) as well.
7355
7356struct AAPrivatizablePtrArgument final : public AAPrivatizablePtrImpl {
7357 AAPrivatizablePtrArgument(const IRPosition &IRP, Attributor &A)
7358 : AAPrivatizablePtrImpl(IRP, A) {}
7359
7360 /// See AAPrivatizablePtrImpl::identifyPrivatizableType(...)
7361 std::optional<Type *> identifyPrivatizableType(Attributor &A) override {
7362 // If this is a byval argument and we know all the call sites (so we can
7363 // rewrite them), there is no need to check them explicitly.
7364 bool UsedAssumedInformation = false;
7366 A.getAttrs(getIRPosition(), {Attribute::ByVal}, Attrs,
7367 /* IgnoreSubsumingPositions */ true);
7368 if (!Attrs.empty() &&
7369 A.checkForAllCallSites([](AbstractCallSite ACS) { return true; }, *this,
7370 true, UsedAssumedInformation))
7371 return Attrs[0].getValueAsType();
7372
7373 std::optional<Type *> Ty;
7374 unsigned ArgNo = getIRPosition().getCallSiteArgNo();
7375
7376 // Make sure the associated call site argument has the same type at all call
7377 // sites and it is an allocation we know is safe to privatize, for now that
7378 // means we only allow alloca instructions.
7379 // TODO: We can additionally analyze the accesses in the callee to create
7380 // the type from that information instead. That is a little more
7381 // involved and will be done in a follow up patch.
7382 auto CallSiteCheck = [&](AbstractCallSite ACS) {
7383 IRPosition ACSArgPos = IRPosition::callsite_argument(ACS, ArgNo);
7384 // Check if a coresponding argument was found or if it is one not
7385 // associated (which can happen for callback calls).
7386 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
7387 return false;
7388
7389 // Check that all call sites agree on a type.
7390 auto *PrivCSArgAA =
7391 A.getAAFor<AAPrivatizablePtr>(*this, ACSArgPos, DepClassTy::REQUIRED);
7392 if (!PrivCSArgAA)
7393 return false;
7394 std::optional<Type *> CSTy = PrivCSArgAA->getPrivatizableType();
7395
7396 LLVM_DEBUG({
7397 dbgs() << "[AAPrivatizablePtr] ACSPos: " << ACSArgPos << ", CSTy: ";
7398 if (CSTy && *CSTy)
7399 (*CSTy)->print(dbgs());
7400 else if (CSTy)
7401 dbgs() << "<nullptr>";
7402 else
7403 dbgs() << "<none>";
7404 });
7405
7406 Ty = combineTypes(Ty, CSTy);
7407
7408 LLVM_DEBUG({
7409 dbgs() << " : New Type: ";
7410 if (Ty && *Ty)
7411 (*Ty)->print(dbgs());
7412 else if (Ty)
7413 dbgs() << "<nullptr>";
7414 else
7415 dbgs() << "<none>";
7416 dbgs() << "\n";
7417 });
7418
7419 return !Ty || *Ty;
7420 };
7421
7422 if (!A.checkForAllCallSites(CallSiteCheck, *this, true,
7423 UsedAssumedInformation))
7424 return nullptr;
7425 return Ty;
7426 }
7427
7428 /// See AbstractAttribute::updateImpl(...).
7429 ChangeStatus updateImpl(Attributor &A) override {
7430 PrivatizableType = identifyPrivatizableType(A);
7431 if (!PrivatizableType)
7432 return ChangeStatus::UNCHANGED;
7433 if (!*PrivatizableType)
7434 return indicatePessimisticFixpoint();
7435
7436 // The dependence is optional so we don't give up once we give up on the
7437 // alignment.
7438 A.getAAFor<AAAlign>(*this, IRPosition::value(getAssociatedValue()),
7439 DepClassTy::OPTIONAL);
7440
7441 // Avoid arguments with padding for now.
7442 if (!A.hasAttr(getIRPosition(), Attribute::ByVal) &&
7443 !isDenselyPacked(*PrivatizableType, A.getInfoCache().getDL())) {
7444 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Padding detected\n");
7445 return indicatePessimisticFixpoint();
7446 }
7447
7448 // Collect the types that will replace the privatizable type in the function
7449 // signature.
7450 SmallVector<Type *, 16> ReplacementTypes;
7451 identifyReplacementTypes(*PrivatizableType, ReplacementTypes);
7452
7453 // Verify callee and caller agree on how the promoted argument would be
7454 // passed.
7455 Function &Fn = *getIRPosition().getAnchorScope();
7456 const auto *TTI =
7457 A.getInfoCache().getAnalysisResultForFunction<TargetIRAnalysis>(Fn);
7458 if (!TTI) {
7459 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Missing TTI for function "
7460 << Fn.getName() << "\n");
7461 return indicatePessimisticFixpoint();
7462 }
7463
7464 auto CallSiteCheck = [&](AbstractCallSite ACS) {
7465 CallBase *CB = ACS.getInstruction();
7466 return TTI->areTypesABICompatible(
7467 CB->getCaller(),
7469 ReplacementTypes);
7470 };
7471 bool UsedAssumedInformation = false;
7472 if (!A.checkForAllCallSites(CallSiteCheck, *this, true,
7473 UsedAssumedInformation)) {
7474 LLVM_DEBUG(
7475 dbgs() << "[AAPrivatizablePtr] ABI incompatibility detected for "
7476 << Fn.getName() << "\n");
7477 return indicatePessimisticFixpoint();
7478 }
7479
7480 // Register a rewrite of the argument.
7481 Argument *Arg = getAssociatedArgument();
7482 if (!A.isValidFunctionSignatureRewrite(*Arg, ReplacementTypes)) {
7483 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Rewrite not valid\n");
7484 return indicatePessimisticFixpoint();
7485 }
7486
7487 unsigned ArgNo = Arg->getArgNo();
7488
7489 // Helper to check if for the given call site the associated argument is
7490 // passed to a callback where the privatization would be different.
7491 auto IsCompatiblePrivArgOfCallback = [&](CallBase &CB) {
7492 SmallVector<const Use *, 4> CallbackUses;
7493 AbstractCallSite::getCallbackUses(CB, CallbackUses);
7494 for (const Use *U : CallbackUses) {
7495 AbstractCallSite CBACS(U);
7496 assert(CBACS && CBACS.isCallbackCall());
7497 for (Argument &CBArg : CBACS.getCalledFunction()->args()) {
7498 int CBArgNo = CBACS.getCallArgOperandNo(CBArg);
7499
7500 LLVM_DEBUG({
7501 dbgs()
7502 << "[AAPrivatizablePtr] Argument " << *Arg
7503 << "check if can be privatized in the context of its parent ("
7504 << Arg->getParent()->getName()
7505 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7506 "callback ("
7507 << CBArgNo << "@" << CBACS.getCalledFunction()->getName()
7508 << ")\n[AAPrivatizablePtr] " << CBArg << " : "
7509 << CBACS.getCallArgOperand(CBArg) << " vs "
7510 << CB.getArgOperand(ArgNo) << "\n"
7511 << "[AAPrivatizablePtr] " << CBArg << " : "
7512 << CBACS.getCallArgOperandNo(CBArg) << " vs " << ArgNo << "\n";
7513 });
7514
7515 if (CBArgNo != int(ArgNo))
7516 continue;
7517 const auto *CBArgPrivAA = A.getAAFor<AAPrivatizablePtr>(
7518 *this, IRPosition::argument(CBArg), DepClassTy::REQUIRED);
7519 if (CBArgPrivAA && CBArgPrivAA->isValidState()) {
7520 auto CBArgPrivTy = CBArgPrivAA->getPrivatizableType();
7521 if (!CBArgPrivTy)
7522 continue;
7523 if (*CBArgPrivTy == PrivatizableType)
7524 continue;
7525 }
7526
7527 LLVM_DEBUG({
7528 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
7529 << " cannot be privatized in the context of its parent ("
7530 << Arg->getParent()->getName()
7531 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7532 "callback ("
7533 << CBArgNo << "@" << CBACS.getCalledFunction()->getName()
7534 << ").\n[AAPrivatizablePtr] for which the argument "
7535 "privatization is not compatible.\n";
7536 });
7537 return false;
7538 }
7539 }
7540 return true;
7541 };
7542
7543 // Helper to check if for the given call site the associated argument is
7544 // passed to a direct call where the privatization would be different.
7545 auto IsCompatiblePrivArgOfDirectCS = [&](AbstractCallSite ACS) {
7546 CallBase *DC = cast<CallBase>(ACS.getInstruction());
7547 int DCArgNo = ACS.getCallArgOperandNo(ArgNo);
7548 assert(DCArgNo >= 0 && unsigned(DCArgNo) < DC->arg_size() &&
7549 "Expected a direct call operand for callback call operand");
7550
7551 Function *DCCallee =
7553 LLVM_DEBUG({
7554 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
7555 << " check if be privatized in the context of its parent ("
7556 << Arg->getParent()->getName()
7557 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7558 "direct call of ("
7559 << DCArgNo << "@" << DCCallee->getName() << ").\n";
7560 });
7561
7562 if (unsigned(DCArgNo) < DCCallee->arg_size()) {
7563 const auto *DCArgPrivAA = A.getAAFor<AAPrivatizablePtr>(
7564 *this, IRPosition::argument(*DCCallee->getArg(DCArgNo)),
7565 DepClassTy::REQUIRED);
7566 if (DCArgPrivAA && DCArgPrivAA->isValidState()) {
7567 auto DCArgPrivTy = DCArgPrivAA->getPrivatizableType();
7568 if (!DCArgPrivTy)
7569 return true;
7570 if (*DCArgPrivTy == PrivatizableType)
7571 return true;
7572 }
7573 }
7574
7575 LLVM_DEBUG({
7576 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
7577 << " cannot be privatized in the context of its parent ("
7578 << Arg->getParent()->getName()
7579 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7580 "direct call of ("
7582 << ").\n[AAPrivatizablePtr] for which the argument "
7583 "privatization is not compatible.\n";
7584 });
7585 return false;
7586 };
7587
7588 // Helper to check if the associated argument is used at the given abstract
7589 // call site in a way that is incompatible with the privatization assumed
7590 // here.
7591 auto IsCompatiblePrivArgOfOtherCallSite = [&](AbstractCallSite ACS) {
7592 if (ACS.isDirectCall())
7593 return IsCompatiblePrivArgOfCallback(*ACS.getInstruction());
7594 if (ACS.isCallbackCall())
7595 return IsCompatiblePrivArgOfDirectCS(ACS);
7596 return false;
7597 };
7598
7599 if (!A.checkForAllCallSites(IsCompatiblePrivArgOfOtherCallSite, *this, true,
7600 UsedAssumedInformation))
7601 return indicatePessimisticFixpoint();
7602
7603 return ChangeStatus::UNCHANGED;
7604 }
7605
7606 /// Given a type to private \p PrivType, collect the constituates (which are
7607 /// used) in \p ReplacementTypes.
7608 static void
7609 identifyReplacementTypes(Type *PrivType,
7610 SmallVectorImpl<Type *> &ReplacementTypes) {
7611 // TODO: For now we expand the privatization type to the fullest which can
7612 // lead to dead arguments that need to be removed later.
7613 assert(PrivType && "Expected privatizable type!");
7614
7615 // Traverse the type, extract constituate types on the outermost level.
7616 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) {
7617 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++)
7618 ReplacementTypes.push_back(PrivStructType->getElementType(u));
7619 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) {
7620 ReplacementTypes.append(PrivArrayType->getNumElements(),
7621 PrivArrayType->getElementType());
7622 } else {
7623 ReplacementTypes.push_back(PrivType);
7624 }
7625 }
7626
7627 /// Initialize \p Base according to the type \p PrivType at position \p IP.
7628 /// The values needed are taken from the arguments of \p F starting at
7629 /// position \p ArgNo.
7630 static void createInitialization(Type *PrivType, Value &Base, Function &F,
7631 unsigned ArgNo, BasicBlock::iterator IP) {
7632 assert(PrivType && "Expected privatizable type!");
7633
7634 IRBuilder<NoFolder> IRB(IP->getParent(), IP);
7635 const DataLayout &DL = F.getDataLayout();
7636
7637 // Traverse the type, build GEPs and stores.
7638 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) {
7639 const StructLayout *PrivStructLayout = DL.getStructLayout(PrivStructType);
7640 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++) {
7641 Value *Ptr =
7642 constructPointer(&Base, PrivStructLayout->getElementOffset(u), IRB);
7643 new StoreInst(F.getArg(ArgNo + u), Ptr, IP);
7644 }
7645 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) {
7646 Type *PointeeTy = PrivArrayType->getElementType();
7647 uint64_t PointeeTySize = DL.getTypeStoreSize(PointeeTy);
7648 for (unsigned u = 0, e = PrivArrayType->getNumElements(); u < e; u++) {
7649 Value *Ptr = constructPointer(&Base, u * PointeeTySize, IRB);
7650 new StoreInst(F.getArg(ArgNo + u), Ptr, IP);
7651 }
7652 } else {
7653 new StoreInst(F.getArg(ArgNo), &Base, IP);
7654 }
7655 }
7656
7657 /// Extract values from \p Base according to the type \p PrivType at the
7658 /// call position \p ACS. The values are appended to \p ReplacementValues.
7659 void createReplacementValues(Align Alignment, Type *PrivType,
7660 AbstractCallSite ACS, Value *Base,
7661 SmallVectorImpl<Value *> &ReplacementValues) {
7662 assert(Base && "Expected base value!");
7663 assert(PrivType && "Expected privatizable type!");
7664 Instruction *IP = ACS.getInstruction();
7665
7666 IRBuilder<NoFolder> IRB(IP);
7667 const DataLayout &DL = IP->getDataLayout();
7668
7669 // Traverse the type, build GEPs and loads.
7670 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) {
7671 const StructLayout *PrivStructLayout = DL.getStructLayout(PrivStructType);
7672 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++) {
7673 Type *PointeeTy = PrivStructType->getElementType(u);
7674 Value *Ptr =
7675 constructPointer(Base, PrivStructLayout->getElementOffset(u), IRB);
7676 LoadInst *L = new LoadInst(PointeeTy, Ptr, "", IP->getIterator());
7677 L->setAlignment(Alignment);
7678 ReplacementValues.push_back(L);
7679 }
7680 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) {
7681 Type *PointeeTy = PrivArrayType->getElementType();
7682 uint64_t PointeeTySize = DL.getTypeStoreSize(PointeeTy);
7683 for (unsigned u = 0, e = PrivArrayType->getNumElements(); u < e; u++) {
7684 Value *Ptr = constructPointer(Base, u * PointeeTySize, IRB);
7685 LoadInst *L = new LoadInst(PointeeTy, Ptr, "", IP->getIterator());
7686 L->setAlignment(Alignment);
7687 ReplacementValues.push_back(L);
7688 }
7689 } else {
7690 LoadInst *L = new LoadInst(PrivType, Base, "", IP->getIterator());
7691 L->setAlignment(Alignment);
7692 ReplacementValues.push_back(L);
7693 }
7694 }
7695
7696 /// See AbstractAttribute::manifest(...)
7697 ChangeStatus manifest(Attributor &A) override {
7698 if (!PrivatizableType)
7699 return ChangeStatus::UNCHANGED;
7700 assert(*PrivatizableType && "Expected privatizable type!");
7701
7702 // Collect all tail calls in the function as we cannot allow new allocas to
7703 // escape into tail recursion.
7704 // TODO: Be smarter about new allocas escaping into tail calls.
7706 bool UsedAssumedInformation = false;
7707 if (!A.checkForAllInstructions(
7708 [&](Instruction &I) {
7709 CallInst &CI = cast<CallInst>(I);
7710 if (CI.isTailCall())
7711 TailCalls.push_back(&CI);
7712 return true;
7713 },
7714 *this, {Instruction::Call}, UsedAssumedInformation))
7715 return ChangeStatus::UNCHANGED;
7716
7717 Argument *Arg = getAssociatedArgument();
7718 // Query AAAlign attribute for alignment of associated argument to
7719 // determine the best alignment of loads.
7720 const auto *AlignAA =
7721 A.getAAFor<AAAlign>(*this, IRPosition::value(*Arg), DepClassTy::NONE);
7722
7723 // Callback to repair the associated function. A new alloca is placed at the
7724 // beginning and initialized with the values passed through arguments. The
7725 // new alloca replaces the use of the old pointer argument.
7727 [=](const Attributor::ArgumentReplacementInfo &ARI,
7728 Function &ReplacementFn, Function::arg_iterator ArgIt) {
7729 BasicBlock &EntryBB = ReplacementFn.getEntryBlock();
7731 const DataLayout &DL = IP->getDataLayout();
7732 unsigned AS = DL.getAllocaAddrSpace();
7733 Instruction *AI = new AllocaInst(*PrivatizableType, AS,
7734 Arg->getName() + ".priv", IP);
7735 createInitialization(*PrivatizableType, *AI, ReplacementFn,
7736 ArgIt->getArgNo(), IP);
7737
7738 if (AI->getType() != Arg->getType())
7739 AI = BitCastInst::CreatePointerBitCastOrAddrSpaceCast(
7740 AI, Arg->getType(), "", IP);
7741 Arg->replaceAllUsesWith(AI);
7742
7743 for (CallInst *CI : TailCalls)
7744 CI->setTailCall(false);
7745 };
7746
7747 // Callback to repair a call site of the associated function. The elements
7748 // of the privatizable type are loaded prior to the call and passed to the
7749 // new function version.
7751 [=](const Attributor::ArgumentReplacementInfo &ARI,
7752 AbstractCallSite ACS, SmallVectorImpl<Value *> &NewArgOperands) {
7753 // When no alignment is specified for the load instruction,
7754 // natural alignment is assumed.
7755 createReplacementValues(
7756 AlignAA ? AlignAA->getAssumedAlign() : Align(0),
7757 *PrivatizableType, ACS,
7758 ACS.getCallArgOperand(ARI.getReplacedArg().getArgNo()),
7759 NewArgOperands);
7760 };
7761
7762 // Collect the types that will replace the privatizable type in the function
7763 // signature.
7764 SmallVector<Type *, 16> ReplacementTypes;
7765 identifyReplacementTypes(*PrivatizableType, ReplacementTypes);
7766
7767 // Register a rewrite of the argument.
7768 if (A.registerFunctionSignatureRewrite(*Arg, ReplacementTypes,
7769 std::move(FnRepairCB),
7770 std::move(ACSRepairCB)))
7771 return ChangeStatus::CHANGED;
7772 return ChangeStatus::UNCHANGED;
7773 }
7774
7775 /// See AbstractAttribute::trackStatistics()
7776 void trackStatistics() const override {
7777 STATS_DECLTRACK_ARG_ATTR(privatizable_ptr);
7778 }
7779};
7780
7781struct AAPrivatizablePtrFloating : public AAPrivatizablePtrImpl {
7782 AAPrivatizablePtrFloating(const IRPosition &IRP, Attributor &A)
7783 : AAPrivatizablePtrImpl(IRP, A) {}
7784
7785 /// See AbstractAttribute::initialize(...).
7786 void initialize(Attributor &A) override {
7787 // TODO: We can privatize more than arguments.
7788 indicatePessimisticFixpoint();
7789 }
7790
7791 ChangeStatus updateImpl(Attributor &A) override {
7792 llvm_unreachable("AAPrivatizablePtr(Floating|Returned|CallSiteReturned)::"
7793 "updateImpl will not be called");
7794 }
7795
7796 /// See AAPrivatizablePtrImpl::identifyPrivatizableType(...)
7797 std::optional<Type *> identifyPrivatizableType(Attributor &A) override {
7798 Value *Obj = getUnderlyingObject(&getAssociatedValue());
7799 if (!Obj) {
7800 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] No underlying object found!\n");
7801 return nullptr;
7802 }
7803
7804 if (auto *AI = dyn_cast<AllocaInst>(Obj))
7805 if (auto *CI = dyn_cast<ConstantInt>(AI->getArraySize()))
7806 if (CI->isOne())
7807 return AI->getAllocatedType();
7808 if (auto *Arg = dyn_cast<Argument>(Obj)) {
7809 auto *PrivArgAA = A.getAAFor<AAPrivatizablePtr>(
7810 *this, IRPosition::argument(*Arg), DepClassTy::REQUIRED);
7811 if (PrivArgAA && PrivArgAA->isAssumedPrivatizablePtr())
7812 return PrivArgAA->getPrivatizableType();
7813 }
7814
7815 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Underlying object neither valid "
7816 "alloca nor privatizable argument: "
7817 << *Obj << "!\n");
7818 return nullptr;
7819 }
7820
7821 /// See AbstractAttribute::trackStatistics()
7822 void trackStatistics() const override {
7823 STATS_DECLTRACK_FLOATING_ATTR(privatizable_ptr);
7824 }
7825};
7826
7827struct AAPrivatizablePtrCallSiteArgument final
7828 : public AAPrivatizablePtrFloating {
7829 AAPrivatizablePtrCallSiteArgument(const IRPosition &IRP, Attributor &A)
7830 : AAPrivatizablePtrFloating(IRP, A) {}
7831
7832 /// See AbstractAttribute::initialize(...).
7833 void initialize(Attributor &A) override {
7834 if (A.hasAttr(getIRPosition(), Attribute::ByVal))
7835 indicateOptimisticFixpoint();
7836 }
7837
7838 /// See AbstractAttribute::updateImpl(...).
7839 ChangeStatus updateImpl(Attributor &A) override {
7840 PrivatizableType = identifyPrivatizableType(A);
7841 if (!PrivatizableType)
7842 return ChangeStatus::UNCHANGED;
7843 if (!*PrivatizableType)
7844 return indicatePessimisticFixpoint();
7845
7846 const IRPosition &IRP = getIRPosition();
7847 bool IsKnownNoCapture;
7848 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
7849 A, this, IRP, DepClassTy::REQUIRED, IsKnownNoCapture);
7850 if (!IsAssumedNoCapture) {
7851 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer might be captured!\n");
7852 return indicatePessimisticFixpoint();
7853 }
7854
7855 bool IsKnownNoAlias;
7857 A, this, IRP, DepClassTy::REQUIRED, IsKnownNoAlias)) {
7858 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer might alias!\n");
7859 return indicatePessimisticFixpoint();
7860 }
7861
7862 bool IsKnown;
7863 if (!AA::isAssumedReadOnly(A, IRP, *this, IsKnown)) {
7864 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer is written!\n");
7865 return indicatePessimisticFixpoint();
7866 }
7867
7868 return ChangeStatus::UNCHANGED;
7869 }
7870
7871 /// See AbstractAttribute::trackStatistics()
7872 void trackStatistics() const override {
7873 STATS_DECLTRACK_CSARG_ATTR(privatizable_ptr);
7874 }
7875};
7876
7877struct AAPrivatizablePtrCallSiteReturned final
7878 : public AAPrivatizablePtrFloating {
7879 AAPrivatizablePtrCallSiteReturned(const IRPosition &IRP, Attributor &A)
7880 : AAPrivatizablePtrFloating(IRP, A) {}
7881
7882 /// See AbstractAttribute::initialize(...).
7883 void initialize(Attributor &A) override {
7884 // TODO: We can privatize more than arguments.
7885 indicatePessimisticFixpoint();
7886 }
7887
7888 /// See AbstractAttribute::trackStatistics()
7889 void trackStatistics() const override {
7890 STATS_DECLTRACK_CSRET_ATTR(privatizable_ptr);
7891 }
7892};
7893
7894struct AAPrivatizablePtrReturned final : public AAPrivatizablePtrFloating {
7895 AAPrivatizablePtrReturned(const IRPosition &IRP, Attributor &A)
7896 : AAPrivatizablePtrFloating(IRP, A) {}
7897
7898 /// See AbstractAttribute::initialize(...).
7899 void initialize(Attributor &A) override {
7900 // TODO: We can privatize more than arguments.
7901 indicatePessimisticFixpoint();
7902 }
7903
7904 /// See AbstractAttribute::trackStatistics()
7905 void trackStatistics() const override {
7906 STATS_DECLTRACK_FNRET_ATTR(privatizable_ptr);
7907 }
7908};
7909} // namespace
7910
7911/// -------------------- Memory Behavior Attributes ----------------------------
7912/// Includes read-none, read-only, and write-only.
7913/// ----------------------------------------------------------------------------
7914namespace {
7915struct AAMemoryBehaviorImpl : public AAMemoryBehavior {
7916 AAMemoryBehaviorImpl(const IRPosition &IRP, Attributor &A)
7917 : AAMemoryBehavior(IRP, A) {}
7918
7919 /// See AbstractAttribute::initialize(...).
7920 void initialize(Attributor &A) override {
7921 intersectAssumedBits(BEST_STATE);
7922 getKnownStateFromValue(A, getIRPosition(), getState());
7923 AAMemoryBehavior::initialize(A);
7924 }
7925
7926 /// Return the memory behavior information encoded in the IR for \p IRP.
7927 static void getKnownStateFromValue(Attributor &A, const IRPosition &IRP,
7928 BitIntegerState &State,
7929 bool IgnoreSubsumingPositions = false) {
7931 A.getAttrs(IRP, AttrKinds, Attrs, IgnoreSubsumingPositions);
7932 for (const Attribute &Attr : Attrs) {
7933 switch (Attr.getKindAsEnum()) {
7934 case Attribute::ReadNone:
7935 State.addKnownBits(NO_ACCESSES);
7936 break;
7937 case Attribute::ReadOnly:
7938 State.addKnownBits(NO_WRITES);
7939 break;
7940 case Attribute::WriteOnly:
7941 State.addKnownBits(NO_READS);
7942 break;
7943 default:
7944 llvm_unreachable("Unexpected attribute!");
7945 }
7946 }
7947
7948 if (auto *I = dyn_cast<Instruction>(&IRP.getAnchorValue())) {
7949 if (!I->mayReadFromMemory())
7950 State.addKnownBits(NO_READS);
7951 if (!I->mayWriteToMemory())
7952 State.addKnownBits(NO_WRITES);
7953 }
7954 }
7955
7956 /// See AbstractAttribute::getDeducedAttributes(...).
7957 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
7958 SmallVectorImpl<Attribute> &Attrs) const override {
7959 assert(Attrs.size() == 0);
7960 if (isAssumedReadNone())
7961 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadNone));
7962 else if (isAssumedReadOnly())
7963 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadOnly));
7964 else if (isAssumedWriteOnly())
7965 Attrs.push_back(Attribute::get(Ctx, Attribute::WriteOnly));
7966 assert(Attrs.size() <= 1);
7967 }
7968
7969 /// See AbstractAttribute::manifest(...).
7970 ChangeStatus manifest(Attributor &A) override {
7971 const IRPosition &IRP = getIRPosition();
7972
7973 if (A.hasAttr(IRP, Attribute::ReadNone,
7974 /* IgnoreSubsumingPositions */ true))
7975 return ChangeStatus::UNCHANGED;
7976
7977 // Check if we would improve the existing attributes first.
7978 SmallVector<Attribute, 4> DeducedAttrs;
7979 getDeducedAttributes(A, IRP.getAnchorValue().getContext(), DeducedAttrs);
7980 if (llvm::all_of(DeducedAttrs, [&](const Attribute &Attr) {
7981 return A.hasAttr(IRP, Attr.getKindAsEnum(),
7982 /* IgnoreSubsumingPositions */ true);
7983 }))
7984 return ChangeStatus::UNCHANGED;
7985
7986 // Clear existing attributes.
7987 A.removeAttrs(IRP, AttrKinds);
7988 // Clear conflicting writable attribute.
7989 if (isAssumedReadOnly())
7990 A.removeAttrs(IRP, Attribute::Writable);
7991
7992 // Use the generic manifest method.
7993 return IRAttribute::manifest(A);
7994 }
7995
7996 /// See AbstractState::getAsStr().
7997 const std::string getAsStr(Attributor *A) const override {
7998 if (isAssumedReadNone())
7999 return "readnone";
8000 if (isAssumedReadOnly())
8001 return "readonly";
8002 if (isAssumedWriteOnly())
8003 return "writeonly";
8004 return "may-read/write";
8005 }
8006
8007 /// The set of IR attributes AAMemoryBehavior deals with.
8008 static const Attribute::AttrKind AttrKinds[3];
8009};
8010
8011const Attribute::AttrKind AAMemoryBehaviorImpl::AttrKinds[] = {
8012 Attribute::ReadNone, Attribute::ReadOnly, Attribute::WriteOnly};
8013
8014/// Memory behavior attribute for a floating value.
8015struct AAMemoryBehaviorFloating : AAMemoryBehaviorImpl {
8016 AAMemoryBehaviorFloating(const IRPosition &IRP, Attributor &A)
8017 : AAMemoryBehaviorImpl(IRP, A) {}
8018
8019 /// See AbstractAttribute::updateImpl(...).
8020 ChangeStatus updateImpl(Attributor &A) override;
8021
8022 /// See AbstractAttribute::trackStatistics()
8023 void trackStatistics() const override {
8024 if (isAssumedReadNone())
8026 else if (isAssumedReadOnly())
8028 else if (isAssumedWriteOnly())
8030 }
8031
8032private:
8033 /// Return true if users of \p UserI might access the underlying
8034 /// variable/location described by \p U and should therefore be analyzed.
8035 bool followUsersOfUseIn(Attributor &A, const Use &U,
8036 const Instruction *UserI);
8037
8038 /// Update the state according to the effect of use \p U in \p UserI.
8039 void analyzeUseIn(Attributor &A, const Use &U, const Instruction *UserI);
8040};
8041
8042/// Memory behavior attribute for function argument.
8043struct AAMemoryBehaviorArgument : AAMemoryBehaviorFloating {
8044 AAMemoryBehaviorArgument(const IRPosition &IRP, Attributor &A)
8045 : AAMemoryBehaviorFloating(IRP, A) {}
8046
8047 /// See AbstractAttribute::initialize(...).
8048 void initialize(Attributor &A) override {
8049 intersectAssumedBits(BEST_STATE);
8050 const IRPosition &IRP = getIRPosition();
8051 // TODO: Make IgnoreSubsumingPositions a property of an IRAttribute so we
8052 // can query it when we use has/getAttr. That would allow us to reuse the
8053 // initialize of the base class here.
8054 bool HasByVal = A.hasAttr(IRP, {Attribute::ByVal},
8055 /* IgnoreSubsumingPositions */ true);
8056 getKnownStateFromValue(A, IRP, getState(),
8057 /* IgnoreSubsumingPositions */ HasByVal);
8058 }
8059
8060 ChangeStatus manifest(Attributor &A) override {
8061 // TODO: Pointer arguments are not supported on vectors of pointers yet.
8062 if (!getAssociatedValue().getType()->isPointerTy())
8063 return ChangeStatus::UNCHANGED;
8064
8065 // TODO: From readattrs.ll: "inalloca parameters are always
8066 // considered written"
8067 if (A.hasAttr(getIRPosition(),
8068 {Attribute::InAlloca, Attribute::Preallocated})) {
8069 removeKnownBits(NO_WRITES);
8070 removeAssumedBits(NO_WRITES);
8071 }
8072 A.removeAttrs(getIRPosition(), AttrKinds);
8073 return AAMemoryBehaviorFloating::manifest(A);
8074 }
8075
8076 /// See AbstractAttribute::trackStatistics()
8077 void trackStatistics() const override {
8078 if (isAssumedReadNone())
8079 STATS_DECLTRACK_ARG_ATTR(readnone)
8080 else if (isAssumedReadOnly())
8081 STATS_DECLTRACK_ARG_ATTR(readonly)
8082 else if (isAssumedWriteOnly())
8083 STATS_DECLTRACK_ARG_ATTR(writeonly)
8084 }
8085};
8086
8087struct AAMemoryBehaviorCallSiteArgument final : AAMemoryBehaviorArgument {
8088 AAMemoryBehaviorCallSiteArgument(const IRPosition &IRP, Attributor &A)
8089 : AAMemoryBehaviorArgument(IRP, A) {}
8090
8091 /// See AbstractAttribute::initialize(...).
8092 void initialize(Attributor &A) override {
8093 // If we don't have an associated attribute this is either a variadic call
8094 // or an indirect call, either way, nothing to do here.
8095 Argument *Arg = getAssociatedArgument();
8096 if (!Arg) {
8097 indicatePessimisticFixpoint();
8098 return;
8099 }
8100 if (Arg->hasByValAttr()) {
8101 addKnownBits(NO_WRITES);
8102 removeKnownBits(NO_READS);
8103 removeAssumedBits(NO_READS);
8104 }
8105 AAMemoryBehaviorArgument::initialize(A);
8106 if (getAssociatedFunction()->isDeclaration())
8107 indicatePessimisticFixpoint();
8108 }
8109
8110 /// See AbstractAttribute::updateImpl(...).
8111 ChangeStatus updateImpl(Attributor &A) override {
8112 // TODO: Once we have call site specific value information we can provide
8113 // call site specific liveness liveness information and then it makes
8114 // sense to specialize attributes for call sites arguments instead of
8115 // redirecting requests to the callee argument.
8116 Argument *Arg = getAssociatedArgument();
8117 const IRPosition &ArgPos = IRPosition::argument(*Arg);
8118 auto *ArgAA =
8119 A.getAAFor<AAMemoryBehavior>(*this, ArgPos, DepClassTy::REQUIRED);
8120 if (!ArgAA)
8121 return indicatePessimisticFixpoint();
8122 return clampStateAndIndicateChange(getState(), ArgAA->getState());
8123 }
8124
8125 /// See AbstractAttribute::trackStatistics()
8126 void trackStatistics() const override {
8127 if (isAssumedReadNone())
8129 else if (isAssumedReadOnly())
8131 else if (isAssumedWriteOnly())
8133 }
8134};
8135
8136/// Memory behavior attribute for a call site return position.
8137struct AAMemoryBehaviorCallSiteReturned final : AAMemoryBehaviorFloating {
8138 AAMemoryBehaviorCallSiteReturned(const IRPosition &IRP, Attributor &A)
8139 : AAMemoryBehaviorFloating(IRP, A) {}
8140
8141 /// See AbstractAttribute::initialize(...).
8142 void initialize(Attributor &A) override {
8143 AAMemoryBehaviorImpl::initialize(A);
8144 }
8145 /// See AbstractAttribute::manifest(...).
8146 ChangeStatus manifest(Attributor &A) override {
8147 // We do not annotate returned values.
8148 return ChangeStatus::UNCHANGED;
8149 }
8150
8151 /// See AbstractAttribute::trackStatistics()
8152 void trackStatistics() const override {}
8153};
8154
8155/// An AA to represent the memory behavior function attributes.
8156struct AAMemoryBehaviorFunction final : public AAMemoryBehaviorImpl {
8157 AAMemoryBehaviorFunction(const IRPosition &IRP, Attributor &A)
8158 : AAMemoryBehaviorImpl(IRP, A) {}
8159
8160 /// See AbstractAttribute::updateImpl(Attributor &A).
8161 ChangeStatus updateImpl(Attributor &A) override;
8162
8163 /// See AbstractAttribute::manifest(...).
8164 ChangeStatus manifest(Attributor &A) override {
8165 // TODO: It would be better to merge this with AAMemoryLocation, so that
8166 // we could determine read/write per location. This would also have the
8167 // benefit of only one place trying to manifest the memory attribute.
8168 Function &F = cast<Function>(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 (Argument &Arg : F.args())
8181 A.removeAttrs(IRPosition::argument(Arg), Attribute::Writable);
8182 return A.manifestAttrs(getIRPosition(),
8183 Attribute::getWithMemoryEffects(F.getContext(), ME));
8184 }
8185
8186 /// See AbstractAttribute::trackStatistics()
8187 void trackStatistics() const override {
8188 if (isAssumedReadNone())
8189 STATS_DECLTRACK_FN_ATTR(readnone)
8190 else if (isAssumedReadOnly())
8191 STATS_DECLTRACK_FN_ATTR(readonly)
8192 else if (isAssumedWriteOnly())
8193 STATS_DECLTRACK_FN_ATTR(writeonly)
8194 }
8195};
8196
8197/// AAMemoryBehavior attribute for call sites.
8198struct AAMemoryBehaviorCallSite final
8199 : AACalleeToCallSite<AAMemoryBehavior, AAMemoryBehaviorImpl> {
8200 AAMemoryBehaviorCallSite(const IRPosition &IRP, Attributor &A)
8201 : AACalleeToCallSite<AAMemoryBehavior, AAMemoryBehaviorImpl>(IRP, A) {}
8202
8203 /// See AbstractAttribute::manifest(...).
8204 ChangeStatus manifest(Attributor &A) override {
8205 // TODO: Deduplicate this with AAMemoryBehaviorFunction.
8206 CallBase &CB = cast<CallBase>(getAnchorValue());
8208 if (isAssumedReadNone())
8209 ME = MemoryEffects::none();
8210 else if (isAssumedReadOnly())
8212 else if (isAssumedWriteOnly())
8214
8215 A.removeAttrs(getIRPosition(), AttrKinds);
8216 // Clear conflicting writable attribute.
8217 if (ME.onlyReadsMemory())
8218 for (Use &U : CB.args())
8219 A.removeAttrs(IRPosition::callsite_argument(CB, U.getOperandNo()),
8220 Attribute::Writable);
8221 return A.manifestAttrs(
8222 getIRPosition(), Attribute::getWithMemoryEffects(CB.getContext(), ME));
8223 }
8224
8225 /// See AbstractAttribute::trackStatistics()
8226 void trackStatistics() const override {
8227 if (isAssumedReadNone())
8228 STATS_DECLTRACK_CS_ATTR(readnone)
8229 else if (isAssumedReadOnly())
8230 STATS_DECLTRACK_CS_ATTR(readonly)
8231 else if (isAssumedWriteOnly())
8232 STATS_DECLTRACK_CS_ATTR(writeonly)
8233 }
8234};
8235
8236ChangeStatus AAMemoryBehaviorFunction::updateImpl(Attributor &A) {
8237
8238 // The current assumed state used to determine a change.
8239 auto AssumedState = getAssumed();
8240
8241 auto CheckRWInst = [&](Instruction &I) {
8242 // If the instruction has an own memory behavior state, use it to restrict
8243 // the local state. No further analysis is required as the other memory
8244 // state is as optimistic as it gets.
8245 if (const auto *CB = dyn_cast<CallBase>(&I)) {
8246 const auto *MemBehaviorAA = A.getAAFor<AAMemoryBehavior>(
8248 if (MemBehaviorAA) {
8249 intersectAssumedBits(MemBehaviorAA->getAssumed());
8250 return !isAtFixpoint();
8251 }
8252 }
8253
8254 // Remove access kind modifiers if necessary.
8255 if (I.mayReadFromMemory())
8256 removeAssumedBits(NO_READS);
8257 if (I.mayWriteToMemory())
8258 removeAssumedBits(NO_WRITES);
8259 return !isAtFixpoint();
8260 };
8261
8262 bool UsedAssumedInformation = false;
8263 if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this,
8264 UsedAssumedInformation))
8265 return indicatePessimisticFixpoint();
8266
8267 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
8269}
8270
8271ChangeStatus AAMemoryBehaviorFloating::updateImpl(Attributor &A) {
8272
8273 const IRPosition &IRP = getIRPosition();
8274 const IRPosition &FnPos = IRPosition::function_scope(IRP);
8275 AAMemoryBehavior::StateType &S = getState();
8276
8277 // First, check the function scope. We take the known information and we avoid
8278 // work if the assumed information implies the current assumed information for
8279 // this attribute. This is a valid for all but byval arguments.
8280 Argument *Arg = IRP.getAssociatedArgument();
8281 AAMemoryBehavior::base_t FnMemAssumedState =
8283 if (!Arg || !Arg->hasByValAttr()) {
8284 const auto *FnMemAA =
8285 A.getAAFor<AAMemoryBehavior>(*this, FnPos, DepClassTy::OPTIONAL);
8286 if (FnMemAA) {
8287 FnMemAssumedState = FnMemAA->getAssumed();
8288 S.addKnownBits(FnMemAA->getKnown());
8289 if ((S.getAssumed() & FnMemAA->getAssumed()) == S.getAssumed())
8291 }
8292 }
8293
8294 // The current assumed state used to determine a change.
8295 auto AssumedState = S.getAssumed();
8296
8297 // Make sure the value is not captured (except through "return"), if
8298 // it is, any information derived would be irrelevant anyway as we cannot
8299 // check the potential aliases introduced by the capture. However, no need
8300 // to fall back to anythign less optimistic than the function state.
8301 bool IsKnownNoCapture;
8302 const AANoCapture *ArgNoCaptureAA = nullptr;
8303 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
8304 A, this, IRP, DepClassTy::OPTIONAL, IsKnownNoCapture, false,
8305 &ArgNoCaptureAA);
8306
8307 if (!IsAssumedNoCapture &&
8308 (!ArgNoCaptureAA || !ArgNoCaptureAA->isAssumedNoCaptureMaybeReturned())) {
8309 S.intersectAssumedBits(FnMemAssumedState);
8310 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
8312 }
8313
8314 // Visit and expand uses until all are analyzed or a fixpoint is reached.
8315 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
8316 Instruction *UserI = cast<Instruction>(U.getUser());
8317 LLVM_DEBUG(dbgs() << "[AAMemoryBehavior] Use: " << *U << " in " << *UserI
8318 << " \n");
8319
8320 // Droppable users, e.g., llvm::assume does not actually perform any action.
8321 if (UserI->isDroppable())
8322 return true;
8323
8324 // Check if the users of UserI should also be visited.
8325 Follow = followUsersOfUseIn(A, U, UserI);
8326
8327 // If UserI might touch memory we analyze the use in detail.
8328 if (UserI->mayReadOrWriteMemory())
8329 analyzeUseIn(A, U, UserI);
8330
8331 return !isAtFixpoint();
8332 };
8333
8334 if (!A.checkForAllUses(UsePred, *this, getAssociatedValue()))
8335 return indicatePessimisticFixpoint();
8336
8337 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
8339}
8340
8341bool AAMemoryBehaviorFloating::followUsersOfUseIn(Attributor &A, const Use &U,
8342 const Instruction *UserI) {
8343 // The loaded value is unrelated to the pointer argument, no need to
8344 // follow the users of the load.
8345 if (isa<LoadInst>(UserI) || isa<ReturnInst>(UserI))
8346 return false;
8347
8348 // By default we follow all uses assuming UserI might leak information on U,
8349 // we have special handling for call sites operands though.
8350 const auto *CB = dyn_cast<CallBase>(UserI);
8351 if (!CB || !CB->isArgOperand(&U))
8352 return true;
8353
8354 // If the use is a call argument known not to be captured, the users of
8355 // the call do not need to be visited because they have to be unrelated to
8356 // the input. Note that this check is not trivial even though we disallow
8357 // general capturing of the underlying argument. The reason is that the
8358 // call might the argument "through return", which we allow and for which we
8359 // need to check call users.
8360 if (U.get()->getType()->isPointerTy()) {
8361 unsigned ArgNo = CB->getArgOperandNo(&U);
8362 bool IsKnownNoCapture;
8364 A, this, IRPosition::callsite_argument(*CB, ArgNo),
8365 DepClassTy::OPTIONAL, IsKnownNoCapture);
8366 }
8367
8368 return true;
8369}
8370
8371void AAMemoryBehaviorFloating::analyzeUseIn(Attributor &A, const Use &U,
8372 const Instruction *UserI) {
8373 assert(UserI->mayReadOrWriteMemory());
8374
8375 switch (UserI->getOpcode()) {
8376 default:
8377 // TODO: Handle all atomics and other side-effect operations we know of.
8378 break;
8379 case Instruction::Load:
8380 // Loads cause the NO_READS property to disappear.
8381 removeAssumedBits(NO_READS);
8382 return;
8383
8384 case Instruction::Store:
8385 // Stores cause the NO_WRITES property to disappear if the use is the
8386 // pointer operand. Note that while capturing was taken care of somewhere
8387 // else we need to deal with stores of the value that is not looked through.
8388 if (cast<StoreInst>(UserI)->getPointerOperand() == U.get())
8389 removeAssumedBits(NO_WRITES);
8390 else
8391 indicatePessimisticFixpoint();
8392 return;
8393
8394 case Instruction::Call:
8395 case Instruction::CallBr:
8396 case Instruction::Invoke: {
8397 // For call sites we look at the argument memory behavior attribute (this
8398 // could be recursive!) in order to restrict our own state.
8399 const auto *CB = cast<CallBase>(UserI);
8400
8401 // Give up on operand bundles.
8402 if (CB->isBundleOperand(&U)) {
8403 indicatePessimisticFixpoint();
8404 return;
8405 }
8406
8407 // Calling a function does read the function pointer, maybe write it if the
8408 // function is self-modifying.
8409 if (CB->isCallee(&U)) {
8410 removeAssumedBits(NO_READS);
8411 break;
8412 }
8413
8414 // Adjust the possible access behavior based on the information on the
8415 // argument.
8416 IRPosition Pos;
8417 if (U.get()->getType()->isPointerTy())
8419 else
8421 const auto *MemBehaviorAA =
8422 A.getAAFor<AAMemoryBehavior>(*this, Pos, DepClassTy::OPTIONAL);
8423 if (!MemBehaviorAA)
8424 break;
8425 // "assumed" has at most the same bits as the MemBehaviorAA assumed
8426 // and at least "known".
8427 intersectAssumedBits(MemBehaviorAA->getAssumed());
8428 return;
8429 }
8430 };
8431
8432 // Generally, look at the "may-properties" and adjust the assumed state if we
8433 // did not trigger special handling before.
8434 if (UserI->mayReadFromMemory())
8435 removeAssumedBits(NO_READS);
8436 if (UserI->mayWriteToMemory())
8437 removeAssumedBits(NO_WRITES);
8438}
8439} // namespace
8440
8441/// -------------------- Memory Locations Attributes ---------------------------
8442/// Includes read-none, argmemonly, inaccessiblememonly,
8443/// inaccessiblememorargmemonly
8444/// ----------------------------------------------------------------------------
8445
8448 if (0 == (MLK & AAMemoryLocation::NO_LOCATIONS))
8449 return "all memory";
8451 return "no memory";
8452 std::string S = "memory:";
8453 if (0 == (MLK & AAMemoryLocation::NO_LOCAL_MEM))
8454 S += "stack,";
8455 if (0 == (MLK & AAMemoryLocation::NO_CONST_MEM))
8456 S += "constant,";
8458 S += "internal global,";
8460 S += "external global,";
8461 if (0 == (MLK & AAMemoryLocation::NO_ARGUMENT_MEM))
8462 S += "argument,";
8464 S += "inaccessible,";
8465 if (0 == (MLK & AAMemoryLocation::NO_MALLOCED_MEM))
8466 S += "malloced,";
8467 if (0 == (MLK & AAMemoryLocation::NO_UNKOWN_MEM))
8468 S += "unknown,";
8469 S.pop_back();
8470 return S;
8471}
8472
8473namespace {
8474struct AAMemoryLocationImpl : public AAMemoryLocation {
8475
8476 AAMemoryLocationImpl(const IRPosition &IRP, Attributor &A)
8477 : AAMemoryLocation(IRP, A), Allocator(A.Allocator) {
8478 AccessKind2Accesses.fill(nullptr);
8479 }
8480
8481 ~AAMemoryLocationImpl() override {
8482 // The AccessSets are allocated via a BumpPtrAllocator, we call
8483 // the destructor manually.
8484 for (AccessSet *AS : AccessKind2Accesses)
8485 if (AS)
8486 AS->~AccessSet();
8487 }
8488
8489 /// See AbstractAttribute::initialize(...).
8490 void initialize(Attributor &A) override {
8491 intersectAssumedBits(BEST_STATE);
8492 getKnownStateFromValue(A, getIRPosition(), getState());
8493 AAMemoryLocation::initialize(A);
8494 }
8495
8496 /// Return the memory behavior information encoded in the IR for \p IRP.
8497 static void getKnownStateFromValue(Attributor &A, const IRPosition &IRP,
8498 BitIntegerState &State,
8499 bool IgnoreSubsumingPositions = false) {
8500 // For internal functions we ignore `argmemonly` and
8501 // `inaccessiblememorargmemonly` as we might break it via interprocedural
8502 // constant propagation. It is unclear if this is the best way but it is
8503 // unlikely this will cause real performance problems. If we are deriving
8504 // attributes for the anchor function we even remove the attribute in
8505 // addition to ignoring it.
8506 // TODO: A better way to handle this would be to add ~NO_GLOBAL_MEM /
8507 // MemoryEffects::Other as a possible location.
8508 bool UseArgMemOnly = true;
8509 Function *AnchorFn = IRP.getAnchorScope();
8510 if (AnchorFn && A.isRunOn(*AnchorFn))
8511 UseArgMemOnly = !AnchorFn->hasLocalLinkage();
8512
8514 A.getAttrs(IRP, {Attribute::Memory}, Attrs, IgnoreSubsumingPositions);
8515 for (const Attribute &Attr : Attrs) {
8516 // TODO: We can map MemoryEffects to Attributor locations more precisely.
8517 MemoryEffects ME = Attr.getMemoryEffects();
8518 if (ME.doesNotAccessMemory()) {
8519 State.addKnownBits(NO_LOCAL_MEM | NO_CONST_MEM);
8520 continue;
8521 }
8522 if (ME.onlyAccessesInaccessibleMem()) {
8523 State.addKnownBits(inverseLocation(NO_INACCESSIBLE_MEM, true, true));
8524 continue;
8525 }
8526 if (ME.onlyAccessesArgPointees()) {
8527 if (UseArgMemOnly)
8528 State.addKnownBits(inverseLocation(NO_ARGUMENT_MEM, true, true));
8529 else {
8530 // Remove location information, only keep read/write info.
8531 ME = MemoryEffects(ME.getModRef());
8532 A.manifestAttrs(IRP,
8533 Attribute::getWithMemoryEffects(
8534 IRP.getAnchorValue().getContext(), ME),
8535 /*ForceReplace*/ true);
8536 }
8537 continue;
8538 }
8540 if (UseArgMemOnly)
8541 State.addKnownBits(inverseLocation(
8542 NO_INACCESSIBLE_MEM | NO_ARGUMENT_MEM, true, true));
8543 else {
8544 // Remove location information, only keep read/write info.
8545 ME = MemoryEffects(ME.getModRef());
8546 A.manifestAttrs(IRP,
8547 Attribute::getWithMemoryEffects(
8548 IRP.getAnchorValue().getContext(), ME),
8549 /*ForceReplace*/ true);
8550 }
8551 continue;
8552 }
8553 }
8554 }
8555
8556 /// See AbstractAttribute::getDeducedAttributes(...).
8557 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
8558 SmallVectorImpl<Attribute> &Attrs) const override {
8559 // TODO: We can map Attributor locations to MemoryEffects more precisely.
8560 assert(Attrs.size() == 0);
8561 if (getIRPosition().getPositionKind() == IRPosition::IRP_FUNCTION) {
8562 if (isAssumedReadNone())
8563 Attrs.push_back(
8564 Attribute::getWithMemoryEffects(Ctx, MemoryEffects::none()));
8565 else if (isAssumedInaccessibleMemOnly())
8566 Attrs.push_back(Attribute::getWithMemoryEffects(
8568 else if (isAssumedArgMemOnly())
8569 Attrs.push_back(
8570 Attribute::getWithMemoryEffects(Ctx, MemoryEffects::argMemOnly()));
8571 else if (isAssumedInaccessibleOrArgMemOnly())
8572 Attrs.push_back(Attribute::getWithMemoryEffects(
8574 }
8575 assert(Attrs.size() <= 1);
8576 }
8577
8578 /// See AbstractAttribute::manifest(...).
8579 ChangeStatus manifest(Attributor &A) override {
8580 // TODO: If AAMemoryLocation and AAMemoryBehavior are merged, we could
8581 // provide per-location modref information here.
8582 const IRPosition &IRP = getIRPosition();
8583
8584 SmallVector<Attribute, 1> DeducedAttrs;
8585 getDeducedAttributes(A, IRP.getAnchorValue().getContext(), DeducedAttrs);
8586 if (DeducedAttrs.size() != 1)
8587 return ChangeStatus::UNCHANGED;
8588 MemoryEffects ME = DeducedAttrs[0].getMemoryEffects();
8589
8590 return A.manifestAttrs(IRP, Attribute::getWithMemoryEffects(
8591 IRP.getAnchorValue().getContext(), ME));
8592 }
8593
8594 /// See AAMemoryLocation::checkForAllAccessesToMemoryKind(...).
8595 bool checkForAllAccessesToMemoryKind(
8596 function_ref<bool(const Instruction *, const Value *, AccessKind,
8597 MemoryLocationsKind)>
8598 Pred,
8599 MemoryLocationsKind RequestedMLK) const override {
8600 if (!isValidState())
8601 return false;
8602
8603 MemoryLocationsKind AssumedMLK = getAssumedNotAccessedLocation();
8604 if (AssumedMLK == NO_LOCATIONS)
8605 return true;
8606
8607 unsigned Idx = 0;
8608 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS;
8609 CurMLK *= 2, ++Idx) {
8610 if (CurMLK & RequestedMLK)
8611 continue;
8612
8613 if (const AccessSet *Accesses = AccessKind2Accesses[Idx])
8614 for (const AccessInfo &AI : *Accesses)
8615 if (!Pred(AI.I, AI.Ptr, AI.Kind, CurMLK))
8616 return false;
8617 }
8618
8619 return true;
8620 }
8621
8622 ChangeStatus indicatePessimisticFixpoint() override {
8623 // If we give up and indicate a pessimistic fixpoint this instruction will
8624 // become an access for all potential access kinds:
8625 // TODO: Add pointers for argmemonly and globals to improve the results of
8626 // checkForAllAccessesToMemoryKind.
8627 bool Changed = false;
8628 MemoryLocationsKind KnownMLK = getKnown();
8629 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
8630 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS; CurMLK *= 2)
8631 if (!(CurMLK & KnownMLK))
8632 updateStateAndAccessesMap(getState(), CurMLK, I, nullptr, Changed,
8633 getAccessKindFromInst(I));
8634 return AAMemoryLocation::indicatePessimisticFixpoint();
8635 }
8636
8637protected:
8638 /// Helper struct to tie together an instruction that has a read or write
8639 /// effect with the pointer it accesses (if any).
8640 struct AccessInfo {
8641
8642 /// The instruction that caused the access.
8643 const Instruction *I;
8644
8645 /// The base pointer that is accessed, or null if unknown.
8646 const Value *Ptr;
8647
8648 /// The kind of access (read/write/read+write).
8650
8651 bool operator==(const AccessInfo &RHS) const {
8652 return I == RHS.I && Ptr == RHS.Ptr && Kind == RHS.Kind;
8653 }
8654 bool operator()(const AccessInfo &LHS, const AccessInfo &RHS) const {
8655 if (LHS.I != RHS.I)
8656 return LHS.I < RHS.I;
8657 if (LHS.Ptr != RHS.Ptr)
8658 return LHS.Ptr < RHS.Ptr;
8659 if (LHS.Kind != RHS.Kind)
8660 return LHS.Kind < RHS.Kind;
8661 return false;
8662 }
8663 };
8664
8665 /// Mapping from *single* memory location kinds, e.g., LOCAL_MEM with the
8666 /// value of NO_LOCAL_MEM, to the accesses encountered for this memory kind.
8667 using AccessSet = SmallSet<AccessInfo, 2, AccessInfo>;
8668 std::array<AccessSet *, llvm::ConstantLog2<VALID_STATE>()>
8669 AccessKind2Accesses;
8670
8671 /// Categorize the pointer arguments of CB that might access memory in
8672 /// AccessedLoc and update the state and access map accordingly.
8673 void
8674 categorizeArgumentPointerLocations(Attributor &A, CallBase &CB,
8675 AAMemoryLocation::StateType &AccessedLocs,
8676 bool &Changed);
8677
8678 /// Return the kind(s) of location that may be accessed by \p V.
8680 categorizeAccessedLocations(Attributor &A, Instruction &I, bool &Changed);
8681
8682 /// Return the access kind as determined by \p I.
8683 AccessKind getAccessKindFromInst(const Instruction *I) {
8684 AccessKind AK = READ_WRITE;
8685 if (I) {
8686 AK = I->mayReadFromMemory() ? READ : NONE;
8687 AK = AccessKind(AK | (I->mayWriteToMemory() ? WRITE : NONE));
8688 }
8689 return AK;
8690 }
8691
8692 /// Update the state \p State and the AccessKind2Accesses given that \p I is
8693 /// an access of kind \p AK to a \p MLK memory location with the access
8694 /// pointer \p Ptr.
8695 void updateStateAndAccessesMap(AAMemoryLocation::StateType &State,
8696 MemoryLocationsKind MLK, const Instruction *I,
8697 const Value *Ptr, bool &Changed,
8698 AccessKind AK = READ_WRITE) {
8699
8700 assert(isPowerOf2_32(MLK) && "Expected a single location set!");
8701 auto *&Accesses = AccessKind2Accesses[llvm::Log2_32(MLK)];
8702 if (!Accesses)
8703 Accesses = new (Allocator) AccessSet();
8704 Changed |= Accesses->insert(AccessInfo{I, Ptr, AK}).second;
8705 if (MLK == NO_UNKOWN_MEM)
8706 MLK = NO_LOCATIONS;
8707 State.removeAssumedBits(MLK);
8708 }
8709
8710 /// Determine the underlying locations kinds for \p Ptr, e.g., globals or
8711 /// arguments, and update the state and access map accordingly.
8712 void categorizePtrValue(Attributor &A, const Instruction &I, const Value &Ptr,
8713 AAMemoryLocation::StateType &State, bool &Changed,
8714 unsigned AccessAS = 0);
8715
8716 /// Used to allocate access sets.
8718};
8719
8720void AAMemoryLocationImpl::categorizePtrValue(
8721 Attributor &A, const Instruction &I, const Value &Ptr,
8722 AAMemoryLocation::StateType &State, bool &Changed, unsigned AccessAS) {
8723 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize pointer locations for "
8724 << Ptr << " ["
8725 << getMemoryLocationsAsStr(State.getAssumed()) << "]\n");
8726
8727 auto Pred = [&](Value &Obj) {
8728 unsigned ObjectAS = Obj.getType()->getPointerAddressSpace();
8729 // TODO: recognize the TBAA used for constant accesses.
8730 MemoryLocationsKind MLK = NO_LOCATIONS;
8731
8732 // Filter accesses to constant (GPU) memory if we have an AS at the access
8733 // site or the object is known to actually have the associated AS.
8734 if (AA::isGPU(A.getModule())) {
8735 if (AA::isGPUConstantAddressSpace(A.getModule(), AccessAS) ||
8736 (AA::isGPUConstantAddressSpace(A.getModule(), ObjectAS) &&
8737 isIdentifiedObject(&Obj)))
8738 return true;
8739 }
8740
8741 if (isa<UndefValue>(&Obj))
8742 return true;
8743 if (isa<Argument>(&Obj)) {
8744 // TODO: For now we do not treat byval arguments as local copies performed
8745 // on the call edge, though, we should. To make that happen we need to
8746 // teach various passes, e.g., DSE, about the copy effect of a byval. That
8747 // would also allow us to mark functions only accessing byval arguments as
8748 // readnone again, arguably their accesses have no effect outside of the
8749 // function, like accesses to allocas.
8750 MLK = NO_ARGUMENT_MEM;
8751 } else if (auto *GV = dyn_cast<GlobalValue>(&Obj)) {
8752 // Reading constant memory is not treated as a read "effect" by the
8753 // function attr pass so we won't neither. Constants defined by TBAA are
8754 // similar. (We know we do not write it because it is constant.)
8755 if (auto *GVar = dyn_cast<GlobalVariable>(GV))
8756 if (GVar->isConstant())
8757 return true;
8758
8759 if (GV->hasLocalLinkage())
8760 MLK = NO_GLOBAL_INTERNAL_MEM;
8761 else
8762 MLK = NO_GLOBAL_EXTERNAL_MEM;
8763 } else if (isa<ConstantPointerNull>(&Obj) &&
8764 (!NullPointerIsDefined(getAssociatedFunction(), AccessAS) ||
8765 !NullPointerIsDefined(getAssociatedFunction(), ObjectAS))) {
8766 return true;
8767 } else if (isa<AllocaInst>(&Obj)) {
8768 MLK = NO_LOCAL_MEM;
8769 } else if (const auto *CB = dyn_cast<CallBase>(&Obj)) {
8770 bool IsKnownNoAlias;
8773 IsKnownNoAlias))
8774 MLK = NO_MALLOCED_MEM;
8775 else
8776 MLK = NO_UNKOWN_MEM;
8777 } else {
8778 MLK = NO_UNKOWN_MEM;
8779 }
8780
8781 assert(MLK != NO_LOCATIONS && "No location specified!");
8782 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Ptr value can be categorized: "
8783 << Obj << " -> " << getMemoryLocationsAsStr(MLK) << "\n");
8784 updateStateAndAccessesMap(State, MLK, &I, &Obj, Changed,
8785 getAccessKindFromInst(&I));
8786
8787 return true;
8788 };
8789
8790 const auto *AA = A.getAAFor<AAUnderlyingObjects>(
8792 if (!AA || !AA->forallUnderlyingObjects(Pred, AA::Intraprocedural)) {
8793 LLVM_DEBUG(
8794 dbgs() << "[AAMemoryLocation] Pointer locations not categorized\n");
8795 updateStateAndAccessesMap(State, NO_UNKOWN_MEM, &I, nullptr, Changed,
8796 getAccessKindFromInst(&I));
8797 return;
8798 }
8799
8800 LLVM_DEBUG(
8801 dbgs() << "[AAMemoryLocation] Accessed locations with pointer locations: "
8802 << getMemoryLocationsAsStr(State.getAssumed()) << "\n");
8803}
8804
8805void AAMemoryLocationImpl::categorizeArgumentPointerLocations(
8806 Attributor &A, CallBase &CB, AAMemoryLocation::StateType &AccessedLocs,
8807 bool &Changed) {
8808 for (unsigned ArgNo = 0, E = CB.arg_size(); ArgNo < E; ++ArgNo) {
8809
8810 // Skip non-pointer arguments.
8811 const Value *ArgOp = CB.getArgOperand(ArgNo);
8812 if (!ArgOp->getType()->isPtrOrPtrVectorTy())
8813 continue;
8814
8815 // Skip readnone arguments.
8816 const IRPosition &ArgOpIRP = IRPosition::callsite_argument(CB, ArgNo);
8817 const auto *ArgOpMemLocationAA =
8818 A.getAAFor<AAMemoryBehavior>(*this, ArgOpIRP, DepClassTy::OPTIONAL);
8819
8820 if (ArgOpMemLocationAA && ArgOpMemLocationAA->isAssumedReadNone())
8821 continue;
8822
8823 // Categorize potentially accessed pointer arguments as if there was an
8824 // access instruction with them as pointer.
8825 categorizePtrValue(A, CB, *ArgOp, AccessedLocs, Changed);
8826 }
8827}
8828
8830AAMemoryLocationImpl::categorizeAccessedLocations(Attributor &A, Instruction &I,
8831 bool &Changed) {
8832 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize accessed locations for "
8833 << I << "\n");
8834
8835 AAMemoryLocation::StateType AccessedLocs;
8836 AccessedLocs.intersectAssumedBits(NO_LOCATIONS);
8837
8838 if (auto *CB = dyn_cast<CallBase>(&I)) {
8839
8840 // First check if we assume any memory is access is visible.
8841 const auto *CBMemLocationAA = A.getAAFor<AAMemoryLocation>(
8843 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize call site: " << I
8844 << " [" << CBMemLocationAA << "]\n");
8845 if (!CBMemLocationAA) {
8846 updateStateAndAccessesMap(AccessedLocs, NO_UNKOWN_MEM, &I, nullptr,
8847 Changed, getAccessKindFromInst(&I));
8848 return NO_UNKOWN_MEM;
8849 }
8850
8851 if (CBMemLocationAA->isAssumedReadNone())
8852 return NO_LOCATIONS;
8853
8854 if (CBMemLocationAA->isAssumedInaccessibleMemOnly()) {
8855 updateStateAndAccessesMap(AccessedLocs, NO_INACCESSIBLE_MEM, &I, nullptr,
8856 Changed, getAccessKindFromInst(&I));
8857 return AccessedLocs.getAssumed();
8858 }
8859
8860 uint32_t CBAssumedNotAccessedLocs =
8861 CBMemLocationAA->getAssumedNotAccessedLocation();
8862
8863 // Set the argmemonly and global bit as we handle them separately below.
8864 uint32_t CBAssumedNotAccessedLocsNoArgMem =
8865 CBAssumedNotAccessedLocs | NO_ARGUMENT_MEM | NO_GLOBAL_MEM;
8866
8867 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS; CurMLK *= 2) {
8868 if (CBAssumedNotAccessedLocsNoArgMem & CurMLK)
8869 continue;
8870 updateStateAndAccessesMap(AccessedLocs, CurMLK, &I, nullptr, Changed,
8871 getAccessKindFromInst(&I));
8872 }
8873
8874 // Now handle global memory if it might be accessed. This is slightly tricky
8875 // as NO_GLOBAL_MEM has multiple bits set.
8876 bool HasGlobalAccesses = ((~CBAssumedNotAccessedLocs) & NO_GLOBAL_MEM);
8877 if (HasGlobalAccesses) {
8878 auto AccessPred = [&](const Instruction *, const Value *Ptr,
8879 AccessKind Kind, MemoryLocationsKind MLK) {
8880 updateStateAndAccessesMap(AccessedLocs, MLK, &I, Ptr, Changed,
8881 getAccessKindFromInst(&I));
8882 return true;
8883 };
8884 if (!CBMemLocationAA->checkForAllAccessesToMemoryKind(
8885 AccessPred, inverseLocation(NO_GLOBAL_MEM, false, false)))
8886 return AccessedLocs.getWorstState();
8887 }
8888
8889 LLVM_DEBUG(
8890 dbgs() << "[AAMemoryLocation] Accessed state before argument handling: "
8891 << getMemoryLocationsAsStr(AccessedLocs.getAssumed()) << "\n");
8892
8893 // Now handle argument memory if it might be accessed.
8894 bool HasArgAccesses = ((~CBAssumedNotAccessedLocs) & NO_ARGUMENT_MEM);
8895 if (HasArgAccesses)
8896 categorizeArgumentPointerLocations(A, *CB, AccessedLocs, Changed);
8897
8898 LLVM_DEBUG(
8899 dbgs() << "[AAMemoryLocation] Accessed state after argument handling: "
8900 << getMemoryLocationsAsStr(AccessedLocs.getAssumed()) << "\n");
8901
8902 return AccessedLocs.getAssumed();
8903 }
8904
8905 if (const Value *Ptr = getPointerOperand(&I, /* AllowVolatile */ true)) {
8906 LLVM_DEBUG(
8907 dbgs() << "[AAMemoryLocation] Categorize memory access with pointer: "
8908 << I << " [" << *Ptr << "]\n");
8909 categorizePtrValue(A, I, *Ptr, AccessedLocs, Changed,
8910 Ptr->getType()->getPointerAddressSpace());
8911 return AccessedLocs.getAssumed();
8912 }
8913
8914 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Failed to categorize instruction: "
8915 << I << "\n");
8916 updateStateAndAccessesMap(AccessedLocs, NO_UNKOWN_MEM, &I, nullptr, Changed,
8917 getAccessKindFromInst(&I));
8918 return AccessedLocs.getAssumed();
8919}
8920
8921/// An AA to represent the memory behavior function attributes.
8922struct AAMemoryLocationFunction final : public AAMemoryLocationImpl {
8923 AAMemoryLocationFunction(const IRPosition &IRP, Attributor &A)
8924 : AAMemoryLocationImpl(IRP, A) {}
8925
8926 /// See AbstractAttribute::updateImpl(Attributor &A).
8927 ChangeStatus updateImpl(Attributor &A) override {
8928
8929 const auto *MemBehaviorAA =
8930 A.getAAFor<AAMemoryBehavior>(*this, getIRPosition(), DepClassTy::NONE);
8931 if (MemBehaviorAA && MemBehaviorAA->isAssumedReadNone()) {
8932 if (MemBehaviorAA->isKnownReadNone())
8933 return indicateOptimisticFixpoint();
8935 "AAMemoryLocation was not read-none but AAMemoryBehavior was!");
8936 A.recordDependence(*MemBehaviorAA, *this, DepClassTy::OPTIONAL);
8937 return ChangeStatus::UNCHANGED;
8938 }
8939
8940 // The current assumed state used to determine a change.
8941 auto AssumedState = getAssumed();
8942 bool Changed = false;
8943
8944 auto CheckRWInst = [&](Instruction &I) {
8945 MemoryLocationsKind MLK = categorizeAccessedLocations(A, I, Changed);
8946 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Accessed locations for " << I
8947 << ": " << getMemoryLocationsAsStr(MLK) << "\n");
8948 removeAssumedBits(inverseLocation(MLK, false, false));
8949 // Stop once only the valid bit set in the *not assumed location*, thus
8950 // once we don't actually exclude any memory locations in the state.
8951 return getAssumedNotAccessedLocation() != VALID_STATE;
8952 };
8953
8954 bool UsedAssumedInformation = false;
8955 if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this,
8956 UsedAssumedInformation))
8957 return indicatePessimisticFixpoint();
8958
8959 Changed |= AssumedState != getAssumed();
8960 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
8961 }
8962
8963 /// See AbstractAttribute::trackStatistics()
8964 void trackStatistics() const override {
8965 if (isAssumedReadNone())
8966 STATS_DECLTRACK_FN_ATTR(readnone)
8967 else if (isAssumedArgMemOnly())
8968 STATS_DECLTRACK_FN_ATTR(argmemonly)
8969 else if (isAssumedInaccessibleMemOnly())
8970 STATS_DECLTRACK_FN_ATTR(inaccessiblememonly)
8971 else if (isAssumedInaccessibleOrArgMemOnly())
8972 STATS_DECLTRACK_FN_ATTR(inaccessiblememorargmemonly)
8973 }
8974};
8975
8976/// AAMemoryLocation attribute for call sites.
8977struct AAMemoryLocationCallSite final : AAMemoryLocationImpl {
8978 AAMemoryLocationCallSite(const IRPosition &IRP, Attributor &A)
8979 : AAMemoryLocationImpl(IRP, A) {}
8980
8981 /// See AbstractAttribute::updateImpl(...).
8982 ChangeStatus updateImpl(Attributor &A) override {
8983 // TODO: Once we have call site specific value information we can provide
8984 // call site specific liveness liveness information and then it makes
8985 // sense to specialize attributes for call sites arguments instead of
8986 // redirecting requests to the callee argument.
8987 Function *F = getAssociatedFunction();
8988 const IRPosition &FnPos = IRPosition::function(*F);
8989 auto *FnAA =
8990 A.getAAFor<AAMemoryLocation>(*this, FnPos, DepClassTy::REQUIRED);
8991 if (!FnAA)
8992 return indicatePessimisticFixpoint();
8993 bool Changed = false;
8994 auto AccessPred = [&](const Instruction *I, const Value *Ptr,
8995 AccessKind Kind, MemoryLocationsKind MLK) {
8996 updateStateAndAccessesMap(getState(), MLK, I, Ptr, Changed,
8997 getAccessKindFromInst(I));
8998 return true;
8999 };
9000 if (!FnAA->checkForAllAccessesToMemoryKind(AccessPred, ALL_LOCATIONS))
9001 return indicatePessimisticFixpoint();
9002 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
9003 }
9004
9005 /// See AbstractAttribute::trackStatistics()
9006 void trackStatistics() const override {
9007 if (isAssumedReadNone())
9008 STATS_DECLTRACK_CS_ATTR(readnone)
9009 }
9010};
9011} // namespace
9012
9013/// ------------------ denormal-fp-math Attribute -------------------------
9014
9015namespace {
9016struct AADenormalFPMathImpl : public AADenormalFPMath {
9017 AADenormalFPMathImpl(const IRPosition &IRP, Attributor &A)
9018 : AADenormalFPMath(IRP, A) {}
9019
9020 const std::string getAsStr(Attributor *A) const override {
9021 std::string Str("AADenormalFPMath[");
9022 raw_string_ostream OS(Str);
9023
9024 DenormalState Known = getKnown();
9025 if (Known.Mode.isValid())
9026 OS << "denormal-fp-math=" << Known.Mode;
9027 else
9028 OS << "invalid";
9029
9030 if (Known.ModeF32.isValid())
9031 OS << " denormal-fp-math-f32=" << Known.ModeF32;
9032 OS << ']';
9033 return Str;
9034 }
9035};
9036
9037struct AADenormalFPMathFunction final : AADenormalFPMathImpl {
9038 AADenormalFPMathFunction(const IRPosition &IRP, Attributor &A)
9039 : AADenormalFPMathImpl(IRP, A) {}
9040
9041 void initialize(Attributor &A) override {
9042 const Function *F = getAnchorScope();
9043 DenormalFPEnv DenormEnv = F->getDenormalFPEnv();
9044
9045 Known = DenormalState{DenormEnv.DefaultMode, DenormEnv.F32Mode};
9046 if (isModeFixed())
9047 indicateFixpoint();
9048 }
9049
9050 ChangeStatus updateImpl(Attributor &A) override {
9051 ChangeStatus Change = ChangeStatus::UNCHANGED;
9052
9053 auto CheckCallSite = [=, &Change, &A](AbstractCallSite CS) {
9054 Function *Caller = CS.getInstruction()->getFunction();
9055 LLVM_DEBUG(dbgs() << "[AADenormalFPMath] Call " << Caller->getName()
9056 << "->" << getAssociatedFunction()->getName() << '\n');
9057
9058 const auto *CallerInfo = A.getAAFor<AADenormalFPMath>(
9059 *this, IRPosition::function(*Caller), DepClassTy::REQUIRED);
9060 if (!CallerInfo)
9061 return false;
9062
9063 Change = Change | clampStateAndIndicateChange(this->getState(),
9064 CallerInfo->getState());
9065 return true;
9066 };
9067
9068 bool AllCallSitesKnown = true;
9069 if (!A.checkForAllCallSites(CheckCallSite, *this, true, AllCallSitesKnown))
9070 return indicatePessimisticFixpoint();
9071
9072 if (Change == ChangeStatus::CHANGED && isModeFixed())
9073 indicateFixpoint();
9074 return Change;
9075 }
9076
9077 ChangeStatus manifest(Attributor &A) override {
9078 LLVMContext &Ctx = getAssociatedFunction()->getContext();
9079
9080 SmallVector<Attribute, 2> AttrToAdd;
9082
9083 // TODO: Change to use DenormalFPEnv everywhere.
9084 DenormalFPEnv KnownEnv(Known.Mode, Known.ModeF32);
9085
9086 if (KnownEnv == DenormalFPEnv::getDefault()) {
9087 AttrToRemove.push_back(Attribute::DenormalFPEnv);
9088 } else {
9089 AttrToAdd.push_back(Attribute::get(
9090 Ctx, Attribute::DenormalFPEnv,
9091 DenormalFPEnv(Known.Mode, Known.ModeF32).toIntValue()));
9092 }
9093
9094 auto &IRP = getIRPosition();
9095
9096 // TODO: There should be a combined add and remove API.
9097 return A.removeAttrs(IRP, AttrToRemove) |
9098 A.manifestAttrs(IRP, AttrToAdd, /*ForceReplace=*/true);
9099 }
9100
9101 void trackStatistics() const override {
9102 STATS_DECLTRACK_FN_ATTR(denormal_fpenv)
9103 }
9104};
9105} // namespace
9106
9107/// ------------------ Value Constant Range Attribute -------------------------
9108
9109namespace {
9110struct AAValueConstantRangeImpl : AAValueConstantRange {
9111 using StateType = IntegerRangeState;
9112 AAValueConstantRangeImpl(const IRPosition &IRP, Attributor &A)
9113 : AAValueConstantRange(IRP, A) {}
9114
9115 /// See AbstractAttribute::initialize(..).
9116 void initialize(Attributor &A) override {
9117 if (A.hasSimplificationCallback(getIRPosition())) {
9118 indicatePessimisticFixpoint();
9119 return;
9120 }
9121
9122 // Intersect a range given by SCEV.
9123 intersectKnown(getConstantRangeFromSCEV(A, getCtxI()));
9124
9125 // Intersect a range given by LVI.
9126 intersectKnown(getConstantRangeFromLVI(A, getCtxI()));
9127 }
9128
9129 /// See AbstractAttribute::getAsStr().
9130 const std::string getAsStr(Attributor *A) const override {
9131 std::string Str;
9132 llvm::raw_string_ostream OS(Str);
9133 OS << "range(" << getBitWidth() << ")<";
9134 getKnown().print(OS);
9135 OS << " / ";
9136 getAssumed().print(OS);
9137 OS << ">";
9138 return Str;
9139 }
9140
9141 /// Helper function to get a SCEV expr for the associated value at program
9142 /// point \p I.
9143 const SCEV *getSCEV(Attributor &A, const Instruction *I = nullptr) const {
9144 if (!getAnchorScope())
9145 return nullptr;
9146
9147 ScalarEvolution *SE =
9148 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(
9149 *getAnchorScope());
9150
9151 LoopInfo *LI = A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(
9152 *getAnchorScope());
9153
9154 if (!SE || !LI)
9155 return nullptr;
9156
9157 const SCEV *S = SE->getSCEV(&getAssociatedValue());
9158 if (!I)
9159 return S;
9160
9161 return SE->getSCEVAtScope(S, LI->getLoopFor(I->getParent()));
9162 }
9163
9164 /// Helper function to get a range from SCEV for the associated value at
9165 /// program point \p I.
9166 ConstantRange getConstantRangeFromSCEV(Attributor &A,
9167 const Instruction *I = nullptr) const {
9168 if (!getAnchorScope())
9169 return getWorstState(getBitWidth());
9170
9171 ScalarEvolution *SE =
9172 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(
9173 *getAnchorScope());
9174
9175 const SCEV *S = getSCEV(A, I);
9176 if (!SE || !S)
9177 return getWorstState(getBitWidth());
9178
9179 return SE->getUnsignedRange(S);
9180 }
9181
9182 /// Helper function to get a range from LVI for the associated value at
9183 /// program point \p I.
9184 ConstantRange
9185 getConstantRangeFromLVI(Attributor &A,
9186 const Instruction *CtxI = nullptr) const {
9187 if (!getAnchorScope())
9188 return getWorstState(getBitWidth());
9189
9190 LazyValueInfo *LVI =
9191 A.getInfoCache().getAnalysisResultForFunction<LazyValueAnalysis>(
9192 *getAnchorScope());
9193
9194 if (!LVI || !CtxI)
9195 return getWorstState(getBitWidth());
9196 return LVI->getConstantRange(&getAssociatedValue(),
9197 const_cast<Instruction *>(CtxI),
9198 /*UndefAllowed*/ false);
9199 }
9200
9201 /// Return true if \p CtxI is valid for querying outside analyses.
9202 /// This basically makes sure we do not ask intra-procedural analysis
9203 /// about a context in the wrong function or a context that violates
9204 /// dominance assumptions they might have. The \p AllowAACtxI flag indicates
9205 /// if the original context of this AA is OK or should be considered invalid.
9206 bool isValidCtxInstructionForOutsideAnalysis(Attributor &A,
9207 const Instruction *CtxI,
9208 bool AllowAACtxI) const {
9209 if (!CtxI || (!AllowAACtxI && CtxI == getCtxI()))
9210 return false;
9211
9212 // Our context might be in a different function, neither intra-procedural
9213 // analysis (ScalarEvolution nor LazyValueInfo) can handle that.
9214 if (!AA::isValidInScope(getAssociatedValue(), CtxI->getFunction()))
9215 return false;
9216
9217 // If the context is not dominated by the value there are paths to the
9218 // context that do not define the value. This cannot be handled by
9219 // LazyValueInfo so we need to bail.
9220 if (auto *I = dyn_cast<Instruction>(&getAssociatedValue())) {
9221 InformationCache &InfoCache = A.getInfoCache();
9222 const DominatorTree *DT =
9223 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(
9224 *I->getFunction());
9225 return DT && DT->dominates(I, CtxI);
9226 }
9227
9228 return true;
9229 }
9230
9231 /// See AAValueConstantRange::getKnownConstantRange(..).
9232 ConstantRange
9233 getKnownConstantRange(Attributor &A,
9234 const Instruction *CtxI = nullptr) const override {
9235 if (!isValidCtxInstructionForOutsideAnalysis(A, CtxI,
9236 /* AllowAACtxI */ false))
9237 return getKnown();
9238
9239 ConstantRange LVIR = getConstantRangeFromLVI(A, CtxI);
9240 ConstantRange SCEVR = getConstantRangeFromSCEV(A, CtxI);
9241 return getKnown().intersectWith(SCEVR).intersectWith(LVIR);
9242 }
9243
9244 /// See AAValueConstantRange::getAssumedConstantRange(..).
9245 ConstantRange
9246 getAssumedConstantRange(Attributor &A,
9247 const Instruction *CtxI = nullptr) const override {
9248 // TODO: Make SCEV use Attributor assumption.
9249 // We may be able to bound a variable range via assumptions in
9250 // Attributor. ex.) If x is assumed to be in [1, 3] and y is known to
9251 // evolve to x^2 + x, then we can say that y is in [2, 12].
9252 if (!isValidCtxInstructionForOutsideAnalysis(A, CtxI,
9253 /* AllowAACtxI */ false))
9254 return getAssumed();
9255
9256 ConstantRange LVIR = getConstantRangeFromLVI(A, CtxI);
9257 ConstantRange SCEVR = getConstantRangeFromSCEV(A, CtxI);
9258 return getAssumed().intersectWith(SCEVR).intersectWith(LVIR);
9259 }
9260
9261 /// Helper function to create MDNode for range metadata.
9262 static MDNode *
9263 getMDNodeForConstantRange(Type *Ty, LLVMContext &Ctx,
9264 const ConstantRange &AssumedConstantRange) {
9265 Metadata *LowAndHigh[] = {ConstantAsMetadata::get(ConstantInt::get(
9266 Ty, AssumedConstantRange.getLower())),
9267 ConstantAsMetadata::get(ConstantInt::get(
9268 Ty, AssumedConstantRange.getUpper()))};
9269 return MDNode::get(Ctx, LowAndHigh);
9270 }
9271
9272 /// Return true if \p Assumed is included in ranges from instruction \p I.
9273 static bool isBetterRange(const ConstantRange &Assumed,
9274 const Instruction &I) {
9275 if (Assumed.isFullSet())
9276 return false;
9277
9278 std::optional<ConstantRange> Known;
9279
9280 if (const auto *CB = dyn_cast<CallBase>(&I)) {
9281 Known = CB->getRange();
9282 } else if (MDNode *KnownRanges = I.getMetadata(LLVMContext::MD_range)) {
9283 // If multiple ranges are annotated in IR, we give up to annotate assumed
9284 // range for now.
9285
9286 // TODO: If there exists a known range which containts assumed range, we
9287 // can say assumed range is better.
9288 if (KnownRanges->getNumOperands() > 2)
9289 return false;
9290
9291 ConstantInt *Lower =
9292 mdconst::extract<ConstantInt>(KnownRanges->getOperand(0));
9293 ConstantInt *Upper =
9294 mdconst::extract<ConstantInt>(KnownRanges->getOperand(1));
9295
9296 Known.emplace(Lower->getValue(), Upper->getValue());
9297 }
9298 return !Known || (*Known != Assumed && Known->contains(Assumed));
9299 }
9300
9301 /// Helper function to set range metadata.
9302 static bool
9303 setRangeMetadataIfisBetterRange(Instruction *I,
9304 const ConstantRange &AssumedConstantRange) {
9305 if (isBetterRange(AssumedConstantRange, *I)) {
9306 I->setMetadata(LLVMContext::MD_range,
9307 getMDNodeForConstantRange(I->getType(), I->getContext(),
9308 AssumedConstantRange));
9309 return true;
9310 }
9311 return false;
9312 }
9313 /// Helper function to set range return attribute.
9314 static bool
9315 setRangeRetAttrIfisBetterRange(Attributor &A, const IRPosition &IRP,
9316 Instruction *I,
9317 const ConstantRange &AssumedConstantRange) {
9318 if (isBetterRange(AssumedConstantRange, *I)) {
9319 A.manifestAttrs(IRP,
9320 Attribute::get(I->getContext(), Attribute::Range,
9321 AssumedConstantRange),
9322 /*ForceReplace*/ true);
9323 return true;
9324 }
9325 return false;
9326 }
9327
9328 /// See AbstractAttribute::manifest()
9329 ChangeStatus manifest(Attributor &A) override {
9330 ChangeStatus Changed = ChangeStatus::UNCHANGED;
9331 ConstantRange AssumedConstantRange = getAssumedConstantRange(A);
9332 assert(!AssumedConstantRange.isFullSet() && "Invalid state");
9333
9334 auto &V = getAssociatedValue();
9335 if (!AssumedConstantRange.isEmptySet() &&
9336 !AssumedConstantRange.isSingleElement()) {
9337 if (Instruction *I = dyn_cast<Instruction>(&V)) {
9338 assert(I == getCtxI() && "Should not annotate an instruction which is "
9339 "not the context instruction");
9340 if (isa<LoadInst>(I))
9341 if (setRangeMetadataIfisBetterRange(I, AssumedConstantRange))
9342 Changed = ChangeStatus::CHANGED;
9343 if (isa<CallInst>(I))
9344 if (setRangeRetAttrIfisBetterRange(A, getIRPosition(), I,
9345 AssumedConstantRange))
9346 Changed = ChangeStatus::CHANGED;
9347 }
9348 }
9349
9350 return Changed;
9351 }
9352};
9353
9354struct AAValueConstantRangeArgument final
9355 : AAArgumentFromCallSiteArguments<
9356 AAValueConstantRange, AAValueConstantRangeImpl, IntegerRangeState,
9357 true /* BridgeCallBaseContext */> {
9358 using Base = AAArgumentFromCallSiteArguments<
9359 AAValueConstantRange, AAValueConstantRangeImpl, IntegerRangeState,
9360 true /* BridgeCallBaseContext */>;
9361 AAValueConstantRangeArgument(const IRPosition &IRP, Attributor &A)
9362 : Base(IRP, A) {}
9363
9364 /// See AbstractAttribute::trackStatistics()
9365 void trackStatistics() const override {
9366 STATS_DECLTRACK_ARG_ATTR(value_range)
9367 }
9368};
9369
9370struct AAValueConstantRangeReturned
9371 : AAReturnedFromReturnedValues<AAValueConstantRange,
9372 AAValueConstantRangeImpl,
9373 AAValueConstantRangeImpl::StateType,
9374 /* PropagateCallBaseContext */ true> {
9375 using Base =
9376 AAReturnedFromReturnedValues<AAValueConstantRange,
9377 AAValueConstantRangeImpl,
9378 AAValueConstantRangeImpl::StateType,
9379 /* PropagateCallBaseContext */ true>;
9380 AAValueConstantRangeReturned(const IRPosition &IRP, Attributor &A)
9381 : Base(IRP, A) {}
9382
9383 /// See AbstractAttribute::initialize(...).
9384 void initialize(Attributor &A) override {
9385 if (!A.isFunctionIPOAmendable(*getAssociatedFunction()))
9386 indicatePessimisticFixpoint();
9387 }
9388
9389 /// See AbstractAttribute::trackStatistics()
9390 void trackStatistics() const override {
9391 STATS_DECLTRACK_FNRET_ATTR(value_range)
9392 }
9393};
9394
9395struct AAValueConstantRangeFloating : AAValueConstantRangeImpl {
9396 AAValueConstantRangeFloating(const IRPosition &IRP, Attributor &A)
9397 : AAValueConstantRangeImpl(IRP, A) {}
9398
9399 /// See AbstractAttribute::initialize(...).
9400 void initialize(Attributor &A) override {
9401 AAValueConstantRangeImpl::initialize(A);
9402 if (isAtFixpoint())
9403 return;
9404
9405 Value &V = getAssociatedValue();
9406
9407 if (auto *C = dyn_cast<ConstantInt>(&V)) {
9408 unionAssumed(ConstantRange(C->getValue()));
9409 indicateOptimisticFixpoint();
9410 return;
9411 }
9412
9413 if (isa<UndefValue>(&V)) {
9414 // Collapse the undef state to 0.
9415 unionAssumed(ConstantRange(APInt(getBitWidth(), 0)));
9416 indicateOptimisticFixpoint();
9417 return;
9418 }
9419
9420 if (isa<CallBase>(&V))
9421 return;
9422
9423 if (isa<BinaryOperator>(&V) || isa<CmpInst>(&V) || isa<CastInst>(&V))
9424 return;
9425
9426 // If it is a load instruction with range metadata, use it.
9427 if (LoadInst *LI = dyn_cast<LoadInst>(&V))
9428 if (auto *RangeMD = LI->getMetadata(LLVMContext::MD_range)) {
9429 intersectKnown(getConstantRangeFromMetadata(*RangeMD));
9430 return;
9431 }
9432
9433 // We can work with PHI and select instruction as we traverse their operands
9434 // during update.
9435 if (isa<SelectInst>(V) || isa<PHINode>(V))
9436 return;
9437
9438 // Otherwise we give up.
9439 indicatePessimisticFixpoint();
9440
9441 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] We give up: "
9442 << getAssociatedValue() << "\n");
9443 }
9444
9445 bool calculateBinaryOperator(
9446 Attributor &A, BinaryOperator *BinOp, IntegerRangeState &T,
9447 const Instruction *CtxI,
9448 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) {
9449 Value *LHS = BinOp->getOperand(0);
9450 Value *RHS = BinOp->getOperand(1);
9451
9452 // Simplify the operands first.
9453 bool UsedAssumedInformation = false;
9454 const auto &SimplifiedLHS = A.getAssumedSimplified(
9455 IRPosition::value(*LHS, getCallBaseContext()), *this,
9456 UsedAssumedInformation, AA::Interprocedural);
9457 if (!SimplifiedLHS.has_value())
9458 return true;
9459 if (!*SimplifiedLHS)
9460 return false;
9461 LHS = *SimplifiedLHS;
9462
9463 const auto &SimplifiedRHS = A.getAssumedSimplified(
9464 IRPosition::value(*RHS, getCallBaseContext()), *this,
9465 UsedAssumedInformation, AA::Interprocedural);
9466 if (!SimplifiedRHS.has_value())
9467 return true;
9468 if (!*SimplifiedRHS)
9469 return false;
9470 RHS = *SimplifiedRHS;
9471
9472 // TODO: Allow non integers as well.
9473 if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy())
9474 return false;
9475
9476 auto *LHSAA = A.getAAFor<AAValueConstantRange>(
9477 *this, IRPosition::value(*LHS, getCallBaseContext()),
9478 DepClassTy::REQUIRED);
9479 if (!LHSAA)
9480 return false;
9481 QuerriedAAs.push_back(LHSAA);
9482 auto LHSAARange = LHSAA->getAssumedConstantRange(A, CtxI);
9483
9484 auto *RHSAA = A.getAAFor<AAValueConstantRange>(
9485 *this, IRPosition::value(*RHS, getCallBaseContext()),
9486 DepClassTy::REQUIRED);
9487 if (!RHSAA)
9488 return false;
9489 QuerriedAAs.push_back(RHSAA);
9490 auto RHSAARange = RHSAA->getAssumedConstantRange(A, CtxI);
9491
9492 auto AssumedRange = LHSAARange.binaryOp(BinOp->getOpcode(), RHSAARange);
9493
9494 T.unionAssumed(AssumedRange);
9495
9496 // TODO: Track a known state too.
9497
9498 return T.isValidState();
9499 }
9500
9501 bool calculateCastInst(
9502 Attributor &A, CastInst *CastI, IntegerRangeState &T,
9503 const Instruction *CtxI,
9504 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) {
9505 assert(CastI->getNumOperands() == 1 && "Expected cast to be unary!");
9506 // TODO: Allow non integers as well.
9507 Value *OpV = CastI->getOperand(0);
9508
9509 // Simplify the operand first.
9510 bool UsedAssumedInformation = false;
9511 const auto &SimplifiedOpV = A.getAssumedSimplified(
9512 IRPosition::value(*OpV, getCallBaseContext()), *this,
9513 UsedAssumedInformation, AA::Interprocedural);
9514 if (!SimplifiedOpV.has_value())
9515 return true;
9516 if (!*SimplifiedOpV)
9517 return false;
9518 OpV = *SimplifiedOpV;
9519
9520 if (!OpV->getType()->isIntegerTy())
9521 return false;
9522
9523 auto *OpAA = A.getAAFor<AAValueConstantRange>(
9524 *this, IRPosition::value(*OpV, getCallBaseContext()),
9525 DepClassTy::REQUIRED);
9526 if (!OpAA)
9527 return false;
9528 QuerriedAAs.push_back(OpAA);
9529 T.unionAssumed(OpAA->getAssumed().castOp(CastI->getOpcode(),
9530 getState().getBitWidth()));
9531 return T.isValidState();
9532 }
9533
9534 bool
9535 calculateCmpInst(Attributor &A, CmpInst *CmpI, IntegerRangeState &T,
9536 const Instruction *CtxI,
9537 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) {
9538 Value *LHS = CmpI->getOperand(0);
9539 Value *RHS = CmpI->getOperand(1);
9540
9541 // Simplify the operands first.
9542 bool UsedAssumedInformation = false;
9543 const auto &SimplifiedLHS = A.getAssumedSimplified(
9544 IRPosition::value(*LHS, getCallBaseContext()), *this,
9545 UsedAssumedInformation, AA::Interprocedural);
9546 if (!SimplifiedLHS.has_value())
9547 return true;
9548 if (!*SimplifiedLHS)
9549 return false;
9550 LHS = *SimplifiedLHS;
9551
9552 const auto &SimplifiedRHS = A.getAssumedSimplified(
9553 IRPosition::value(*RHS, getCallBaseContext()), *this,
9554 UsedAssumedInformation, AA::Interprocedural);
9555 if (!SimplifiedRHS.has_value())
9556 return true;
9557 if (!*SimplifiedRHS)
9558 return false;
9559 RHS = *SimplifiedRHS;
9560
9561 // TODO: Allow non integers as well.
9562 if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy())
9563 return false;
9564
9565 auto *LHSAA = A.getAAFor<AAValueConstantRange>(
9566 *this, IRPosition::value(*LHS, getCallBaseContext()),
9567 DepClassTy::REQUIRED);
9568 if (!LHSAA)
9569 return false;
9570 QuerriedAAs.push_back(LHSAA);
9571 auto *RHSAA = A.getAAFor<AAValueConstantRange>(
9572 *this, IRPosition::value(*RHS, getCallBaseContext()),
9573 DepClassTy::REQUIRED);
9574 if (!RHSAA)
9575 return false;
9576 QuerriedAAs.push_back(RHSAA);
9577 auto LHSAARange = LHSAA->getAssumedConstantRange(A, CtxI);
9578 auto RHSAARange = RHSAA->getAssumedConstantRange(A, CtxI);
9579
9580 // If one of them is empty set, we can't decide.
9581 if (LHSAARange.isEmptySet() || RHSAARange.isEmptySet())
9582 return true;
9583
9584 bool MustTrue = false, MustFalse = false;
9585
9586 auto AllowedRegion =
9588
9589 if (AllowedRegion.intersectWith(LHSAARange).isEmptySet())
9590 MustFalse = true;
9591
9592 if (LHSAARange.icmp(CmpI->getPredicate(), RHSAARange))
9593 MustTrue = true;
9594
9595 assert((!MustTrue || !MustFalse) &&
9596 "Either MustTrue or MustFalse should be false!");
9597
9598 if (MustTrue)
9599 T.unionAssumed(ConstantRange(APInt(/* numBits */ 1, /* val */ 1)));
9600 else if (MustFalse)
9601 T.unionAssumed(ConstantRange(APInt(/* numBits */ 1, /* val */ 0)));
9602 else
9603 T.unionAssumed(ConstantRange(/* BitWidth */ 1, /* isFullSet */ true));
9604
9605 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] " << *CmpI << " after "
9606 << (MustTrue ? "true" : (MustFalse ? "false" : "unknown"))
9607 << ": " << T << "\n\t" << *LHSAA << "\t<op>\n\t"
9608 << *RHSAA);
9609
9610 // TODO: Track a known state too.
9611 return T.isValidState();
9612 }
9613
9614 /// See AbstractAttribute::updateImpl(...).
9615 ChangeStatus updateImpl(Attributor &A) override {
9616
9617 IntegerRangeState T(getBitWidth());
9618 auto VisitValueCB = [&](Value &V, const Instruction *CtxI) -> bool {
9620 if (!I || isa<CallBase>(I)) {
9621
9622 // Simplify the operand first.
9623 bool UsedAssumedInformation = false;
9624 const auto &SimplifiedOpV = A.getAssumedSimplified(
9625 IRPosition::value(V, getCallBaseContext()), *this,
9626 UsedAssumedInformation, AA::Interprocedural);
9627 if (!SimplifiedOpV.has_value())
9628 return true;
9629 if (!*SimplifiedOpV)
9630 return false;
9631 Value *VPtr = *SimplifiedOpV;
9632
9633 // If the value is not instruction, we query AA to Attributor.
9634 const auto *AA = A.getAAFor<AAValueConstantRange>(
9635 *this, IRPosition::value(*VPtr, getCallBaseContext()),
9636 DepClassTy::REQUIRED);
9637
9638 // Clamp operator is not used to utilize a program point CtxI.
9639 if (AA)
9640 T.unionAssumed(AA->getAssumedConstantRange(A, CtxI));
9641 else
9642 return false;
9643
9644 return T.isValidState();
9645 }
9646
9648 if (auto *BinOp = dyn_cast<BinaryOperator>(I)) {
9649 if (!calculateBinaryOperator(A, BinOp, T, CtxI, QuerriedAAs))
9650 return false;
9651 } else if (auto *CmpI = dyn_cast<CmpInst>(I)) {
9652 if (!calculateCmpInst(A, CmpI, T, CtxI, QuerriedAAs))
9653 return false;
9654 } else if (auto *CastI = dyn_cast<CastInst>(I)) {
9655 if (!calculateCastInst(A, CastI, T, CtxI, QuerriedAAs))
9656 return false;
9657 } else {
9658 // Give up with other instructions.
9659 // TODO: Add other instructions
9660
9661 T.indicatePessimisticFixpoint();
9662 return false;
9663 }
9664
9665 // Catch circular reasoning in a pessimistic way for now.
9666 // TODO: Check how the range evolves and if we stripped anything, see also
9667 // AADereferenceable or AAAlign for similar situations.
9668 for (const AAValueConstantRange *QueriedAA : QuerriedAAs) {
9669 if (QueriedAA != this)
9670 continue;
9671 // If we are in a stady state we do not need to worry.
9672 if (T.getAssumed() == getState().getAssumed())
9673 continue;
9674 T.indicatePessimisticFixpoint();
9675 }
9676
9677 return T.isValidState();
9678 };
9679
9680 if (!VisitValueCB(getAssociatedValue(), getCtxI()))
9681 return indicatePessimisticFixpoint();
9682
9683 // Ensure that long def-use chains can't cause circular reasoning either by
9684 // introducing a cutoff below.
9685 if (clampStateAndIndicateChange(getState(), T) == ChangeStatus::UNCHANGED)
9686 return ChangeStatus::UNCHANGED;
9687 if (++NumChanges > MaxNumChanges) {
9688 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] performed " << NumChanges
9689 << " but only " << MaxNumChanges
9690 << " are allowed to avoid cyclic reasoning.");
9691 return indicatePessimisticFixpoint();
9692 }
9693 return ChangeStatus::CHANGED;
9694 }
9695
9696 /// See AbstractAttribute::trackStatistics()
9697 void trackStatistics() const override {
9699 }
9700
9701 /// Tracker to bail after too many widening steps of the constant range.
9702 int NumChanges = 0;
9703
9704 /// Upper bound for the number of allowed changes (=widening steps) for the
9705 /// constant range before we give up.
9706 static constexpr int MaxNumChanges = 5;
9707};
9708
9709struct AAValueConstantRangeFunction : AAValueConstantRangeImpl {
9710 AAValueConstantRangeFunction(const IRPosition &IRP, Attributor &A)
9711 : AAValueConstantRangeImpl(IRP, A) {}
9712
9713 /// See AbstractAttribute::initialize(...).
9714 ChangeStatus updateImpl(Attributor &A) override {
9715 llvm_unreachable("AAValueConstantRange(Function|CallSite)::updateImpl will "
9716 "not be called");
9717 }
9718
9719 /// See AbstractAttribute::trackStatistics()
9720 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(value_range) }
9721};
9722
9723struct AAValueConstantRangeCallSite : AAValueConstantRangeFunction {
9724 AAValueConstantRangeCallSite(const IRPosition &IRP, Attributor &A)
9725 : AAValueConstantRangeFunction(IRP, A) {}
9726
9727 /// See AbstractAttribute::trackStatistics()
9728 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(value_range) }
9729};
9730
9731struct AAValueConstantRangeCallSiteReturned
9732 : AACalleeToCallSite<AAValueConstantRange, AAValueConstantRangeImpl,
9733 AAValueConstantRangeImpl::StateType,
9734 /* IntroduceCallBaseContext */ true> {
9735 AAValueConstantRangeCallSiteReturned(const IRPosition &IRP, Attributor &A)
9736 : AACalleeToCallSite<AAValueConstantRange, AAValueConstantRangeImpl,
9737 AAValueConstantRangeImpl::StateType,
9738 /* IntroduceCallBaseContext */ true>(IRP, A) {}
9739
9740 /// See AbstractAttribute::initialize(...).
9741 void initialize(Attributor &A) override {
9742 // If it is a call instruction with range attribute, use the range.
9743 if (CallInst *CI = dyn_cast<CallInst>(&getAssociatedValue())) {
9744 if (std::optional<ConstantRange> Range = CI->getRange())
9745 intersectKnown(*Range);
9746 }
9747
9748 AAValueConstantRangeImpl::initialize(A);
9749 }
9750
9751 /// See AbstractAttribute::trackStatistics()
9752 void trackStatistics() const override {
9753 STATS_DECLTRACK_CSRET_ATTR(value_range)
9754 }
9755};
9756struct AAValueConstantRangeCallSiteArgument : AAValueConstantRangeFloating {
9757 AAValueConstantRangeCallSiteArgument(const IRPosition &IRP, Attributor &A)
9758 : AAValueConstantRangeFloating(IRP, A) {}
9759
9760 /// See AbstractAttribute::manifest()
9761 ChangeStatus manifest(Attributor &A) override {
9762 return ChangeStatus::UNCHANGED;
9763 }
9764
9765 /// See AbstractAttribute::trackStatistics()
9766 void trackStatistics() const override {
9767 STATS_DECLTRACK_CSARG_ATTR(value_range)
9768 }
9769};
9770} // namespace
9771
9772/// ------------------ Potential Values Attribute -------------------------
9773
9774namespace {
9775struct AAPotentialConstantValuesImpl : AAPotentialConstantValues {
9776 using StateType = PotentialConstantIntValuesState;
9777
9778 AAPotentialConstantValuesImpl(const IRPosition &IRP, Attributor &A)
9779 : AAPotentialConstantValues(IRP, A) {}
9780
9781 /// See AbstractAttribute::initialize(..).
9782 void initialize(Attributor &A) override {
9783 if (A.hasSimplificationCallback(getIRPosition()))
9784 indicatePessimisticFixpoint();
9785 else
9786 AAPotentialConstantValues::initialize(A);
9787 }
9788
9789 bool fillSetWithConstantValues(Attributor &A, const IRPosition &IRP, SetTy &S,
9790 bool &ContainsUndef, bool ForSelf) {
9792 bool UsedAssumedInformation = false;
9793 if (!A.getAssumedSimplifiedValues(IRP, *this, Values, AA::Interprocedural,
9794 UsedAssumedInformation)) {
9795 // Avoid recursion when the caller is computing constant values for this
9796 // IRP itself.
9797 if (ForSelf)
9798 return false;
9799 if (!IRP.getAssociatedType()->isIntegerTy())
9800 return false;
9801 auto *PotentialValuesAA = A.getAAFor<AAPotentialConstantValues>(
9802 *this, IRP, DepClassTy::REQUIRED);
9803 if (!PotentialValuesAA || !PotentialValuesAA->getState().isValidState())
9804 return false;
9805 ContainsUndef = PotentialValuesAA->getState().undefIsContained();
9806 S = PotentialValuesAA->getState().getAssumedSet();
9807 return true;
9808 }
9809
9810 // Copy all the constant values, except UndefValue. ContainsUndef is true
9811 // iff Values contains only UndefValue instances. If there are other known
9812 // constants, then UndefValue is dropped.
9813 ContainsUndef = false;
9814 for (auto &It : Values) {
9815 if (isa<UndefValue>(It.getValue())) {
9816 ContainsUndef = true;
9817 continue;
9818 }
9819 auto *CI = dyn_cast<ConstantInt>(It.getValue());
9820 if (!CI)
9821 return false;
9822 S.insert(CI->getValue());
9823 }
9824 ContainsUndef &= S.empty();
9825
9826 return true;
9827 }
9828
9829 /// See AbstractAttribute::getAsStr().
9830 const std::string getAsStr(Attributor *A) const override {
9831 std::string Str;
9832 llvm::raw_string_ostream OS(Str);
9833 OS << getState();
9834 return Str;
9835 }
9836
9837 /// See AbstractAttribute::updateImpl(...).
9838 ChangeStatus updateImpl(Attributor &A) override {
9839 return indicatePessimisticFixpoint();
9840 }
9841};
9842
9843struct AAPotentialConstantValuesArgument final
9844 : AAArgumentFromCallSiteArguments<AAPotentialConstantValues,
9845 AAPotentialConstantValuesImpl,
9846 PotentialConstantIntValuesState> {
9847 using Base = AAArgumentFromCallSiteArguments<AAPotentialConstantValues,
9848 AAPotentialConstantValuesImpl,
9850 AAPotentialConstantValuesArgument(const IRPosition &IRP, Attributor &A)
9851 : Base(IRP, A) {}
9852
9853 /// See AbstractAttribute::trackStatistics()
9854 void trackStatistics() const override {
9855 STATS_DECLTRACK_ARG_ATTR(potential_values)
9856 }
9857};
9858
9859struct AAPotentialConstantValuesReturned
9860 : AAReturnedFromReturnedValues<AAPotentialConstantValues,
9861 AAPotentialConstantValuesImpl> {
9862 using Base = AAReturnedFromReturnedValues<AAPotentialConstantValues,
9863 AAPotentialConstantValuesImpl>;
9864 AAPotentialConstantValuesReturned(const IRPosition &IRP, Attributor &A)
9865 : Base(IRP, A) {}
9866
9867 void initialize(Attributor &A) override {
9868 if (!A.isFunctionIPOAmendable(*getAssociatedFunction()))
9869 indicatePessimisticFixpoint();
9870 Base::initialize(A);
9871 }
9872
9873 /// See AbstractAttribute::trackStatistics()
9874 void trackStatistics() const override {
9875 STATS_DECLTRACK_FNRET_ATTR(potential_values)
9876 }
9877};
9878
9879struct AAPotentialConstantValuesFloating : AAPotentialConstantValuesImpl {
9880 AAPotentialConstantValuesFloating(const IRPosition &IRP, Attributor &A)
9881 : AAPotentialConstantValuesImpl(IRP, A) {}
9882
9883 /// See AbstractAttribute::initialize(..).
9884 void initialize(Attributor &A) override {
9885 AAPotentialConstantValuesImpl::initialize(A);
9886 if (isAtFixpoint())
9887 return;
9888
9889 Value &V = getAssociatedValue();
9890
9891 if (auto *C = dyn_cast<ConstantInt>(&V)) {
9892 unionAssumed(C->getValue());
9893 indicateOptimisticFixpoint();
9894 return;
9895 }
9896
9897 if (isa<UndefValue>(&V)) {
9898 unionAssumedWithUndef();
9899 indicateOptimisticFixpoint();
9900 return;
9901 }
9902
9903 if (isa<BinaryOperator>(&V) || isa<ICmpInst>(&V) || isa<CastInst>(&V))
9904 return;
9905
9906 if (isa<SelectInst>(V) || isa<PHINode>(V) || isa<LoadInst>(V))
9907 return;
9908
9909 indicatePessimisticFixpoint();
9910
9911 LLVM_DEBUG(dbgs() << "[AAPotentialConstantValues] We give up: "
9912 << getAssociatedValue() << "\n");
9913 }
9914
9915 static bool calculateICmpInst(const ICmpInst *ICI, const APInt &LHS,
9916 const APInt &RHS) {
9917 return ICmpInst::compare(LHS, RHS, ICI->getPredicate());
9918 }
9919
9920 static APInt calculateCastInst(const CastInst *CI, const APInt &Src,
9921 uint32_t ResultBitWidth) {
9922 Instruction::CastOps CastOp = CI->getOpcode();
9923 switch (CastOp) {
9924 default:
9925 llvm_unreachable("unsupported or not integer cast");
9926 case Instruction::Trunc:
9927 return Src.trunc(ResultBitWidth);
9928 case Instruction::SExt:
9929 return Src.sext(ResultBitWidth);
9930 case Instruction::ZExt:
9931 return Src.zext(ResultBitWidth);
9932 case Instruction::BitCast:
9933 return Src;
9934 }
9935 }
9936
9937 static APInt calculateBinaryOperator(const BinaryOperator *BinOp,
9938 const APInt &LHS, const APInt &RHS,
9939 bool &SkipOperation, bool &Unsupported) {
9940 Instruction::BinaryOps BinOpcode = BinOp->getOpcode();
9941 // Unsupported is set to true when the binary operator is not supported.
9942 // SkipOperation is set to true when UB occur with the given operand pair
9943 // (LHS, RHS).
9944 // TODO: we should look at nsw and nuw keywords to handle operations
9945 // that create poison or undef value.
9946 switch (BinOpcode) {
9947 default:
9948 Unsupported = true;
9949 return LHS;
9950 case Instruction::Add:
9951 return LHS + RHS;
9952 case Instruction::Sub:
9953 return LHS - RHS;
9954 case Instruction::Mul:
9955 return LHS * RHS;
9956 case Instruction::UDiv:
9957 if (RHS.isZero()) {
9958 SkipOperation = true;
9959 return LHS;
9960 }
9961 return LHS.udiv(RHS);
9962 case Instruction::SDiv:
9963 if (RHS.isZero()) {
9964 SkipOperation = true;
9965 return LHS;
9966 }
9967 return LHS.sdiv(RHS);
9968 case Instruction::URem:
9969 if (RHS.isZero()) {
9970 SkipOperation = true;
9971 return LHS;
9972 }
9973 return LHS.urem(RHS);
9974 case Instruction::SRem:
9975 if (RHS.isZero()) {
9976 SkipOperation = true;
9977 return LHS;
9978 }
9979 return LHS.srem(RHS);
9980 case Instruction::Shl:
9981 return LHS.shl(RHS);
9982 case Instruction::LShr:
9983 return LHS.lshr(RHS);
9984 case Instruction::AShr:
9985 return LHS.ashr(RHS);
9986 case Instruction::And:
9987 return LHS & RHS;
9988 case Instruction::Or:
9989 return LHS | RHS;
9990 case Instruction::Xor:
9991 return LHS ^ RHS;
9992 }
9993 }
9994
9995 bool calculateBinaryOperatorAndTakeUnion(const BinaryOperator *BinOp,
9996 const APInt &LHS, const APInt &RHS) {
9997 bool SkipOperation = false;
9998 bool Unsupported = false;
9999 APInt Result =
10000 calculateBinaryOperator(BinOp, LHS, RHS, SkipOperation, Unsupported);
10001 if (Unsupported)
10002 return false;
10003 // If SkipOperation is true, we can ignore this operand pair (L, R).
10004 if (!SkipOperation)
10005 unionAssumed(Result);
10006 return isValidState();
10007 }
10008
10009 ChangeStatus updateWithICmpInst(Attributor &A, ICmpInst *ICI) {
10010 auto AssumedBefore = getAssumed();
10011 Value *LHS = ICI->getOperand(0);
10012 Value *RHS = ICI->getOperand(1);
10013
10014 bool LHSContainsUndef = false, RHSContainsUndef = false;
10015 SetTy LHSAAPVS, RHSAAPVS;
10016 if (!fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS,
10017 LHSContainsUndef, /* ForSelf */ false) ||
10018 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS,
10019 RHSContainsUndef, /* ForSelf */ false))
10020 return indicatePessimisticFixpoint();
10021
10022 // TODO: make use of undef flag to limit potential values aggressively.
10023 bool MaybeTrue = false, MaybeFalse = false;
10024 const APInt Zero(RHS->getType()->getIntegerBitWidth(), 0);
10025 if (LHSContainsUndef && RHSContainsUndef) {
10026 // The result of any comparison between undefs can be soundly replaced
10027 // with undef.
10028 unionAssumedWithUndef();
10029 } else if (LHSContainsUndef) {
10030 for (const APInt &R : RHSAAPVS) {
10031 bool CmpResult = calculateICmpInst(ICI, Zero, R);
10032 MaybeTrue |= CmpResult;
10033 MaybeFalse |= !CmpResult;
10034 if (MaybeTrue & MaybeFalse)
10035 return indicatePessimisticFixpoint();
10036 }
10037 } else if (RHSContainsUndef) {
10038 for (const APInt &L : LHSAAPVS) {
10039 bool CmpResult = calculateICmpInst(ICI, L, Zero);
10040 MaybeTrue |= CmpResult;
10041 MaybeFalse |= !CmpResult;
10042 if (MaybeTrue & MaybeFalse)
10043 return indicatePessimisticFixpoint();
10044 }
10045 } else {
10046 for (const APInt &L : LHSAAPVS) {
10047 for (const APInt &R : RHSAAPVS) {
10048 bool CmpResult = calculateICmpInst(ICI, L, R);
10049 MaybeTrue |= CmpResult;
10050 MaybeFalse |= !CmpResult;
10051 if (MaybeTrue & MaybeFalse)
10052 return indicatePessimisticFixpoint();
10053 }
10054 }
10055 }
10056 if (MaybeTrue)
10057 unionAssumed(APInt(/* numBits */ 1, /* val */ 1));
10058 if (MaybeFalse)
10059 unionAssumed(APInt(/* numBits */ 1, /* val */ 0));
10060 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10061 : ChangeStatus::CHANGED;
10062 }
10063
10064 ChangeStatus updateWithSelectInst(Attributor &A, SelectInst *SI) {
10065 auto AssumedBefore = getAssumed();
10066 Value *LHS = SI->getTrueValue();
10067 Value *RHS = SI->getFalseValue();
10068
10069 bool UsedAssumedInformation = false;
10070 std::optional<Constant *> C = A.getAssumedConstant(
10071 *SI->getCondition(), *this, UsedAssumedInformation);
10072
10073 // Check if we only need one operand.
10074 bool OnlyLeft = false, OnlyRight = false;
10075 if (C && *C && (*C)->isOneValue())
10076 OnlyLeft = true;
10077 else if (C && *C && (*C)->isNullValue())
10078 OnlyRight = true;
10079
10080 bool LHSContainsUndef = false, RHSContainsUndef = false;
10081 SetTy LHSAAPVS, RHSAAPVS;
10082 if (!OnlyRight &&
10083 !fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS,
10084 LHSContainsUndef, /* ForSelf */ false))
10085 return indicatePessimisticFixpoint();
10086
10087 if (!OnlyLeft &&
10088 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS,
10089 RHSContainsUndef, /* ForSelf */ false))
10090 return indicatePessimisticFixpoint();
10091
10092 if (OnlyLeft || OnlyRight) {
10093 // select (true/false), lhs, rhs
10094 auto *OpAA = OnlyLeft ? &LHSAAPVS : &RHSAAPVS;
10095 auto Undef = OnlyLeft ? LHSContainsUndef : RHSContainsUndef;
10096
10097 if (Undef)
10098 unionAssumedWithUndef();
10099 else {
10100 for (const auto &It : *OpAA)
10101 unionAssumed(It);
10102 }
10103
10104 } else if (LHSContainsUndef && RHSContainsUndef) {
10105 // select i1 *, undef , undef => undef
10106 unionAssumedWithUndef();
10107 } else {
10108 for (const auto &It : LHSAAPVS)
10109 unionAssumed(It);
10110 for (const auto &It : RHSAAPVS)
10111 unionAssumed(It);
10112 }
10113 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10114 : ChangeStatus::CHANGED;
10115 }
10116
10117 ChangeStatus updateWithCastInst(Attributor &A, CastInst *CI) {
10118 auto AssumedBefore = getAssumed();
10119 if (!CI->isIntegerCast())
10120 return indicatePessimisticFixpoint();
10121 assert(CI->getNumOperands() == 1 && "Expected cast to be unary!");
10122 uint32_t ResultBitWidth = CI->getDestTy()->getIntegerBitWidth();
10123 Value *Src = CI->getOperand(0);
10124
10125 bool SrcContainsUndef = false;
10126 SetTy SrcPVS;
10127 if (!fillSetWithConstantValues(A, IRPosition::value(*Src), SrcPVS,
10128 SrcContainsUndef, /* ForSelf */ false))
10129 return indicatePessimisticFixpoint();
10130
10131 if (SrcContainsUndef)
10132 unionAssumedWithUndef();
10133 else {
10134 for (const APInt &S : SrcPVS) {
10135 APInt T = calculateCastInst(CI, S, ResultBitWidth);
10136 unionAssumed(T);
10137 }
10138 }
10139 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10140 : ChangeStatus::CHANGED;
10141 }
10142
10143 ChangeStatus updateWithBinaryOperator(Attributor &A, BinaryOperator *BinOp) {
10144 auto AssumedBefore = getAssumed();
10145 Value *LHS = BinOp->getOperand(0);
10146 Value *RHS = BinOp->getOperand(1);
10147
10148 bool LHSContainsUndef = false, RHSContainsUndef = false;
10149 SetTy LHSAAPVS, RHSAAPVS;
10150 if (!fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS,
10151 LHSContainsUndef, /* ForSelf */ false) ||
10152 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS,
10153 RHSContainsUndef, /* ForSelf */ false))
10154 return indicatePessimisticFixpoint();
10155
10156 const APInt Zero = APInt(LHS->getType()->getIntegerBitWidth(), 0);
10157
10158 // TODO: make use of undef flag to limit potential values aggressively.
10159 if (LHSContainsUndef && RHSContainsUndef) {
10160 if (!calculateBinaryOperatorAndTakeUnion(BinOp, Zero, Zero))
10161 return indicatePessimisticFixpoint();
10162 } else if (LHSContainsUndef) {
10163 for (const APInt &R : RHSAAPVS) {
10164 if (!calculateBinaryOperatorAndTakeUnion(BinOp, Zero, R))
10165 return indicatePessimisticFixpoint();
10166 }
10167 } else if (RHSContainsUndef) {
10168 for (const APInt &L : LHSAAPVS) {
10169 if (!calculateBinaryOperatorAndTakeUnion(BinOp, L, Zero))
10170 return indicatePessimisticFixpoint();
10171 }
10172 } else {
10173 for (const APInt &L : LHSAAPVS) {
10174 for (const APInt &R : RHSAAPVS) {
10175 if (!calculateBinaryOperatorAndTakeUnion(BinOp, L, R))
10176 return indicatePessimisticFixpoint();
10177 }
10178 }
10179 }
10180 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10181 : ChangeStatus::CHANGED;
10182 }
10183
10184 ChangeStatus updateWithInstruction(Attributor &A, Instruction *Inst) {
10185 auto AssumedBefore = getAssumed();
10186 SetTy Incoming;
10187 bool ContainsUndef;
10188 if (!fillSetWithConstantValues(A, IRPosition::value(*Inst), Incoming,
10189 ContainsUndef, /* ForSelf */ true))
10190 return indicatePessimisticFixpoint();
10191 if (ContainsUndef) {
10192 unionAssumedWithUndef();
10193 } else {
10194 for (const auto &It : Incoming)
10195 unionAssumed(It);
10196 }
10197 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10198 : ChangeStatus::CHANGED;
10199 }
10200
10201 /// See AbstractAttribute::updateImpl(...).
10202 ChangeStatus updateImpl(Attributor &A) override {
10203 Value &V = getAssociatedValue();
10205
10206 if (auto *ICI = dyn_cast<ICmpInst>(I))
10207 return updateWithICmpInst(A, ICI);
10208
10209 if (auto *SI = dyn_cast<SelectInst>(I))
10210 return updateWithSelectInst(A, SI);
10211
10212 if (auto *CI = dyn_cast<CastInst>(I))
10213 return updateWithCastInst(A, CI);
10214
10215 if (auto *BinOp = dyn_cast<BinaryOperator>(I))
10216 return updateWithBinaryOperator(A, BinOp);
10217
10218 if (isa<PHINode>(I) || isa<LoadInst>(I))
10219 return updateWithInstruction(A, I);
10220
10221 return indicatePessimisticFixpoint();
10222 }
10223
10224 /// See AbstractAttribute::trackStatistics()
10225 void trackStatistics() const override {
10226 STATS_DECLTRACK_FLOATING_ATTR(potential_values)
10227 }
10228};
10229
10230struct AAPotentialConstantValuesFunction : AAPotentialConstantValuesImpl {
10231 AAPotentialConstantValuesFunction(const IRPosition &IRP, Attributor &A)
10232 : AAPotentialConstantValuesImpl(IRP, A) {}
10233
10234 /// See AbstractAttribute::initialize(...).
10235 ChangeStatus updateImpl(Attributor &A) override {
10237 "AAPotentialConstantValues(Function|CallSite)::updateImpl will "
10238 "not be called");
10239 }
10240
10241 /// See AbstractAttribute::trackStatistics()
10242 void trackStatistics() const override {
10243 STATS_DECLTRACK_FN_ATTR(potential_values)
10244 }
10245};
10246
10247struct AAPotentialConstantValuesCallSite : AAPotentialConstantValuesFunction {
10248 AAPotentialConstantValuesCallSite(const IRPosition &IRP, Attributor &A)
10249 : AAPotentialConstantValuesFunction(IRP, A) {}
10250
10251 /// See AbstractAttribute::trackStatistics()
10252 void trackStatistics() const override {
10253 STATS_DECLTRACK_CS_ATTR(potential_values)
10254 }
10255};
10256
10257struct AAPotentialConstantValuesCallSiteReturned
10258 : AACalleeToCallSite<AAPotentialConstantValues,
10259 AAPotentialConstantValuesImpl> {
10260 AAPotentialConstantValuesCallSiteReturned(const IRPosition &IRP,
10261 Attributor &A)
10262 : AACalleeToCallSite<AAPotentialConstantValues,
10263 AAPotentialConstantValuesImpl>(IRP, A) {}
10264
10265 /// See AbstractAttribute::trackStatistics()
10266 void trackStatistics() const override {
10267 STATS_DECLTRACK_CSRET_ATTR(potential_values)
10268 }
10269};
10270
10271struct AAPotentialConstantValuesCallSiteArgument
10272 : AAPotentialConstantValuesFloating {
10273 AAPotentialConstantValuesCallSiteArgument(const IRPosition &IRP,
10274 Attributor &A)
10275 : AAPotentialConstantValuesFloating(IRP, A) {}
10276
10277 /// See AbstractAttribute::initialize(..).
10278 void initialize(Attributor &A) override {
10279 AAPotentialConstantValuesImpl::initialize(A);
10280 if (isAtFixpoint())
10281 return;
10282
10283 Value &V = getAssociatedValue();
10284
10285 if (auto *C = dyn_cast<ConstantInt>(&V)) {
10286 unionAssumed(C->getValue());
10287 indicateOptimisticFixpoint();
10288 return;
10289 }
10290
10291 if (isa<UndefValue>(&V)) {
10292 unionAssumedWithUndef();
10293 indicateOptimisticFixpoint();
10294 return;
10295 }
10296 }
10297
10298 /// See AbstractAttribute::updateImpl(...).
10299 ChangeStatus updateImpl(Attributor &A) override {
10300 Value &V = getAssociatedValue();
10301 auto AssumedBefore = getAssumed();
10302 auto *AA = A.getAAFor<AAPotentialConstantValues>(
10303 *this, IRPosition::value(V), DepClassTy::REQUIRED);
10304 if (!AA)
10305 return indicatePessimisticFixpoint();
10306 const auto &S = AA->getAssumed();
10307 unionAssumed(S);
10308 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10309 : ChangeStatus::CHANGED;
10310 }
10311
10312 /// See AbstractAttribute::trackStatistics()
10313 void trackStatistics() const override {
10314 STATS_DECLTRACK_CSARG_ATTR(potential_values)
10315 }
10316};
10317} // namespace
10318
10319/// ------------------------ NoUndef Attribute ---------------------------------
10321 Attribute::AttrKind ImpliedAttributeKind,
10322 bool IgnoreSubsumingPositions) {
10323 assert(ImpliedAttributeKind == Attribute::NoUndef &&
10324 "Unexpected attribute kind");
10325 if (A.hasAttr(IRP, {Attribute::NoUndef}, IgnoreSubsumingPositions,
10326 Attribute::NoUndef))
10327 return true;
10328
10329 Value &Val = IRP.getAssociatedValue();
10332 LLVMContext &Ctx = Val.getContext();
10333 A.manifestAttrs(IRP, Attribute::get(Ctx, Attribute::NoUndef));
10334 return true;
10335 }
10336
10337 return false;
10338}
10339
10340namespace {
10341struct AANoUndefImpl : AANoUndef {
10342 AANoUndefImpl(const IRPosition &IRP, Attributor &A) : AANoUndef(IRP, A) {}
10343
10344 /// See AbstractAttribute::initialize(...).
10345 void initialize(Attributor &A) override {
10346 Value &V = getAssociatedValue();
10347 if (isa<UndefValue>(V))
10348 indicatePessimisticFixpoint();
10349 assert(!isImpliedByIR(A, getIRPosition(), Attribute::NoUndef));
10350 }
10351
10352 /// See followUsesInMBEC
10353 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
10354 AANoUndef::StateType &State) {
10355 const Value *UseV = U->get();
10356 const DominatorTree *DT = nullptr;
10357 AssumptionCache *AC = nullptr;
10358 InformationCache &InfoCache = A.getInfoCache();
10359 if (Function *F = getAnchorScope()) {
10360 DT = InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F);
10361 AC = InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F);
10362 }
10363 State.setKnown(isGuaranteedNotToBeUndefOrPoison(UseV, AC, I, DT));
10364 bool TrackUse = false;
10365 // Track use for instructions which must produce undef or poison bits when
10366 // at least one operand contains such bits.
10368 TrackUse = true;
10369 return TrackUse;
10370 }
10371
10372 /// See AbstractAttribute::getAsStr().
10373 const std::string getAsStr(Attributor *A) const override {
10374 return getAssumed() ? "noundef" : "may-undef-or-poison";
10375 }
10376
10377 ChangeStatus manifest(Attributor &A) override {
10378 // We don't manifest noundef attribute for dead positions because the
10379 // associated values with dead positions would be replaced with undef
10380 // values.
10381 bool UsedAssumedInformation = false;
10382 if (A.isAssumedDead(getIRPosition(), nullptr, nullptr,
10383 UsedAssumedInformation))
10384 return ChangeStatus::UNCHANGED;
10385 // A position whose simplified value does not have any value is
10386 // considered to be dead. We don't manifest noundef in such positions for
10387 // the same reason above.
10388 if (!A.getAssumedSimplified(getIRPosition(), *this, UsedAssumedInformation,
10390 .has_value())
10391 return ChangeStatus::UNCHANGED;
10392 return AANoUndef::manifest(A);
10393 }
10394};
10395
10396struct AANoUndefFloating : public AANoUndefImpl {
10397 AANoUndefFloating(const IRPosition &IRP, Attributor &A)
10398 : AANoUndefImpl(IRP, A) {}
10399
10400 /// See AbstractAttribute::initialize(...).
10401 void initialize(Attributor &A) override {
10402 AANoUndefImpl::initialize(A);
10403 if (!getState().isAtFixpoint() && getAnchorScope() &&
10404 !getAnchorScope()->isDeclaration())
10405 if (Instruction *CtxI = getCtxI())
10406 followUsesInMBEC(*this, A, getState(), *CtxI);
10407 }
10408
10409 /// See AbstractAttribute::updateImpl(...).
10410 ChangeStatus updateImpl(Attributor &A) override {
10411 auto VisitValueCB = [&](const IRPosition &IRP) -> bool {
10412 bool IsKnownNoUndef;
10414 A, this, IRP, DepClassTy::REQUIRED, IsKnownNoUndef);
10415 };
10416
10417 bool Stripped;
10418 bool UsedAssumedInformation = false;
10419 Value *AssociatedValue = &getAssociatedValue();
10421 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
10422 AA::AnyScope, UsedAssumedInformation))
10423 Stripped = false;
10424 else
10425 Stripped =
10426 Values.size() != 1 || Values.front().getValue() != AssociatedValue;
10427
10428 if (!Stripped) {
10429 // If we haven't stripped anything we might still be able to use a
10430 // different AA, but only if the IRP changes. Effectively when we
10431 // interpret this not as a call site value but as a floating/argument
10432 // value.
10433 const IRPosition AVIRP = IRPosition::value(*AssociatedValue);
10434 if (AVIRP == getIRPosition() || !VisitValueCB(AVIRP))
10435 return indicatePessimisticFixpoint();
10436 return ChangeStatus::UNCHANGED;
10437 }
10438
10439 for (const auto &VAC : Values)
10440 if (!VisitValueCB(IRPosition::value(*VAC.getValue())))
10441 return indicatePessimisticFixpoint();
10442
10443 return ChangeStatus::UNCHANGED;
10444 }
10445
10446 /// See AbstractAttribute::trackStatistics()
10447 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noundef) }
10448};
10449
10450struct AANoUndefReturned final
10451 : AAReturnedFromReturnedValues<AANoUndef, AANoUndefImpl> {
10452 AANoUndefReturned(const IRPosition &IRP, Attributor &A)
10453 : AAReturnedFromReturnedValues<AANoUndef, AANoUndefImpl>(IRP, A) {}
10454
10455 /// See AbstractAttribute::trackStatistics()
10456 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noundef) }
10457};
10458
10459struct AANoUndefArgument final
10460 : AAArgumentFromCallSiteArguments<AANoUndef, AANoUndefImpl> {
10461 AANoUndefArgument(const IRPosition &IRP, Attributor &A)
10462 : AAArgumentFromCallSiteArguments<AANoUndef, AANoUndefImpl>(IRP, A) {}
10463
10464 /// See AbstractAttribute::trackStatistics()
10465 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noundef) }
10466};
10467
10468struct AANoUndefCallSiteArgument final : AANoUndefFloating {
10469 AANoUndefCallSiteArgument(const IRPosition &IRP, Attributor &A)
10470 : AANoUndefFloating(IRP, A) {}
10471
10472 /// See AbstractAttribute::trackStatistics()
10473 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(noundef) }
10474};
10475
10476struct AANoUndefCallSiteReturned final
10477 : AACalleeToCallSite<AANoUndef, AANoUndefImpl> {
10478 AANoUndefCallSiteReturned(const IRPosition &IRP, Attributor &A)
10479 : AACalleeToCallSite<AANoUndef, AANoUndefImpl>(IRP, A) {}
10480
10481 /// See AbstractAttribute::trackStatistics()
10482 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(noundef) }
10483};
10484
10485/// ------------------------ NoFPClass Attribute -------------------------------
10486
10487struct AANoFPClassImpl : AANoFPClass {
10488 AANoFPClassImpl(const IRPosition &IRP, Attributor &A) : AANoFPClass(IRP, A) {}
10489
10490 void initialize(Attributor &A) override {
10491 const IRPosition &IRP = getIRPosition();
10492
10493 Value &V = IRP.getAssociatedValue();
10494 if (isa<UndefValue>(V)) {
10495 indicateOptimisticFixpoint();
10496 return;
10497 }
10498
10500 A.getAttrs(getIRPosition(), {Attribute::NoFPClass}, Attrs, false);
10501 for (const auto &Attr : Attrs) {
10502 addKnownBits(Attr.getNoFPClass());
10503 }
10504
10505 Instruction *CtxI = getCtxI();
10506
10507 if (getPositionKind() != IRPosition::IRP_RETURNED) {
10508 const DataLayout &DL = A.getDataLayout();
10509 InformationCache &InfoCache = A.getInfoCache();
10510
10511 const DominatorTree *DT = nullptr;
10512 AssumptionCache *AC = nullptr;
10513 const TargetLibraryInfo *TLI = nullptr;
10514 Function *F = getAnchorScope();
10515 if (F) {
10516 TLI = InfoCache.getTargetLibraryInfoForFunction(*F);
10517 if (!F->isDeclaration()) {
10518 DT =
10519 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F);
10520 AC = InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F);
10521 }
10522 }
10523
10524 SimplifyQuery Q(DL, TLI, DT, AC, CtxI);
10525
10526 KnownFPClass KnownFPClass = computeKnownFPClass(&V, fcAllFlags, Q);
10527 addKnownBits(~KnownFPClass.KnownFPClasses);
10528 }
10529
10530 if (CtxI)
10531 followUsesInMBEC(*this, A, getState(), *CtxI);
10532 }
10533
10534 /// See followUsesInMBEC
10535 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
10536 AANoFPClass::StateType &State) {
10537 // TODO: Determine what instructions can be looked through.
10538 auto *CB = dyn_cast<CallBase>(I);
10539 if (!CB)
10540 return false;
10541
10542 if (!CB->isArgOperand(U))
10543 return false;
10544
10545 unsigned ArgNo = CB->getArgOperandNo(U);
10546 IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo);
10547 if (auto *NoFPAA = A.getAAFor<AANoFPClass>(*this, IRP, DepClassTy::NONE))
10548 State.addKnownBits(NoFPAA->getState().getKnown());
10549 return false;
10550 }
10551
10552 const std::string getAsStr(Attributor *A) const override {
10553 std::string Result = "nofpclass";
10554 raw_string_ostream OS(Result);
10555 OS << getKnownNoFPClass() << '/' << getAssumedNoFPClass();
10556 return Result;
10557 }
10558
10559 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
10560 SmallVectorImpl<Attribute> &Attrs) const override {
10561 Attrs.emplace_back(Attribute::getWithNoFPClass(Ctx, getAssumedNoFPClass()));
10562 }
10563};
10564
10565struct AANoFPClassFloating : public AANoFPClassImpl {
10566 AANoFPClassFloating(const IRPosition &IRP, Attributor &A)
10567 : AANoFPClassImpl(IRP, A) {}
10568
10569 /// See AbstractAttribute::updateImpl(...).
10570 ChangeStatus updateImpl(Attributor &A) override {
10572 bool UsedAssumedInformation = false;
10573 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
10574 AA::AnyScope, UsedAssumedInformation)) {
10575 Values.push_back({getAssociatedValue(), getCtxI()});
10576 }
10577
10578 StateType T;
10579 auto VisitValueCB = [&](Value &V, const Instruction *CtxI) -> bool {
10580 const auto *AA = A.getAAFor<AANoFPClass>(*this, IRPosition::value(V),
10581 DepClassTy::REQUIRED);
10582 if (!AA || this == AA) {
10583 T.indicatePessimisticFixpoint();
10584 } else {
10585 const AANoFPClass::StateType &S =
10586 static_cast<const AANoFPClass::StateType &>(AA->getState());
10587 T ^= S;
10588 }
10589 return T.isValidState();
10590 };
10591
10592 for (const auto &VAC : Values)
10593 if (!VisitValueCB(*VAC.getValue(), VAC.getCtxI()))
10594 return indicatePessimisticFixpoint();
10595
10596 return clampStateAndIndicateChange(getState(), T);
10597 }
10598
10599 /// See AbstractAttribute::trackStatistics()
10600 void trackStatistics() const override {
10602 }
10603};
10604
10605struct AANoFPClassReturned final
10606 : AAReturnedFromReturnedValues<AANoFPClass, AANoFPClassImpl,
10607 AANoFPClassImpl::StateType, false,
10608 Attribute::None, false> {
10609 AANoFPClassReturned(const IRPosition &IRP, Attributor &A)
10610 : AAReturnedFromReturnedValues<AANoFPClass, AANoFPClassImpl,
10611 AANoFPClassImpl::StateType, false,
10612 Attribute::None, false>(IRP, A) {}
10613
10614 /// See AbstractAttribute::trackStatistics()
10615 void trackStatistics() const override {
10617 }
10618};
10619
10620struct AANoFPClassArgument final
10621 : AAArgumentFromCallSiteArguments<AANoFPClass, AANoFPClassImpl> {
10622 AANoFPClassArgument(const IRPosition &IRP, Attributor &A)
10623 : AAArgumentFromCallSiteArguments<AANoFPClass, AANoFPClassImpl>(IRP, A) {}
10624
10625 /// See AbstractAttribute::trackStatistics()
10626 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nofpclass) }
10627};
10628
10629struct AANoFPClassCallSiteArgument final : AANoFPClassFloating {
10630 AANoFPClassCallSiteArgument(const IRPosition &IRP, Attributor &A)
10631 : AANoFPClassFloating(IRP, A) {}
10632
10633 /// See AbstractAttribute::trackStatistics()
10634 void trackStatistics() const override {
10636 }
10637};
10638
10639struct AANoFPClassCallSiteReturned final
10640 : AACalleeToCallSite<AANoFPClass, AANoFPClassImpl> {
10641 AANoFPClassCallSiteReturned(const IRPosition &IRP, Attributor &A)
10642 : AACalleeToCallSite<AANoFPClass, AANoFPClassImpl>(IRP, A) {}
10643
10644 /// See AbstractAttribute::trackStatistics()
10645 void trackStatistics() const override {
10647 }
10648};
10649
10650struct AACallEdgesImpl : public AACallEdges {
10651 AACallEdgesImpl(const IRPosition &IRP, Attributor &A) : AACallEdges(IRP, A) {}
10652
10653 const SetVector<Function *> &getOptimisticEdges() const override {
10654 return CalledFunctions;
10655 }
10656
10657 bool hasUnknownCallee() const override { return HasUnknownCallee; }
10658
10659 bool hasNonAsmUnknownCallee() const override {
10660 return HasUnknownCalleeNonAsm;
10661 }
10662
10663 const std::string getAsStr(Attributor *A) const override {
10664 return "CallEdges[" + std::to_string(HasUnknownCallee) + "," +
10665 std::to_string(CalledFunctions.size()) + "]";
10666 }
10667
10668 void trackStatistics() const override {}
10669
10670protected:
10671 void addCalledFunction(Function *Fn, ChangeStatus &Change) {
10672 if (CalledFunctions.insert(Fn)) {
10673 Change = ChangeStatus::CHANGED;
10674 LLVM_DEBUG(dbgs() << "[AACallEdges] New call edge: " << Fn->getName()
10675 << "\n");
10676 }
10677 }
10678
10679 void setHasUnknownCallee(bool NonAsm, ChangeStatus &Change) {
10680 if (!HasUnknownCallee)
10681 Change = ChangeStatus::CHANGED;
10682 if (NonAsm && !HasUnknownCalleeNonAsm)
10683 Change = ChangeStatus::CHANGED;
10684 HasUnknownCalleeNonAsm |= NonAsm;
10685 HasUnknownCallee = true;
10686 }
10687
10688private:
10689 /// Optimistic set of functions that might be called by this position.
10690 SetVector<Function *> CalledFunctions;
10691
10692 /// Is there any call with a unknown callee.
10693 bool HasUnknownCallee = false;
10694
10695 /// Is there any call with a unknown callee, excluding any inline asm.
10696 bool HasUnknownCalleeNonAsm = false;
10697};
10698
10699struct AACallEdgesCallSite : public AACallEdgesImpl {
10700 AACallEdgesCallSite(const IRPosition &IRP, Attributor &A)
10701 : AACallEdgesImpl(IRP, A) {}
10702 /// See AbstractAttribute::updateImpl(...).
10703 ChangeStatus updateImpl(Attributor &A) override {
10704 ChangeStatus Change = ChangeStatus::UNCHANGED;
10705
10706 auto VisitValue = [&](Value &V, const Instruction *CtxI) -> bool {
10707 if (Function *Fn = dyn_cast<Function>(&V)) {
10708 addCalledFunction(Fn, Change);
10709 } else {
10710 LLVM_DEBUG(dbgs() << "[AACallEdges] Unrecognized value: " << V << "\n");
10711 setHasUnknownCallee(true, Change);
10712 }
10713
10714 // Explore all values.
10715 return true;
10716 };
10717
10719 // Process any value that we might call.
10720 auto ProcessCalledOperand = [&](Value *V, Instruction *CtxI) {
10721 if (isa<Constant>(V)) {
10722 VisitValue(*V, CtxI);
10723 return;
10724 }
10725
10726 bool UsedAssumedInformation = false;
10727 Values.clear();
10728 if (!A.getAssumedSimplifiedValues(IRPosition::value(*V), *this, Values,
10729 AA::AnyScope, UsedAssumedInformation)) {
10730 Values.push_back({*V, CtxI});
10731 }
10732 for (auto &VAC : Values)
10733 VisitValue(*VAC.getValue(), VAC.getCtxI());
10734 };
10735
10736 CallBase *CB = cast<CallBase>(getCtxI());
10737
10738 if (auto *IA = dyn_cast<InlineAsm>(CB->getCalledOperand())) {
10739 if (IA->hasSideEffects() &&
10740 !hasAssumption(*CB->getCaller(), "ompx_no_call_asm") &&
10741 !hasAssumption(*CB, "ompx_no_call_asm")) {
10742 setHasUnknownCallee(false, Change);
10743 }
10744 return Change;
10745 }
10746
10747 if (CB->isIndirectCall())
10748 if (auto *IndirectCallAA = A.getAAFor<AAIndirectCallInfo>(
10749 *this, getIRPosition(), DepClassTy::OPTIONAL))
10750 if (IndirectCallAA->foreachCallee(
10751 [&](Function *Fn) { return VisitValue(*Fn, CB); }))
10752 return Change;
10753
10754 // The most simple case.
10755 ProcessCalledOperand(CB->getCalledOperand(), CB);
10756
10757 // Process callback functions.
10758 SmallVector<const Use *, 4u> CallbackUses;
10759 AbstractCallSite::getCallbackUses(*CB, CallbackUses);
10760 for (const Use *U : CallbackUses)
10761 ProcessCalledOperand(U->get(), CB);
10762
10763 return Change;
10764 }
10765};
10766
10767struct AACallEdgesFunction : public AACallEdgesImpl {
10768 AACallEdgesFunction(const IRPosition &IRP, Attributor &A)
10769 : AACallEdgesImpl(IRP, A) {}
10770
10771 /// See AbstractAttribute::updateImpl(...).
10772 ChangeStatus updateImpl(Attributor &A) override {
10773 ChangeStatus Change = ChangeStatus::UNCHANGED;
10774
10775 auto ProcessCallInst = [&](Instruction &Inst) {
10776 CallBase &CB = cast<CallBase>(Inst);
10777
10778 auto *CBEdges = A.getAAFor<AACallEdges>(
10779 *this, IRPosition::callsite_function(CB), DepClassTy::REQUIRED);
10780 if (!CBEdges)
10781 return false;
10782 if (CBEdges->hasNonAsmUnknownCallee())
10783 setHasUnknownCallee(true, Change);
10784 if (CBEdges->hasUnknownCallee())
10785 setHasUnknownCallee(false, Change);
10786
10787 for (Function *F : CBEdges->getOptimisticEdges())
10788 addCalledFunction(F, Change);
10789
10790 return true;
10791 };
10792
10793 // Visit all callable instructions.
10794 bool UsedAssumedInformation = false;
10795 if (!A.checkForAllCallLikeInstructions(ProcessCallInst, *this,
10796 UsedAssumedInformation,
10797 /* CheckBBLivenessOnly */ true)) {
10798 // If we haven't looked at all call like instructions, assume that there
10799 // are unknown callees.
10800 setHasUnknownCallee(true, Change);
10801 }
10802
10803 return Change;
10804 }
10805};
10806
10807/// -------------------AAInterFnReachability Attribute--------------------------
10808
10809struct AAInterFnReachabilityFunction
10810 : public CachedReachabilityAA<AAInterFnReachability, Function> {
10811 using Base = CachedReachabilityAA<AAInterFnReachability, Function>;
10812 AAInterFnReachabilityFunction(const IRPosition &IRP, Attributor &A)
10813 : Base(IRP, A) {}
10814
10815 bool instructionCanReach(
10816 Attributor &A, const Instruction &From, const Function &To,
10817 const AA::InstExclusionSetTy *ExclusionSet) const override {
10818 assert(From.getFunction() == getAnchorScope() && "Queried the wrong AA!");
10819 auto *NonConstThis = const_cast<AAInterFnReachabilityFunction *>(this);
10820
10821 RQITy StackRQI(A, From, To, ExclusionSet, false);
10822 RQITy::Reachable Result;
10823 if (!NonConstThis->checkQueryCache(A, StackRQI, Result))
10824 return NonConstThis->isReachableImpl(A, StackRQI,
10825 /*IsTemporaryRQI=*/true);
10826 return Result == RQITy::Reachable::Yes;
10827 }
10828
10829 bool isReachableImpl(Attributor &A, RQITy &RQI,
10830 bool IsTemporaryRQI) override {
10831 const Instruction *EntryI =
10832 &RQI.From->getFunction()->getEntryBlock().front();
10833 if (EntryI != RQI.From &&
10834 !instructionCanReach(A, *EntryI, *RQI.To, nullptr))
10835 return rememberResult(A, RQITy::Reachable::No, RQI, false,
10836 IsTemporaryRQI);
10837
10838 auto CheckReachableCallBase = [&](CallBase *CB) {
10839 auto *CBEdges = A.getAAFor<AACallEdges>(
10840 *this, IRPosition::callsite_function(*CB), DepClassTy::OPTIONAL);
10841 if (!CBEdges || !CBEdges->getState().isValidState())
10842 return false;
10843 // TODO Check To backwards in this case.
10844 if (CBEdges->hasUnknownCallee())
10845 return false;
10846
10847 for (Function *Fn : CBEdges->getOptimisticEdges()) {
10848 if (Fn == RQI.To)
10849 return false;
10850
10851 if (Fn->isDeclaration()) {
10852 if (Fn->hasFnAttribute(Attribute::NoCallback))
10853 continue;
10854 // TODO Check To backwards in this case.
10855 return false;
10856 }
10857
10858 if (Fn == getAnchorScope()) {
10859 if (EntryI == RQI.From)
10860 continue;
10861 return false;
10862 }
10863
10864 const AAInterFnReachability *InterFnReachability =
10865 A.getAAFor<AAInterFnReachability>(*this, IRPosition::function(*Fn),
10866 DepClassTy::OPTIONAL);
10867
10868 const Instruction &FnFirstInst = Fn->getEntryBlock().front();
10869 if (!InterFnReachability ||
10870 InterFnReachability->instructionCanReach(A, FnFirstInst, *RQI.To,
10871 RQI.ExclusionSet))
10872 return false;
10873 }
10874 return true;
10875 };
10876
10877 const auto *IntraFnReachability = A.getAAFor<AAIntraFnReachability>(
10878 *this, IRPosition::function(*RQI.From->getFunction()),
10879 DepClassTy::OPTIONAL);
10880
10881 // Determine call like instructions that we can reach from the inst.
10882 auto CheckCallBase = [&](Instruction &CBInst) {
10883 // There are usually less nodes in the call graph, check inter function
10884 // reachability first.
10885 if (CheckReachableCallBase(cast<CallBase>(&CBInst)))
10886 return true;
10887 return IntraFnReachability && !IntraFnReachability->isAssumedReachable(
10888 A, *RQI.From, CBInst, RQI.ExclusionSet);
10889 };
10890
10891 bool UsedExclusionSet = /* conservative */ true;
10892 bool UsedAssumedInformation = false;
10893 if (!A.checkForAllCallLikeInstructions(CheckCallBase, *this,
10894 UsedAssumedInformation,
10895 /* CheckBBLivenessOnly */ true))
10896 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
10897 IsTemporaryRQI);
10898
10899 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
10900 IsTemporaryRQI);
10901 }
10902
10903 void trackStatistics() const override {}
10904};
10905} // namespace
10906
10907template <typename AAType>
10908static std::optional<Constant *>
10910 const IRPosition &IRP, Type &Ty) {
10911 if (!Ty.isIntegerTy())
10912 return nullptr;
10913
10914 // This will also pass the call base context.
10915 const auto *AA = A.getAAFor<AAType>(QueryingAA, IRP, DepClassTy::NONE);
10916 if (!AA)
10917 return nullptr;
10918
10919 std::optional<Constant *> COpt = AA->getAssumedConstant(A);
10920
10921 if (!COpt.has_value()) {
10922 A.recordDependence(*AA, QueryingAA, DepClassTy::OPTIONAL);
10923 return std::nullopt;
10924 }
10925 if (auto *C = *COpt) {
10926 A.recordDependence(*AA, QueryingAA, DepClassTy::OPTIONAL);
10927 return C;
10928 }
10929 return nullptr;
10930}
10931
10933 Attributor &A, const AbstractAttribute &AA, const IRPosition &IRP,
10935 Type &Ty = *IRP.getAssociatedType();
10936 std::optional<Value *> V;
10937 for (auto &It : Values) {
10938 V = AA::combineOptionalValuesInAAValueLatice(V, It.getValue(), &Ty);
10939 if (V.has_value() && !*V)
10940 break;
10941 }
10942 if (!V.has_value())
10943 return UndefValue::get(&Ty);
10944 return *V;
10945}
10946
10947namespace {
10948struct AAPotentialValuesImpl : AAPotentialValues {
10949 using StateType = PotentialLLVMValuesState;
10950
10951 AAPotentialValuesImpl(const IRPosition &IRP, Attributor &A)
10952 : AAPotentialValues(IRP, A) {}
10953
10954 /// See AbstractAttribute::initialize(..).
10955 void initialize(Attributor &A) override {
10956 if (A.hasSimplificationCallback(getIRPosition())) {
10957 indicatePessimisticFixpoint();
10958 return;
10959 }
10960 Value *Stripped = getAssociatedValue().stripPointerCasts();
10961 if (isa<Constant>(Stripped) && !isa<ConstantExpr>(Stripped)) {
10962 addValue(A, getState(), *Stripped, getCtxI(), AA::AnyScope,
10963 getAnchorScope());
10964 indicateOptimisticFixpoint();
10965 return;
10966 }
10967 AAPotentialValues::initialize(A);
10968 }
10969
10970 /// See AbstractAttribute::getAsStr().
10971 const std::string getAsStr(Attributor *A) const override {
10972 std::string Str;
10973 llvm::raw_string_ostream OS(Str);
10974 OS << getState();
10975 return Str;
10976 }
10977
10978 template <typename AAType>
10979 static std::optional<Value *> askOtherAA(Attributor &A,
10980 const AbstractAttribute &AA,
10981 const IRPosition &IRP, Type &Ty) {
10983 return &IRP.getAssociatedValue();
10984 std::optional<Constant *> C = askForAssumedConstant<AAType>(A, AA, IRP, Ty);
10985 if (!C)
10986 return std::nullopt;
10987 if (*C)
10988 if (auto *CC = AA::getWithType(**C, Ty))
10989 return CC;
10990 return nullptr;
10991 }
10992
10993 virtual void addValue(Attributor &A, StateType &State, Value &V,
10994 const Instruction *CtxI, AA::ValueScope S,
10995 Function *AnchorScope) const {
10996
10997 IRPosition ValIRP = IRPosition::value(V);
10998 if (auto *CB = dyn_cast_or_null<CallBase>(CtxI)) {
10999 for (const auto &U : CB->args()) {
11000 if (U.get() != &V)
11001 continue;
11002 ValIRP = IRPosition::callsite_argument(*CB, CB->getArgOperandNo(&U));
11003 break;
11004 }
11005 }
11006
11007 Value *VPtr = &V;
11008 if (ValIRP.getAssociatedType()->isIntegerTy()) {
11009 Type &Ty = *getAssociatedType();
11010 std::optional<Value *> SimpleV =
11011 askOtherAA<AAValueConstantRange>(A, *this, ValIRP, Ty);
11012 if (SimpleV.has_value() && !*SimpleV) {
11013 auto *PotentialConstantsAA = A.getAAFor<AAPotentialConstantValues>(
11014 *this, ValIRP, DepClassTy::OPTIONAL);
11015 if (PotentialConstantsAA && PotentialConstantsAA->isValidState()) {
11016 for (const auto &It : PotentialConstantsAA->getAssumedSet())
11017 State.unionAssumed({{*ConstantInt::get(&Ty, It), nullptr}, S});
11018 if (PotentialConstantsAA->undefIsContained())
11019 State.unionAssumed({{*UndefValue::get(&Ty), nullptr}, S});
11020 return;
11021 }
11022 }
11023 if (!SimpleV.has_value())
11024 return;
11025
11026 if (*SimpleV)
11027 VPtr = *SimpleV;
11028 }
11029
11030 if (isa<ConstantInt>(VPtr))
11031 CtxI = nullptr;
11032 if (!AA::isValidInScope(*VPtr, AnchorScope))
11034
11035 State.unionAssumed({{*VPtr, CtxI}, S});
11036 }
11037
11038 /// Helper struct to tie a value+context pair together with the scope for
11039 /// which this is the simplified version.
11040 struct ItemInfo {
11041 AA::ValueAndContext I;
11043
11044 bool operator==(const ItemInfo &II) const {
11045 return II.I == I && II.S == S;
11046 };
11047 bool operator<(const ItemInfo &II) const {
11048 return std::tie(I, S) < std::tie(II.I, II.S);
11049 };
11050 };
11051
11052 bool recurseForValue(Attributor &A, const IRPosition &IRP, AA::ValueScope S) {
11053 SmallMapVector<AA::ValueAndContext, int, 8> ValueScopeMap;
11054 for (auto CS : {AA::Intraprocedural, AA::Interprocedural}) {
11055 if (!(CS & S))
11056 continue;
11057
11058 bool UsedAssumedInformation = false;
11060 if (!A.getAssumedSimplifiedValues(IRP, this, Values, CS,
11061 UsedAssumedInformation))
11062 return false;
11063
11064 for (auto &It : Values)
11065 ValueScopeMap[It] += CS;
11066 }
11067 for (auto &It : ValueScopeMap)
11068 addValue(A, getState(), *It.first.getValue(), It.first.getCtxI(),
11069 AA::ValueScope(It.second), getAnchorScope());
11070
11071 return true;
11072 }
11073
11074 void giveUpOnIntraprocedural(Attributor &A) {
11075 auto NewS = StateType::getBestState(getState());
11076 for (const auto &It : getAssumedSet()) {
11077 if (It.second == AA::Intraprocedural)
11078 continue;
11079 addValue(A, NewS, *It.first.getValue(), It.first.getCtxI(),
11080 AA::Interprocedural, getAnchorScope());
11081 }
11082 assert(!undefIsContained() && "Undef should be an explicit value!");
11083 addValue(A, NewS, getAssociatedValue(), getCtxI(), AA::Intraprocedural,
11084 getAnchorScope());
11085 getState() = NewS;
11086 }
11087
11088 /// See AbstractState::indicatePessimisticFixpoint(...).
11089 ChangeStatus indicatePessimisticFixpoint() override {
11090 getState() = StateType::getBestState(getState());
11091 getState().unionAssumed({{getAssociatedValue(), getCtxI()}, AA::AnyScope});
11092 AAPotentialValues::indicateOptimisticFixpoint();
11093 return ChangeStatus::CHANGED;
11094 }
11095
11096 /// See AbstractAttribute::updateImpl(...).
11097 ChangeStatus updateImpl(Attributor &A) override {
11098 return indicatePessimisticFixpoint();
11099 }
11100
11101 /// See AbstractAttribute::manifest(...).
11102 ChangeStatus manifest(Attributor &A) override {
11105 Values.clear();
11106 if (!getAssumedSimplifiedValues(A, Values, S))
11107 continue;
11108 Value &OldV = getAssociatedValue();
11109 if (isa<UndefValue>(OldV))
11110 continue;
11111 Value *NewV = getSingleValue(A, *this, getIRPosition(), Values);
11112 if (!NewV || NewV == &OldV)
11113 continue;
11114 if (getCtxI() &&
11115 !AA::isValidAtPosition({*NewV, *getCtxI()}, A.getInfoCache()))
11116 continue;
11117 if (A.changeAfterManifest(getIRPosition(), *NewV))
11118 return ChangeStatus::CHANGED;
11119 }
11120 return ChangeStatus::UNCHANGED;
11121 }
11122
11123 bool getAssumedSimplifiedValues(
11124 Attributor &A, SmallVectorImpl<AA::ValueAndContext> &Values,
11125 AA::ValueScope S, bool RecurseForSelectAndPHI = false) const override {
11126 if (!isValidState())
11127 return false;
11128 bool UsedAssumedInformation = false;
11129 for (const auto &It : getAssumedSet())
11130 if (It.second & S) {
11131 if (RecurseForSelectAndPHI && (isa<PHINode>(It.first.getValue()) ||
11132 isa<SelectInst>(It.first.getValue()))) {
11133 if (A.getAssumedSimplifiedValues(
11134 IRPosition::inst(*cast<Instruction>(It.first.getValue())),
11135 this, Values, S, UsedAssumedInformation))
11136 continue;
11137 }
11138 Values.push_back(It.first);
11139 }
11140 assert(!undefIsContained() && "Undef should be an explicit value!");
11141 return true;
11142 }
11143};
11144
11145struct AAPotentialValuesFloating : AAPotentialValuesImpl {
11146 AAPotentialValuesFloating(const IRPosition &IRP, Attributor &A)
11147 : AAPotentialValuesImpl(IRP, A) {}
11148
11149 /// See AbstractAttribute::updateImpl(...).
11150 ChangeStatus updateImpl(Attributor &A) override {
11151 auto AssumedBefore = getAssumed();
11152
11153 genericValueTraversal(A, &getAssociatedValue());
11154
11155 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
11156 : ChangeStatus::CHANGED;
11157 }
11158
11159 /// Helper struct to remember which AAIsDead instances we actually used.
11160 struct LivenessInfo {
11161 const AAIsDead *LivenessAA = nullptr;
11162 bool AnyDead = false;
11163 };
11164
11165 /// Check if \p Cmp is a comparison we can simplify.
11166 ///
11167 /// We handle multiple cases, one in which at least one operand is an
11168 /// (assumed) nullptr. If so, try to simplify it using AANonNull on the other
11169 /// operand. Return true if successful, in that case Worklist will be updated.
11170 bool handleCmp(Attributor &A, Value &Cmp, Value *LHS, Value *RHS,
11171 CmpInst::Predicate Pred, ItemInfo II,
11172 SmallVectorImpl<ItemInfo> &Worklist) {
11173
11174 // Simplify the operands first.
11175 bool UsedAssumedInformation = false;
11176 SmallVector<AA::ValueAndContext> LHSValues, RHSValues;
11177 auto GetSimplifiedValues = [&](Value &V,
11179 if (!A.getAssumedSimplifiedValues(
11180 IRPosition::value(V, getCallBaseContext()), this, Values,
11181 AA::Intraprocedural, UsedAssumedInformation)) {
11182 Values.clear();
11183 Values.push_back(AA::ValueAndContext{V, II.I.getCtxI()});
11184 }
11185 return Values.empty();
11186 };
11187 if (GetSimplifiedValues(*LHS, LHSValues))
11188 return true;
11189 if (GetSimplifiedValues(*RHS, RHSValues))
11190 return true;
11191
11192 LLVMContext &Ctx = LHS->getContext();
11193
11194 InformationCache &InfoCache = A.getInfoCache();
11195 Instruction *CmpI = dyn_cast<Instruction>(&Cmp);
11196 Function *F = CmpI ? CmpI->getFunction() : nullptr;
11197 const auto *DT =
11198 F ? InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F)
11199 : nullptr;
11200 const auto *TLI =
11201 F ? A.getInfoCache().getTargetLibraryInfoForFunction(*F) : nullptr;
11202 auto *AC =
11203 F ? InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F)
11204 : nullptr;
11205
11206 const DataLayout &DL = A.getDataLayout();
11207 SimplifyQuery Q(DL, TLI, DT, AC, CmpI);
11208
11209 auto CheckPair = [&](Value &LHSV, Value &RHSV) {
11210 if (isa<UndefValue>(LHSV) || isa<UndefValue>(RHSV)) {
11211 addValue(A, getState(), *UndefValue::get(Cmp.getType()),
11212 /* CtxI */ nullptr, II.S, getAnchorScope());
11213 return true;
11214 }
11215
11216 // Handle the trivial case first in which we don't even need to think
11217 // about null or non-null.
11218 if (&LHSV == &RHSV &&
11220 Constant *NewV = ConstantInt::get(Type::getInt1Ty(Ctx),
11222 addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S,
11223 getAnchorScope());
11224 return true;
11225 }
11226
11227 auto *TypedLHS = AA::getWithType(LHSV, *LHS->getType());
11228 auto *TypedRHS = AA::getWithType(RHSV, *RHS->getType());
11229 if (TypedLHS && TypedRHS) {
11230 Value *NewV = simplifyCmpInst(Pred, TypedLHS, TypedRHS, Q);
11231 if (NewV && NewV != &Cmp) {
11232 addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S,
11233 getAnchorScope());
11234 return true;
11235 }
11236 }
11237
11238 // From now on we only handle equalities (==, !=).
11239 if (!CmpInst::isEquality(Pred))
11240 return false;
11241
11242 bool LHSIsNull = isa<ConstantPointerNull>(LHSV);
11243 bool RHSIsNull = isa<ConstantPointerNull>(RHSV);
11244 if (!LHSIsNull && !RHSIsNull)
11245 return false;
11246
11247 // Left is the nullptr ==/!= non-nullptr case. We'll use AANonNull on the
11248 // non-nullptr operand and if we assume it's non-null we can conclude the
11249 // result of the comparison.
11250 assert((LHSIsNull || RHSIsNull) &&
11251 "Expected nullptr versus non-nullptr comparison at this point");
11252
11253 // The index is the operand that we assume is not null.
11254 unsigned PtrIdx = LHSIsNull;
11255 bool IsKnownNonNull;
11256 bool IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>(
11257 A, this, IRPosition::value(*(PtrIdx ? &RHSV : &LHSV)),
11258 DepClassTy::REQUIRED, IsKnownNonNull);
11259 if (!IsAssumedNonNull)
11260 return false;
11261
11262 // The new value depends on the predicate, true for != and false for ==.
11263 Constant *NewV =
11264 ConstantInt::get(Type::getInt1Ty(Ctx), Pred == CmpInst::ICMP_NE);
11265 addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S,
11266 getAnchorScope());
11267 return true;
11268 };
11269
11270 for (auto &LHSValue : LHSValues)
11271 for (auto &RHSValue : RHSValues)
11272 if (!CheckPair(*LHSValue.getValue(), *RHSValue.getValue()))
11273 return false;
11274 return true;
11275 }
11276
11277 bool handleSelectInst(Attributor &A, SelectInst &SI, ItemInfo II,
11278 SmallVectorImpl<ItemInfo> &Worklist) {
11279 const Instruction *CtxI = II.I.getCtxI();
11280 bool UsedAssumedInformation = false;
11281
11282 std::optional<Constant *> C =
11283 A.getAssumedConstant(*SI.getCondition(), *this, UsedAssumedInformation);
11284 bool NoValueYet = !C.has_value();
11285 if (NoValueYet || isa_and_nonnull<UndefValue>(*C))
11286 return true;
11287 if (auto *CI = dyn_cast_or_null<ConstantInt>(*C)) {
11288 if (CI->isZero())
11289 Worklist.push_back({{*SI.getFalseValue(), CtxI}, II.S});
11290 else
11291 Worklist.push_back({{*SI.getTrueValue(), CtxI}, II.S});
11292 } else if (&SI == &getAssociatedValue()) {
11293 // We could not simplify the condition, assume both values.
11294 Worklist.push_back({{*SI.getTrueValue(), CtxI}, II.S});
11295 Worklist.push_back({{*SI.getFalseValue(), CtxI}, II.S});
11296 } else {
11297 std::optional<Value *> SimpleV = A.getAssumedSimplified(
11298 IRPosition::inst(SI), *this, UsedAssumedInformation, II.S);
11299 if (!SimpleV.has_value())
11300 return true;
11301 if (*SimpleV) {
11302 addValue(A, getState(), **SimpleV, CtxI, II.S, getAnchorScope());
11303 return true;
11304 }
11305 return false;
11306 }
11307 return true;
11308 }
11309
11310 bool handleLoadInst(Attributor &A, LoadInst &LI, ItemInfo II,
11311 SmallVectorImpl<ItemInfo> &Worklist) {
11312 SmallSetVector<Value *, 4> PotentialCopies;
11313 SmallSetVector<Instruction *, 4> PotentialValueOrigins;
11314 bool UsedAssumedInformation = false;
11315 if (!AA::getPotentiallyLoadedValues(A, LI, PotentialCopies,
11316 PotentialValueOrigins, *this,
11317 UsedAssumedInformation,
11318 /* OnlyExact */ true)) {
11319 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Failed to get potentially "
11320 "loaded values for load instruction "
11321 << LI << "\n");
11322 return false;
11323 }
11324
11325 // Do not simplify loads that are only used in llvm.assume if we cannot also
11326 // remove all stores that may feed into the load. The reason is that the
11327 // assume is probably worth something as long as the stores are around.
11328 InformationCache &InfoCache = A.getInfoCache();
11329 if (InfoCache.isOnlyUsedByAssume(LI)) {
11330 if (!llvm::all_of(PotentialValueOrigins, [&](Instruction *I) {
11331 if (!I || isa<AssumeInst>(I))
11332 return true;
11333 if (auto *SI = dyn_cast<StoreInst>(I))
11334 return A.isAssumedDead(SI->getOperandUse(0), this,
11335 /* LivenessAA */ nullptr,
11336 UsedAssumedInformation,
11337 /* CheckBBLivenessOnly */ false);
11338 return A.isAssumedDead(*I, this, /* LivenessAA */ nullptr,
11339 UsedAssumedInformation,
11340 /* CheckBBLivenessOnly */ false);
11341 })) {
11342 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Load is onl used by assumes "
11343 "and we cannot delete all the stores: "
11344 << LI << "\n");
11345 return false;
11346 }
11347 }
11348
11349 // Values have to be dynamically unique or we loose the fact that a
11350 // single llvm::Value might represent two runtime values (e.g.,
11351 // stack locations in different recursive calls).
11352 const Instruction *CtxI = II.I.getCtxI();
11353 bool ScopeIsLocal = (II.S & AA::Intraprocedural);
11354 bool AllLocal = ScopeIsLocal;
11355 bool DynamicallyUnique = llvm::all_of(PotentialCopies, [&](Value *PC) {
11356 AllLocal &= AA::isValidInScope(*PC, getAnchorScope());
11357 return AA::isDynamicallyUnique(A, *this, *PC);
11358 });
11359 if (!DynamicallyUnique) {
11360 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Not all potentially loaded "
11361 "values are dynamically unique: "
11362 << LI << "\n");
11363 return false;
11364 }
11365
11366 for (auto *PotentialCopy : PotentialCopies) {
11367 if (AllLocal) {
11368 Worklist.push_back({{*PotentialCopy, CtxI}, II.S});
11369 } else {
11370 Worklist.push_back({{*PotentialCopy, CtxI}, AA::Interprocedural});
11371 }
11372 }
11373 if (!AllLocal && ScopeIsLocal)
11374 addValue(A, getState(), LI, CtxI, AA::Intraprocedural, getAnchorScope());
11375 return true;
11376 }
11377
11378 bool handlePHINode(
11379 Attributor &A, PHINode &PHI, ItemInfo II,
11380 SmallVectorImpl<ItemInfo> &Worklist,
11381 SmallMapVector<const Function *, LivenessInfo, 4> &LivenessAAs) {
11382 auto GetLivenessInfo = [&](const Function &F) -> LivenessInfo & {
11383 LivenessInfo &LI = LivenessAAs[&F];
11384 if (!LI.LivenessAA)
11385 LI.LivenessAA = A.getAAFor<AAIsDead>(*this, IRPosition::function(F),
11386 DepClassTy::NONE);
11387 return LI;
11388 };
11389
11390 if (&PHI == &getAssociatedValue()) {
11391 LivenessInfo &LI = GetLivenessInfo(*PHI.getFunction());
11392 const auto *CI =
11393 A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>(
11394 *PHI.getFunction());
11395
11396 Cycle *C = nullptr;
11397 bool CyclePHI = mayBeInCycle(CI, &PHI, /* HeaderOnly */ true, &C);
11398 for (unsigned u = 0, e = PHI.getNumIncomingValues(); u < e; u++) {
11399 BasicBlock *IncomingBB = PHI.getIncomingBlock(u);
11400 if (LI.LivenessAA &&
11401 LI.LivenessAA->isEdgeDead(IncomingBB, PHI.getParent())) {
11402 LI.AnyDead = true;
11403 continue;
11404 }
11405 Value *V = PHI.getIncomingValue(u);
11406 if (V == &PHI)
11407 continue;
11408
11409 // If the incoming value is not the PHI but an instruction in the same
11410 // cycle we might have multiple versions of it flying around.
11411 if (CyclePHI && isa<Instruction>(V) &&
11412 (!C || C->contains(cast<Instruction>(V)->getParent())))
11413 return false;
11414
11415 Worklist.push_back({{*V, IncomingBB->getTerminator()}, II.S});
11416 }
11417 return true;
11418 }
11419
11420 bool UsedAssumedInformation = false;
11421 std::optional<Value *> SimpleV = A.getAssumedSimplified(
11422 IRPosition::inst(PHI), *this, UsedAssumedInformation, II.S);
11423 if (!SimpleV.has_value())
11424 return true;
11425 if (!(*SimpleV))
11426 return false;
11427 addValue(A, getState(), **SimpleV, &PHI, II.S, getAnchorScope());
11428 return true;
11429 }
11430
11431 /// Use the generic, non-optimistic InstSimplfy functionality if we managed to
11432 /// simplify any operand of the instruction \p I. Return true if successful,
11433 /// in that case Worklist will be updated.
11434 bool handleGenericInst(Attributor &A, Instruction &I, ItemInfo II,
11435 SmallVectorImpl<ItemInfo> &Worklist) {
11436 bool SomeSimplified = false;
11437 bool UsedAssumedInformation = false;
11438
11439 SmallVector<Value *, 8> NewOps(I.getNumOperands());
11440 int Idx = 0;
11441 for (Value *Op : I.operands()) {
11442 const auto &SimplifiedOp = A.getAssumedSimplified(
11443 IRPosition::value(*Op, getCallBaseContext()), *this,
11444 UsedAssumedInformation, AA::Intraprocedural);
11445 // If we are not sure about any operand we are not sure about the entire
11446 // instruction, we'll wait.
11447 if (!SimplifiedOp.has_value())
11448 return true;
11449
11450 if (*SimplifiedOp)
11451 NewOps[Idx] = *SimplifiedOp;
11452 else
11453 NewOps[Idx] = Op;
11454
11455 SomeSimplified |= (NewOps[Idx] != Op);
11456 ++Idx;
11457 }
11458
11459 // We won't bother with the InstSimplify interface if we didn't simplify any
11460 // operand ourselves.
11461 if (!SomeSimplified)
11462 return false;
11463
11464 InformationCache &InfoCache = A.getInfoCache();
11465 Function *F = I.getFunction();
11466 const auto *DT =
11467 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F);
11468 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
11469 auto *AC = InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F);
11470
11471 const DataLayout &DL = I.getDataLayout();
11472 SimplifyQuery Q(DL, TLI, DT, AC, &I);
11473 Value *NewV = simplifyInstructionWithOperands(&I, NewOps, Q);
11474 if (!NewV || NewV == &I)
11475 return false;
11476
11477 LLVM_DEBUG(dbgs() << "Generic inst " << I << " assumed simplified to "
11478 << *NewV << "\n");
11479 Worklist.push_back({{*NewV, II.I.getCtxI()}, II.S});
11480 return true;
11481 }
11482
11484 Attributor &A, Instruction &I, ItemInfo II,
11485 SmallVectorImpl<ItemInfo> &Worklist,
11486 SmallMapVector<const Function *, LivenessInfo, 4> &LivenessAAs) {
11487 if (auto *CI = dyn_cast<CmpInst>(&I))
11488 return handleCmp(A, *CI, CI->getOperand(0), CI->getOperand(1),
11489 CI->getPredicate(), II, Worklist);
11490
11491 switch (I.getOpcode()) {
11492 case Instruction::Select:
11493 return handleSelectInst(A, cast<SelectInst>(I), II, Worklist);
11494 case Instruction::PHI:
11495 return handlePHINode(A, cast<PHINode>(I), II, Worklist, LivenessAAs);
11496 case Instruction::Load:
11497 return handleLoadInst(A, cast<LoadInst>(I), II, Worklist);
11498 default:
11499 return handleGenericInst(A, I, II, Worklist);
11500 };
11501 return false;
11502 }
11503
11504 void genericValueTraversal(Attributor &A, Value *InitialV) {
11505 SmallMapVector<const Function *, LivenessInfo, 4> LivenessAAs;
11506
11507 SmallSet<ItemInfo, 16> Visited;
11509 Worklist.push_back({{*InitialV, getCtxI()}, AA::AnyScope});
11510
11511 int Iteration = 0;
11512 do {
11513 ItemInfo II = Worklist.pop_back_val();
11514 Value *V = II.I.getValue();
11515 assert(V);
11516 const Instruction *CtxI = II.I.getCtxI();
11517 AA::ValueScope S = II.S;
11518
11519 // Check if we should process the current value. To prevent endless
11520 // recursion keep a record of the values we followed!
11521 if (!Visited.insert(II).second)
11522 continue;
11523
11524 // Make sure we limit the compile time for complex expressions.
11525 if (Iteration++ >= MaxPotentialValuesIterations) {
11526 LLVM_DEBUG(dbgs() << "Generic value traversal reached iteration limit: "
11527 << Iteration << "!\n");
11528 addValue(A, getState(), *V, CtxI, S, getAnchorScope());
11529 continue;
11530 }
11531
11532 // Explicitly look through calls with a "returned" attribute if we do
11533 // not have a pointer as stripPointerCasts only works on them.
11534 Value *NewV = nullptr;
11535 if (V->getType()->isPointerTy()) {
11536 NewV = AA::getWithType(*V->stripPointerCasts(), *V->getType());
11537 } else {
11538 if (auto *CB = dyn_cast<CallBase>(V))
11539 if (auto *Callee =
11541 for (Argument &Arg : Callee->args())
11542 if (Arg.hasReturnedAttr()) {
11543 NewV = CB->getArgOperand(Arg.getArgNo());
11544 break;
11545 }
11546 }
11547 }
11548 if (NewV && NewV != V) {
11549 Worklist.push_back({{*NewV, CtxI}, S});
11550 continue;
11551 }
11552
11553 if (auto *I = dyn_cast<Instruction>(V)) {
11554 if (simplifyInstruction(A, *I, II, Worklist, LivenessAAs))
11555 continue;
11556 }
11557
11558 if (V != InitialV || isa<Argument>(V))
11559 if (recurseForValue(A, IRPosition::value(*V), II.S))
11560 continue;
11561
11562 // If we haven't stripped anything we give up.
11563 if (V == InitialV && CtxI == getCtxI()) {
11564 indicatePessimisticFixpoint();
11565 return;
11566 }
11567
11568 addValue(A, getState(), *V, CtxI, S, getAnchorScope());
11569 } while (!Worklist.empty());
11570
11571 // If we actually used liveness information so we have to record a
11572 // dependence.
11573 for (auto &It : LivenessAAs)
11574 if (It.second.AnyDead)
11575 A.recordDependence(*It.second.LivenessAA, *this, DepClassTy::OPTIONAL);
11576 }
11577
11578 /// See AbstractAttribute::trackStatistics()
11579 void trackStatistics() const override {
11580 STATS_DECLTRACK_FLOATING_ATTR(potential_values)
11581 }
11582};
11583
11584struct AAPotentialValuesArgument final : AAPotentialValuesImpl {
11585 using Base = AAPotentialValuesImpl;
11586 AAPotentialValuesArgument(const IRPosition &IRP, Attributor &A)
11587 : Base(IRP, A) {}
11588
11589 /// See AbstractAttribute::initialize(..).
11590 void initialize(Attributor &A) override {
11591 auto &Arg = cast<Argument>(getAssociatedValue());
11593 indicatePessimisticFixpoint();
11594 }
11595
11596 /// See AbstractAttribute::updateImpl(...).
11597 ChangeStatus updateImpl(Attributor &A) override {
11598 auto AssumedBefore = getAssumed();
11599
11600 unsigned ArgNo = getCalleeArgNo();
11601
11602 bool UsedAssumedInformation = false;
11604 auto CallSitePred = [&](AbstractCallSite ACS) {
11605 const auto CSArgIRP = IRPosition::callsite_argument(ACS, ArgNo);
11606 if (CSArgIRP.getPositionKind() == IRP_INVALID)
11607 return false;
11608
11609 if (!A.getAssumedSimplifiedValues(CSArgIRP, this, Values,
11611 UsedAssumedInformation))
11612 return false;
11613
11614 return isValidState();
11615 };
11616
11617 if (!A.checkForAllCallSites(CallSitePred, *this,
11618 /* RequireAllCallSites */ true,
11619 UsedAssumedInformation))
11620 return indicatePessimisticFixpoint();
11621
11622 Function *Fn = getAssociatedFunction();
11623 bool AnyNonLocal = false;
11624 for (auto &It : Values) {
11625 if (isa<Constant>(It.getValue())) {
11626 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::AnyScope,
11627 getAnchorScope());
11628 continue;
11629 }
11630 if (!AA::isDynamicallyUnique(A, *this, *It.getValue()))
11631 return indicatePessimisticFixpoint();
11632
11633 if (auto *Arg = dyn_cast<Argument>(It.getValue()))
11634 if (Arg->getParent() == Fn) {
11635 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::AnyScope,
11636 getAnchorScope());
11637 continue;
11638 }
11639 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::Interprocedural,
11640 getAnchorScope());
11641 AnyNonLocal = true;
11642 }
11643 assert(!undefIsContained() && "Undef should be an explicit value!");
11644 if (AnyNonLocal)
11645 giveUpOnIntraprocedural(A);
11646
11647 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
11648 : ChangeStatus::CHANGED;
11649 }
11650
11651 /// See AbstractAttribute::trackStatistics()
11652 void trackStatistics() const override {
11653 STATS_DECLTRACK_ARG_ATTR(potential_values)
11654 }
11655};
11656
11657struct AAPotentialValuesReturned : public AAPotentialValuesFloating {
11658 using Base = AAPotentialValuesFloating;
11659 AAPotentialValuesReturned(const IRPosition &IRP, Attributor &A)
11660 : Base(IRP, A) {}
11661
11662 /// See AbstractAttribute::initialize(..).
11663 void initialize(Attributor &A) override {
11664 Function *F = getAssociatedFunction();
11665 if (!F || F->isDeclaration() || F->getReturnType()->isVoidTy()) {
11666 indicatePessimisticFixpoint();
11667 return;
11668 }
11669
11670 for (Argument &Arg : F->args())
11671 if (Arg.hasReturnedAttr()) {
11672 addValue(A, getState(), Arg, nullptr, AA::AnyScope, F);
11673 ReturnedArg = &Arg;
11674 break;
11675 }
11676 if (!A.isFunctionIPOAmendable(*F) ||
11677 A.hasSimplificationCallback(getIRPosition())) {
11678 if (!ReturnedArg)
11679 indicatePessimisticFixpoint();
11680 else
11681 indicateOptimisticFixpoint();
11682 }
11683 }
11684
11685 /// See AbstractAttribute::updateImpl(...).
11686 ChangeStatus updateImpl(Attributor &A) override {
11687 auto AssumedBefore = getAssumed();
11688 bool UsedAssumedInformation = false;
11689
11691 Function *AnchorScope = getAnchorScope();
11692 auto HandleReturnedValue = [&](Value &V, Instruction *CtxI,
11693 bool AddValues) {
11695 Values.clear();
11696 if (!A.getAssumedSimplifiedValues(IRPosition::value(V), this, Values, S,
11697 UsedAssumedInformation,
11698 /* RecurseForSelectAndPHI */ true))
11699 return false;
11700 if (!AddValues)
11701 continue;
11702
11703 bool AllInterAreIntra = false;
11704 if (S == AA::Interprocedural)
11705 AllInterAreIntra =
11706 llvm::all_of(Values, [&](const AA::ValueAndContext &VAC) {
11707 return AA::isValidInScope(*VAC.getValue(), AnchorScope);
11708 });
11709
11710 for (const AA::ValueAndContext &VAC : Values) {
11711 addValue(A, getState(), *VAC.getValue(),
11712 VAC.getCtxI() ? VAC.getCtxI() : CtxI,
11713 AllInterAreIntra ? AA::AnyScope : S, AnchorScope);
11714 }
11715 if (AllInterAreIntra)
11716 break;
11717 }
11718 return true;
11719 };
11720
11721 if (ReturnedArg) {
11722 HandleReturnedValue(*ReturnedArg, nullptr, true);
11723 } else {
11724 auto RetInstPred = [&](Instruction &RetI) {
11725 bool AddValues = true;
11726 if (isa<PHINode>(RetI.getOperand(0)) ||
11727 isa<SelectInst>(RetI.getOperand(0))) {
11728 addValue(A, getState(), *RetI.getOperand(0), &RetI, AA::AnyScope,
11729 AnchorScope);
11730 AddValues = false;
11731 }
11732 return HandleReturnedValue(*RetI.getOperand(0), &RetI, AddValues);
11733 };
11734
11735 if (!A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret},
11736 UsedAssumedInformation,
11737 /* CheckBBLivenessOnly */ true))
11738 return indicatePessimisticFixpoint();
11739 }
11740
11741 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
11742 : ChangeStatus::CHANGED;
11743 }
11744
11745 ChangeStatus manifest(Attributor &A) override {
11746 if (ReturnedArg)
11747 return ChangeStatus::UNCHANGED;
11749 if (!getAssumedSimplifiedValues(A, Values, AA::ValueScope::Intraprocedural,
11750 /* RecurseForSelectAndPHI */ true))
11751 return ChangeStatus::UNCHANGED;
11752 Value *NewVal = getSingleValue(A, *this, getIRPosition(), Values);
11753 if (!NewVal)
11754 return ChangeStatus::UNCHANGED;
11755
11756 ChangeStatus Changed = ChangeStatus::UNCHANGED;
11757 if (auto *Arg = dyn_cast<Argument>(NewVal)) {
11758 STATS_DECLTRACK(UniqueReturnValue, FunctionReturn,
11759 "Number of function with unique return");
11760 Changed |= A.manifestAttrs(
11762 {Attribute::get(Arg->getContext(), Attribute::Returned)});
11763 STATS_DECLTRACK_ARG_ATTR(returned);
11764 }
11765
11766 auto RetInstPred = [&](Instruction &RetI) {
11767 Value *RetOp = RetI.getOperand(0);
11768 if (isa<UndefValue>(RetOp) || RetOp == NewVal)
11769 return true;
11770 if (AA::isValidAtPosition({*NewVal, RetI}, A.getInfoCache()))
11771 if (A.changeUseAfterManifest(RetI.getOperandUse(0), *NewVal))
11772 Changed = ChangeStatus::CHANGED;
11773 return true;
11774 };
11775 bool UsedAssumedInformation = false;
11776 (void)A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret},
11777 UsedAssumedInformation,
11778 /* CheckBBLivenessOnly */ true);
11779 return Changed;
11780 }
11781
11782 ChangeStatus indicatePessimisticFixpoint() override {
11783 return AAPotentialValues::indicatePessimisticFixpoint();
11784 }
11785
11786 /// See AbstractAttribute::trackStatistics()
11787 void trackStatistics() const override{
11788 STATS_DECLTRACK_FNRET_ATTR(potential_values)}
11789
11790 /// The argumented with an existing `returned` attribute.
11791 Argument *ReturnedArg = nullptr;
11792};
11793
11794struct AAPotentialValuesFunction : AAPotentialValuesImpl {
11795 AAPotentialValuesFunction(const IRPosition &IRP, Attributor &A)
11796 : AAPotentialValuesImpl(IRP, A) {}
11797
11798 /// See AbstractAttribute::updateImpl(...).
11799 ChangeStatus updateImpl(Attributor &A) override {
11800 llvm_unreachable("AAPotentialValues(Function|CallSite)::updateImpl will "
11801 "not be called");
11802 }
11803
11804 /// See AbstractAttribute::trackStatistics()
11805 void trackStatistics() const override {
11806 STATS_DECLTRACK_FN_ATTR(potential_values)
11807 }
11808};
11809
11810struct AAPotentialValuesCallSite : AAPotentialValuesFunction {
11811 AAPotentialValuesCallSite(const IRPosition &IRP, Attributor &A)
11812 : AAPotentialValuesFunction(IRP, A) {}
11813
11814 /// See AbstractAttribute::trackStatistics()
11815 void trackStatistics() const override {
11816 STATS_DECLTRACK_CS_ATTR(potential_values)
11817 }
11818};
11819
11820struct AAPotentialValuesCallSiteReturned : AAPotentialValuesImpl {
11821 AAPotentialValuesCallSiteReturned(const IRPosition &IRP, Attributor &A)
11822 : AAPotentialValuesImpl(IRP, A) {}
11823
11824 /// See AbstractAttribute::updateImpl(...).
11825 ChangeStatus updateImpl(Attributor &A) override {
11826 auto AssumedBefore = getAssumed();
11827
11828 Function *Callee = getAssociatedFunction();
11829 if (!Callee)
11830 return indicatePessimisticFixpoint();
11831
11832 bool UsedAssumedInformation = false;
11833 auto *CB = cast<CallBase>(getCtxI());
11834 if (CB->isMustTailCall() &&
11835 !A.isAssumedDead(IRPosition::inst(*CB), this, nullptr,
11836 UsedAssumedInformation))
11837 return indicatePessimisticFixpoint();
11838
11839 Function *Caller = CB->getCaller();
11840
11841 auto AddScope = [&](AA::ValueScope S) {
11843 if (!A.getAssumedSimplifiedValues(IRPosition::returned(*Callee), this,
11844 Values, S, UsedAssumedInformation))
11845 return false;
11846
11847 for (auto &It : Values) {
11848 Value *V = It.getValue();
11849 std::optional<Value *> CallerV = A.translateArgumentToCallSiteContent(
11850 V, *CB, *this, UsedAssumedInformation);
11851 if (!CallerV.has_value()) {
11852 // Nothing to do as long as no value was determined.
11853 continue;
11854 }
11855 V = *CallerV ? *CallerV : V;
11856 if (*CallerV && AA::isDynamicallyUnique(A, *this, *V)) {
11857 if (recurseForValue(A, IRPosition::value(*V), S))
11858 continue;
11859 }
11860 if (S == AA::Intraprocedural && !AA::isValidInScope(*V, Caller)) {
11861 giveUpOnIntraprocedural(A);
11862 return true;
11863 }
11864 addValue(A, getState(), *V, CB, S, getAnchorScope());
11865 }
11866 return true;
11867 };
11868 if (!AddScope(AA::Intraprocedural))
11869 return indicatePessimisticFixpoint();
11870 if (!AddScope(AA::Interprocedural))
11871 return indicatePessimisticFixpoint();
11872 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
11873 : ChangeStatus::CHANGED;
11874 }
11875
11876 ChangeStatus indicatePessimisticFixpoint() override {
11877 return AAPotentialValues::indicatePessimisticFixpoint();
11878 }
11879
11880 /// See AbstractAttribute::trackStatistics()
11881 void trackStatistics() const override {
11882 STATS_DECLTRACK_CSRET_ATTR(potential_values)
11883 }
11884};
11885
11886struct AAPotentialValuesCallSiteArgument : AAPotentialValuesFloating {
11887 AAPotentialValuesCallSiteArgument(const IRPosition &IRP, Attributor &A)
11888 : AAPotentialValuesFloating(IRP, A) {}
11889
11890 /// See AbstractAttribute::trackStatistics()
11891 void trackStatistics() const override {
11892 STATS_DECLTRACK_CSARG_ATTR(potential_values)
11893 }
11894};
11895} // namespace
11896
11897/// ---------------------- Assumption Propagation ------------------------------
11898namespace {
11899struct AAAssumptionInfoImpl : public AAAssumptionInfo {
11900 AAAssumptionInfoImpl(const IRPosition &IRP, Attributor &A,
11901 const DenseSet<StringRef> &Known)
11902 : AAAssumptionInfo(IRP, A, Known) {}
11903
11904 /// See AbstractAttribute::manifest(...).
11905 ChangeStatus manifest(Attributor &A) override {
11906 // Don't manifest a universal set if it somehow made it here.
11907 if (getKnown().isUniversal())
11908 return ChangeStatus::UNCHANGED;
11909
11910 const IRPosition &IRP = getIRPosition();
11911 SmallVector<StringRef, 0> Set(getAssumed().getSet().begin(),
11912 getAssumed().getSet().end());
11913 llvm::sort(Set);
11914 return A.manifestAttrs(IRP,
11915 Attribute::get(IRP.getAnchorValue().getContext(),
11917 llvm::join(Set, ",")),
11918 /*ForceReplace=*/true);
11919 }
11920
11921 bool hasAssumption(const StringRef Assumption) const override {
11922 return isValidState() && setContains(Assumption);
11923 }
11924
11925 /// See AbstractAttribute::getAsStr()
11926 const std::string getAsStr(Attributor *A) const override {
11927 const SetContents &Known = getKnown();
11928 const SetContents &Assumed = getAssumed();
11929
11930 SmallVector<StringRef, 0> Set(Known.getSet().begin(), Known.getSet().end());
11931 llvm::sort(Set);
11932 const std::string KnownStr = llvm::join(Set, ",");
11933
11934 std::string AssumedStr = "Universal";
11935 if (!Assumed.isUniversal()) {
11936 Set.assign(Assumed.getSet().begin(), Assumed.getSet().end());
11937 AssumedStr = llvm::join(Set, ",");
11938 }
11939 return "Known [" + KnownStr + "]," + " Assumed [" + AssumedStr + "]";
11940 }
11941};
11942
11943/// Propagates assumption information from parent functions to all of their
11944/// successors. An assumption can be propagated if the containing function
11945/// dominates the called function.
11946///
11947/// We start with a "known" set of assumptions already valid for the associated
11948/// function and an "assumed" set that initially contains all possible
11949/// assumptions. The assumed set is inter-procedurally updated by narrowing its
11950/// contents as concrete values are known. The concrete values are seeded by the
11951/// first nodes that are either entries into the call graph, or contains no
11952/// assumptions. Each node is updated as the intersection of the assumed state
11953/// with all of its predecessors.
11954struct AAAssumptionInfoFunction final : AAAssumptionInfoImpl {
11955 AAAssumptionInfoFunction(const IRPosition &IRP, Attributor &A)
11956 : AAAssumptionInfoImpl(IRP, A,
11957 getAssumptions(*IRP.getAssociatedFunction())) {}
11958
11959 /// See AbstractAttribute::updateImpl(...).
11960 ChangeStatus updateImpl(Attributor &A) override {
11961 bool Changed = false;
11962
11963 auto CallSitePred = [&](AbstractCallSite ACS) {
11964 const auto *AssumptionAA = A.getAAFor<AAAssumptionInfo>(
11965 *this, IRPosition::callsite_function(*ACS.getInstruction()),
11966 DepClassTy::REQUIRED);
11967 if (!AssumptionAA)
11968 return false;
11969 // Get the set of assumptions shared by all of this function's callers.
11970 Changed |= getIntersection(AssumptionAA->getAssumed());
11971 return !getAssumed().empty() || !getKnown().empty();
11972 };
11973
11974 bool UsedAssumedInformation = false;
11975 // Get the intersection of all assumptions held by this node's predecessors.
11976 // If we don't know all the call sites then this is either an entry into the
11977 // call graph or an empty node. This node is known to only contain its own
11978 // assumptions and can be propagated to its successors.
11979 if (!A.checkForAllCallSites(CallSitePred, *this, true,
11980 UsedAssumedInformation))
11981 return indicatePessimisticFixpoint();
11982
11983 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
11984 }
11985
11986 void trackStatistics() const override {}
11987};
11988
11989/// Assumption Info defined for call sites.
11990struct AAAssumptionInfoCallSite final : AAAssumptionInfoImpl {
11991
11992 AAAssumptionInfoCallSite(const IRPosition &IRP, Attributor &A)
11993 : AAAssumptionInfoImpl(IRP, A, getInitialAssumptions(IRP)) {}
11994
11995 /// See AbstractAttribute::initialize(...).
11996 void initialize(Attributor &A) override {
11997 const IRPosition &FnPos = IRPosition::function(*getAnchorScope());
11998 A.getAAFor<AAAssumptionInfo>(*this, FnPos, DepClassTy::REQUIRED);
11999 }
12000
12001 /// See AbstractAttribute::updateImpl(...).
12002 ChangeStatus updateImpl(Attributor &A) override {
12003 const IRPosition &FnPos = IRPosition::function(*getAnchorScope());
12004 auto *AssumptionAA =
12005 A.getAAFor<AAAssumptionInfo>(*this, FnPos, DepClassTy::REQUIRED);
12006 if (!AssumptionAA)
12007 return indicatePessimisticFixpoint();
12008 bool Changed = getIntersection(AssumptionAA->getAssumed());
12009 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
12010 }
12011
12012 /// See AbstractAttribute::trackStatistics()
12013 void trackStatistics() const override {}
12014
12015private:
12016 /// Helper to initialized the known set as all the assumptions this call and
12017 /// the callee contain.
12018 DenseSet<StringRef> getInitialAssumptions(const IRPosition &IRP) {
12019 const CallBase &CB = cast<CallBase>(IRP.getAssociatedValue());
12020 auto Assumptions = getAssumptions(CB);
12021 if (const Function *F = CB.getCaller())
12022 set_union(Assumptions, getAssumptions(*F));
12023 if (Function *F = IRP.getAssociatedFunction())
12024 set_union(Assumptions, getAssumptions(*F));
12025 return Assumptions;
12026 }
12027};
12028} // namespace
12029
12031 return static_cast<AACallGraphNode *>(const_cast<AACallEdges *>(
12032 A.getOrCreateAAFor<AACallEdges>(IRPosition::function(**I))));
12033}
12034
12036
12037/// ------------------------ UnderlyingObjects ---------------------------------
12038
12039namespace {
12040struct AAUnderlyingObjectsImpl
12041 : StateWrapper<BooleanState, AAUnderlyingObjects> {
12043 AAUnderlyingObjectsImpl(const IRPosition &IRP, Attributor &A) : BaseTy(IRP) {}
12044
12045 /// See AbstractAttribute::getAsStr().
12046 const std::string getAsStr(Attributor *A) const override {
12047 if (!isValidState())
12048 return "<invalid>";
12049 std::string Str;
12051 OS << "underlying objects: inter " << InterAssumedUnderlyingObjects.size()
12052 << " objects, intra " << IntraAssumedUnderlyingObjects.size()
12053 << " objects.\n";
12054 if (!InterAssumedUnderlyingObjects.empty()) {
12055 OS << "inter objects:\n";
12056 for (auto *Obj : InterAssumedUnderlyingObjects)
12057 OS << *Obj << '\n';
12058 }
12059 if (!IntraAssumedUnderlyingObjects.empty()) {
12060 OS << "intra objects:\n";
12061 for (auto *Obj : IntraAssumedUnderlyingObjects)
12062 OS << *Obj << '\n';
12063 }
12064 return Str;
12065 }
12066
12067 /// See AbstractAttribute::trackStatistics()
12068 void trackStatistics() const override {}
12069
12070 /// See AbstractAttribute::updateImpl(...).
12071 ChangeStatus updateImpl(Attributor &A) override {
12072 auto &Ptr = getAssociatedValue();
12073
12074 bool UsedAssumedInformation = false;
12075 auto DoUpdate = [&](SmallSetVector<Value *, 8> &UnderlyingObjects,
12077 SmallPtrSet<Value *, 8> SeenObjects;
12079
12080 if (!A.getAssumedSimplifiedValues(IRPosition::value(Ptr), *this, Values,
12081 Scope, UsedAssumedInformation))
12082 return UnderlyingObjects.insert(&Ptr);
12083
12084 bool Changed = false;
12085
12086 for (unsigned I = 0; I < Values.size(); ++I) {
12087 auto &VAC = Values[I];
12088 auto *Obj = VAC.getValue();
12089 Value *UO = getUnderlyingObject(Obj);
12090 if (!SeenObjects.insert(UO ? UO : Obj).second)
12091 continue;
12092 if (UO && UO != Obj) {
12093 if (isa<AllocaInst>(UO) || isa<GlobalValue>(UO)) {
12094 Changed |= UnderlyingObjects.insert(UO);
12095 continue;
12096 }
12097
12098 const auto *OtherAA = A.getAAFor<AAUnderlyingObjects>(
12099 *this, IRPosition::value(*UO), DepClassTy::OPTIONAL);
12100 auto Pred = [&](Value &V) {
12101 if (&V == UO)
12102 Changed |= UnderlyingObjects.insert(UO);
12103 else
12104 Values.emplace_back(V, nullptr);
12105 return true;
12106 };
12107
12108 if (!OtherAA || !OtherAA->forallUnderlyingObjects(Pred, Scope))
12110 "The forall call should not return false at this position");
12111 UsedAssumedInformation |= !OtherAA->getState().isAtFixpoint();
12112 continue;
12113 }
12114
12115 if (isa<SelectInst>(Obj)) {
12116 Changed |= handleIndirect(A, *Obj, UnderlyingObjects, Scope,
12117 UsedAssumedInformation);
12118 continue;
12119 }
12120 if (auto *PHI = dyn_cast<PHINode>(Obj)) {
12121 // Explicitly look through PHIs as we do not care about dynamically
12122 // uniqueness.
12123 for (unsigned u = 0, e = PHI->getNumIncomingValues(); u < e; u++) {
12124 Changed |=
12125 handleIndirect(A, *PHI->getIncomingValue(u), UnderlyingObjects,
12126 Scope, UsedAssumedInformation);
12127 }
12128 continue;
12129 }
12130
12131 Changed |= UnderlyingObjects.insert(Obj);
12132 }
12133
12134 return Changed;
12135 };
12136
12137 bool Changed = false;
12138 Changed |= DoUpdate(IntraAssumedUnderlyingObjects, AA::Intraprocedural);
12139 Changed |= DoUpdate(InterAssumedUnderlyingObjects, AA::Interprocedural);
12140 if (!UsedAssumedInformation)
12141 indicateOptimisticFixpoint();
12142 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
12143 }
12144
12145 bool forallUnderlyingObjects(
12146 function_ref<bool(Value &)> Pred,
12147 AA::ValueScope Scope = AA::Interprocedural) const override {
12148 if (!isValidState())
12149 return Pred(getAssociatedValue());
12150
12151 auto &AssumedUnderlyingObjects = Scope == AA::Intraprocedural
12152 ? IntraAssumedUnderlyingObjects
12153 : InterAssumedUnderlyingObjects;
12154 for (Value *Obj : AssumedUnderlyingObjects)
12155 if (!Pred(*Obj))
12156 return false;
12157
12158 return true;
12159 }
12160
12161private:
12162 /// Handle the case where the value is not the actual underlying value, such
12163 /// as a phi node or a select instruction.
12164 bool handleIndirect(Attributor &A, Value &V,
12165 SmallSetVector<Value *, 8> &UnderlyingObjects,
12166 AA::ValueScope Scope, bool &UsedAssumedInformation) {
12167 bool Changed = false;
12168 const auto *AA = A.getAAFor<AAUnderlyingObjects>(
12169 *this, IRPosition::value(V), DepClassTy::OPTIONAL);
12170 auto Pred = [&](Value &V) {
12171 Changed |= UnderlyingObjects.insert(&V);
12172 return true;
12173 };
12174 if (!AA || !AA->forallUnderlyingObjects(Pred, Scope))
12176 "The forall call should not return false at this position");
12177 UsedAssumedInformation |= !AA->getState().isAtFixpoint();
12178 return Changed;
12179 }
12180
12181 /// All the underlying objects collected so far via intra procedural scope.
12182 SmallSetVector<Value *, 8> IntraAssumedUnderlyingObjects;
12183 /// All the underlying objects collected so far via inter procedural scope.
12184 SmallSetVector<Value *, 8> InterAssumedUnderlyingObjects;
12185};
12186
12187struct AAUnderlyingObjectsFloating final : AAUnderlyingObjectsImpl {
12188 AAUnderlyingObjectsFloating(const IRPosition &IRP, Attributor &A)
12189 : AAUnderlyingObjectsImpl(IRP, A) {}
12190};
12191
12192struct AAUnderlyingObjectsArgument final : AAUnderlyingObjectsImpl {
12193 AAUnderlyingObjectsArgument(const IRPosition &IRP, Attributor &A)
12194 : AAUnderlyingObjectsImpl(IRP, A) {}
12195};
12196
12197struct AAUnderlyingObjectsCallSite final : AAUnderlyingObjectsImpl {
12198 AAUnderlyingObjectsCallSite(const IRPosition &IRP, Attributor &A)
12199 : AAUnderlyingObjectsImpl(IRP, A) {}
12200};
12201
12202struct AAUnderlyingObjectsCallSiteArgument final : AAUnderlyingObjectsImpl {
12203 AAUnderlyingObjectsCallSiteArgument(const IRPosition &IRP, Attributor &A)
12204 : AAUnderlyingObjectsImpl(IRP, A) {}
12205};
12206
12207struct AAUnderlyingObjectsReturned final : AAUnderlyingObjectsImpl {
12208 AAUnderlyingObjectsReturned(const IRPosition &IRP, Attributor &A)
12209 : AAUnderlyingObjectsImpl(IRP, A) {}
12210};
12211
12212struct AAUnderlyingObjectsCallSiteReturned final : AAUnderlyingObjectsImpl {
12213 AAUnderlyingObjectsCallSiteReturned(const IRPosition &IRP, Attributor &A)
12214 : AAUnderlyingObjectsImpl(IRP, A) {}
12215};
12216
12217struct AAUnderlyingObjectsFunction final : AAUnderlyingObjectsImpl {
12218 AAUnderlyingObjectsFunction(const IRPosition &IRP, Attributor &A)
12219 : AAUnderlyingObjectsImpl(IRP, A) {}
12220};
12221} // namespace
12222
12223/// ------------------------ Global Value Info -------------------------------
12224namespace {
12225struct AAGlobalValueInfoFloating : public AAGlobalValueInfo {
12226 AAGlobalValueInfoFloating(const IRPosition &IRP, Attributor &A)
12227 : AAGlobalValueInfo(IRP, A) {}
12228
12229 /// See AbstractAttribute::initialize(...).
12230 void initialize(Attributor &A) override {}
12231
12232 bool checkUse(Attributor &A, const Use &U, bool &Follow,
12233 SmallVectorImpl<const Value *> &Worklist) {
12234 Instruction *UInst = dyn_cast<Instruction>(U.getUser());
12235 if (!UInst) {
12236 Follow = true;
12237 return true;
12238 }
12239
12240 LLVM_DEBUG(dbgs() << "[AAGlobalValueInfo] Check use: " << *U.get() << " in "
12241 << *UInst << "\n");
12242
12243 if (auto *Cmp = dyn_cast<ICmpInst>(U.getUser())) {
12244 int Idx = &Cmp->getOperandUse(0) == &U;
12245 if (isa<Constant>(Cmp->getOperand(Idx)))
12246 return true;
12247 return U == &getAnchorValue();
12248 }
12249
12250 // Explicitly catch return instructions.
12251 if (isa<ReturnInst>(UInst)) {
12252 auto CallSitePred = [&](AbstractCallSite ACS) {
12253 Worklist.push_back(ACS.getInstruction());
12254 return true;
12255 };
12256 bool UsedAssumedInformation = false;
12257 // TODO: We should traverse the uses or add a "non-call-site" CB.
12258 if (!A.checkForAllCallSites(CallSitePred, *UInst->getFunction(),
12259 /*RequireAllCallSites=*/true, this,
12260 UsedAssumedInformation))
12261 return false;
12262 return true;
12263 }
12264
12265 // For now we only use special logic for call sites. However, the tracker
12266 // itself knows about a lot of other non-capturing cases already.
12267 auto *CB = dyn_cast<CallBase>(UInst);
12268 if (!CB)
12269 return false;
12270 // Direct calls are OK uses.
12271 if (CB->isCallee(&U))
12272 return true;
12273 // Non-argument uses are scary.
12274 if (!CB->isArgOperand(&U))
12275 return false;
12276 // TODO: Iterate callees.
12277 auto *Fn = dyn_cast<Function>(CB->getCalledOperand());
12278 if (!Fn || !A.isFunctionIPOAmendable(*Fn))
12279 return false;
12280
12281 unsigned ArgNo = CB->getArgOperandNo(&U);
12282 Worklist.push_back(Fn->getArg(ArgNo));
12283 return true;
12284 }
12285
12286 ChangeStatus updateImpl(Attributor &A) override {
12287 unsigned NumUsesBefore = Uses.size();
12288
12289 SmallPtrSet<const Value *, 8> Visited;
12291 Worklist.push_back(&getAnchorValue());
12292
12293 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
12294 Uses.insert(&U);
12295 // TODO(captures): Make this more precise.
12296 UseCaptureInfo CI = DetermineUseCaptureKind(U, /*Base=*/nullptr);
12297 if (CI.isPassthrough()) {
12298 Follow = true;
12299 return true;
12300 }
12301 return checkUse(A, U, Follow, Worklist);
12302 };
12303 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) {
12304 Uses.insert(&OldU);
12305 return true;
12306 };
12307
12308 while (!Worklist.empty()) {
12309 const Value *V = Worklist.pop_back_val();
12310 if (!Visited.insert(V).second)
12311 continue;
12312 if (!A.checkForAllUses(UsePred, *this, *V,
12313 /* CheckBBLivenessOnly */ true,
12314 DepClassTy::OPTIONAL,
12315 /* IgnoreDroppableUses */ true, EquivalentUseCB)) {
12316 return indicatePessimisticFixpoint();
12317 }
12318 }
12319
12320 return Uses.size() == NumUsesBefore ? ChangeStatus::UNCHANGED
12321 : ChangeStatus::CHANGED;
12322 }
12323
12324 bool isPotentialUse(const Use &U) const override {
12325 return !isValidState() || Uses.contains(&U);
12326 }
12327
12328 /// See AbstractAttribute::manifest(...).
12329 ChangeStatus manifest(Attributor &A) override {
12330 return ChangeStatus::UNCHANGED;
12331 }
12332
12333 /// See AbstractAttribute::getAsStr().
12334 const std::string getAsStr(Attributor *A) const override {
12335 return "[" + std::to_string(Uses.size()) + " uses]";
12336 }
12337
12338 void trackStatistics() const override {
12339 STATS_DECLTRACK_FLOATING_ATTR(GlobalValuesTracked);
12340 }
12341
12342private:
12343 /// Set of (transitive) uses of this GlobalValue.
12344 SmallPtrSet<const Use *, 8> Uses;
12345};
12346} // namespace
12347
12348/// ------------------------ Indirect Call Info -------------------------------
12349namespace {
12350struct AAIndirectCallInfoCallSite : public AAIndirectCallInfo {
12351 AAIndirectCallInfoCallSite(const IRPosition &IRP, Attributor &A)
12352 : AAIndirectCallInfo(IRP, A) {}
12353
12354 /// See AbstractAttribute::initialize(...).
12355 void initialize(Attributor &A) override {
12356 auto *MD = getCtxI()->getMetadata(LLVMContext::MD_callees);
12357 if (!MD && !A.isClosedWorldModule())
12358 return;
12359
12360 if (MD) {
12361 for (const auto &Op : MD->operands())
12362 if (Function *Callee = mdconst::dyn_extract_or_null<Function>(Op))
12363 PotentialCallees.insert(Callee);
12364 } else if (A.isClosedWorldModule()) {
12365 ArrayRef<Function *> IndirectlyCallableFunctions =
12366 A.getInfoCache().getIndirectlyCallableFunctions(A);
12367 PotentialCallees.insert_range(IndirectlyCallableFunctions);
12368 }
12369
12370 if (PotentialCallees.empty())
12371 indicateOptimisticFixpoint();
12372 }
12373
12374 ChangeStatus updateImpl(Attributor &A) override {
12375 CallBase *CB = cast<CallBase>(getCtxI());
12376 const Use &CalleeUse = CB->getCalledOperandUse();
12377 Value *FP = CB->getCalledOperand();
12378
12379 SmallSetVector<Function *, 4> AssumedCalleesNow;
12380 bool AllCalleesKnownNow = AllCalleesKnown;
12381
12382 auto CheckPotentialCalleeUse = [&](Function &PotentialCallee,
12383 bool &UsedAssumedInformation) {
12384 const auto *GIAA = A.getAAFor<AAGlobalValueInfo>(
12385 *this, IRPosition::value(PotentialCallee), DepClassTy::OPTIONAL);
12386 if (!GIAA || GIAA->isPotentialUse(CalleeUse))
12387 return true;
12388 UsedAssumedInformation = !GIAA->isAtFixpoint();
12389 return false;
12390 };
12391
12392 auto AddPotentialCallees = [&]() {
12393 for (auto *PotentialCallee : PotentialCallees) {
12394 bool UsedAssumedInformation = false;
12395 if (CheckPotentialCalleeUse(*PotentialCallee, UsedAssumedInformation))
12396 AssumedCalleesNow.insert(PotentialCallee);
12397 }
12398 };
12399
12400 // Use simplification to find potential callees, if !callees was present,
12401 // fallback to that set if necessary.
12402 bool UsedAssumedInformation = false;
12404 if (!A.getAssumedSimplifiedValues(IRPosition::value(*FP), this, Values,
12405 AA::ValueScope::AnyScope,
12406 UsedAssumedInformation)) {
12407 if (PotentialCallees.empty())
12408 return indicatePessimisticFixpoint();
12409 AddPotentialCallees();
12410 }
12411
12412 // Try to find a reason for \p Fn not to be a potential callee. If none was
12413 // found, add it to the assumed callees set.
12414 auto CheckPotentialCallee = [&](Function &Fn) {
12415 if (!PotentialCallees.empty() && !PotentialCallees.count(&Fn))
12416 return false;
12417
12418 auto &CachedResult = FilterResults[&Fn];
12419 if (CachedResult.has_value())
12420 return CachedResult.value();
12421
12422 bool UsedAssumedInformation = false;
12423 if (!CheckPotentialCalleeUse(Fn, UsedAssumedInformation)) {
12424 if (!UsedAssumedInformation)
12425 CachedResult = false;
12426 return false;
12427 }
12428
12429 int NumFnArgs = Fn.arg_size();
12430 int NumCBArgs = CB->arg_size();
12431
12432 // Check if any excess argument (which we fill up with poison) is known to
12433 // be UB on undef.
12434 for (int I = NumCBArgs; I < NumFnArgs; ++I) {
12435 bool IsKnown = false;
12437 A, this, IRPosition::argument(*Fn.getArg(I)),
12438 DepClassTy::OPTIONAL, IsKnown)) {
12439 if (IsKnown)
12440 CachedResult = false;
12441 return false;
12442 }
12443 }
12444
12445 CachedResult = true;
12446 return true;
12447 };
12448
12449 // Check simplification result, prune known UB callees, also restrict it to
12450 // the !callees set, if present.
12451 for (auto &VAC : Values) {
12452 if (isa<UndefValue>(VAC.getValue()))
12453 continue;
12455 VAC.getValue()->getType()->getPointerAddressSpace() == 0)
12456 continue;
12457 // TODO: Check for known UB, e.g., poison + noundef.
12458 if (auto *VACFn = dyn_cast<Function>(VAC.getValue())) {
12459 if (CheckPotentialCallee(*VACFn))
12460 AssumedCalleesNow.insert(VACFn);
12461 continue;
12462 }
12463 if (!PotentialCallees.empty()) {
12464 AddPotentialCallees();
12465 break;
12466 }
12467 AllCalleesKnownNow = false;
12468 }
12469
12470 if (AssumedCalleesNow == AssumedCallees &&
12471 AllCalleesKnown == AllCalleesKnownNow)
12472 return ChangeStatus::UNCHANGED;
12473
12474 std::swap(AssumedCallees, AssumedCalleesNow);
12475 AllCalleesKnown = AllCalleesKnownNow;
12476 return ChangeStatus::CHANGED;
12477 }
12478
12479 /// See AbstractAttribute::manifest(...).
12480 ChangeStatus manifest(Attributor &A) override {
12481 // If we can't specialize at all, give up now.
12482 if (!AllCalleesKnown && AssumedCallees.empty())
12483 return ChangeStatus::UNCHANGED;
12484
12485 CallBase *CB = cast<CallBase>(getCtxI());
12486 bool UsedAssumedInformation = false;
12487 if (A.isAssumedDead(*CB, this, /*LivenessAA=*/nullptr,
12488 UsedAssumedInformation))
12489 return ChangeStatus::UNCHANGED;
12490
12491 ChangeStatus Changed = ChangeStatus::UNCHANGED;
12492 Value *FP = CB->getCalledOperand();
12493 if (FP->getType()->getPointerAddressSpace())
12494 FP = new AddrSpaceCastInst(FP, PointerType::get(FP->getContext(), 0),
12495 FP->getName() + ".as0", CB->getIterator());
12496
12497 bool CBIsVoid = CB->getType()->isVoidTy();
12499 FunctionType *CSFT = CB->getFunctionType();
12500 SmallVector<Value *> CSArgs(CB->args());
12501
12502 // If we know all callees and there are none, the call site is (effectively)
12503 // dead (or UB).
12504 if (AssumedCallees.empty()) {
12505 assert(AllCalleesKnown &&
12506 "Expected all callees to be known if there are none.");
12507 A.changeToUnreachableAfterManifest(CB);
12508 return ChangeStatus::CHANGED;
12509 }
12510
12511 // Special handling for the single callee case.
12512 if (AllCalleesKnown && AssumedCallees.size() == 1) {
12513 auto *NewCallee = AssumedCallees.front();
12514 if (isLegalToPromote(*CB, NewCallee)) {
12515 promoteCall(*CB, NewCallee, nullptr);
12516 NumIndirectCallsPromoted++;
12517 return ChangeStatus::CHANGED;
12518 }
12519 Instruction *NewCall =
12520 CallInst::Create(FunctionCallee(CSFT, NewCallee), CSArgs,
12521 CB->getName(), CB->getIterator());
12522 if (!CBIsVoid)
12523 A.changeAfterManifest(IRPosition::callsite_returned(*CB), *NewCall);
12524 A.deleteAfterManifest(*CB);
12525 return ChangeStatus::CHANGED;
12526 }
12527
12528 // For each potential value we create a conditional
12529 //
12530 // ```
12531 // if (ptr == value) value(args);
12532 // else ...
12533 // ```
12534 //
12535 bool SpecializedForAnyCallees = false;
12536 bool SpecializedForAllCallees = AllCalleesKnown;
12537 ICmpInst *LastCmp = nullptr;
12538 SmallVector<Function *, 8> SkippedAssumedCallees;
12540 for (Function *NewCallee : AssumedCallees) {
12541 if (!A.shouldSpecializeCallSiteForCallee(*this, *CB, *NewCallee,
12542 AssumedCallees.size())) {
12543 SkippedAssumedCallees.push_back(NewCallee);
12544 SpecializedForAllCallees = false;
12545 continue;
12546 }
12547 SpecializedForAnyCallees = true;
12548
12549 LastCmp = new ICmpInst(IP, llvm::CmpInst::ICMP_EQ, FP, NewCallee);
12550 Instruction *ThenTI =
12551 SplitBlockAndInsertIfThen(LastCmp, IP, /* Unreachable */ false);
12552 BasicBlock *CBBB = CB->getParent();
12553 A.registerManifestAddedBasicBlock(*ThenTI->getParent());
12554 A.registerManifestAddedBasicBlock(*IP->getParent());
12555 auto *SplitTI = cast<CondBrInst>(LastCmp->getNextNode());
12556 BasicBlock *ElseBB;
12557 if (&*IP == CB) {
12558 ElseBB = BasicBlock::Create(ThenTI->getContext(), "",
12559 ThenTI->getFunction(), CBBB);
12560 A.registerManifestAddedBasicBlock(*ElseBB);
12561 IP = UncondBrInst::Create(CBBB, ElseBB)->getIterator();
12562 SplitTI->replaceUsesOfWith(CBBB, ElseBB);
12563 } else {
12564 ElseBB = IP->getParent();
12565 ThenTI->replaceUsesOfWith(ElseBB, CBBB);
12566 }
12567 CastInst *RetBC = nullptr;
12568 CallInst *NewCall = nullptr;
12569 if (isLegalToPromote(*CB, NewCallee)) {
12570 auto *CBClone = cast<CallBase>(CB->clone());
12571 CBClone->insertBefore(ThenTI->getIterator());
12572 NewCall = &cast<CallInst>(promoteCall(*CBClone, NewCallee, &RetBC));
12573 NumIndirectCallsPromoted++;
12574 } else {
12575 NewCall = CallInst::Create(FunctionCallee(CSFT, NewCallee), CSArgs,
12576 CB->getName(), ThenTI->getIterator());
12577 }
12578 NewCalls.push_back({NewCall, RetBC});
12579 }
12580
12581 auto AttachCalleeMetadata = [&](CallBase &IndirectCB) {
12582 if (!AllCalleesKnown)
12583 return ChangeStatus::UNCHANGED;
12584 MDBuilder MDB(IndirectCB.getContext());
12585 MDNode *Callees = MDB.createCallees(SkippedAssumedCallees);
12586 IndirectCB.setMetadata(LLVMContext::MD_callees, Callees);
12587 return ChangeStatus::CHANGED;
12588 };
12589
12590 if (!SpecializedForAnyCallees)
12591 return AttachCalleeMetadata(*CB);
12592
12593 // Check if we need the fallback indirect call still.
12594 if (SpecializedForAllCallees) {
12596 LastCmp->eraseFromParent();
12597 new UnreachableInst(IP->getContext(), IP);
12598 IP->eraseFromParent();
12599 } else {
12600 auto *CBClone = cast<CallInst>(CB->clone());
12601 CBClone->setName(CB->getName());
12602 CBClone->insertBefore(*IP->getParent(), IP);
12603 NewCalls.push_back({CBClone, nullptr});
12604 AttachCalleeMetadata(*CBClone);
12605 }
12606
12607 // Check if we need a PHI to merge the results.
12608 if (!CBIsVoid) {
12609 auto *PHI = PHINode::Create(CB->getType(), NewCalls.size(),
12610 CB->getName() + ".phi",
12611 CB->getParent()->getFirstInsertionPt());
12612 for (auto &It : NewCalls) {
12613 CallBase *NewCall = It.first;
12614 Instruction *CallRet = It.second ? It.second : It.first;
12615 if (CallRet->getType() == CB->getType())
12616 PHI->addIncoming(CallRet, CallRet->getParent());
12617 else if (NewCall->getType()->isVoidTy())
12618 PHI->addIncoming(PoisonValue::get(CB->getType()),
12619 NewCall->getParent());
12620 else
12621 llvm_unreachable("Call return should match or be void!");
12622 }
12623 A.changeAfterManifest(IRPosition::callsite_returned(*CB), *PHI);
12624 }
12625
12626 A.deleteAfterManifest(*CB);
12627 Changed = ChangeStatus::CHANGED;
12628
12629 return Changed;
12630 }
12631
12632 /// See AbstractAttribute::getAsStr().
12633 const std::string getAsStr(Attributor *A) const override {
12634 return std::string(AllCalleesKnown ? "eliminate" : "specialize") +
12635 " indirect call site with " + std::to_string(AssumedCallees.size()) +
12636 " functions";
12637 }
12638
12639 void trackStatistics() const override {
12640 if (AllCalleesKnown) {
12642 Eliminated, CallSites,
12643 "Number of indirect call sites eliminated via specialization")
12644 } else {
12645 STATS_DECLTRACK(Specialized, CallSites,
12646 "Number of indirect call sites specialized")
12647 }
12648 }
12649
12650 bool foreachCallee(function_ref<bool(Function *)> CB) const override {
12651 return isValidState() && AllCalleesKnown && all_of(AssumedCallees, CB);
12652 }
12653
12654private:
12655 /// Map to remember filter results.
12656 DenseMap<Function *, std::optional<bool>> FilterResults;
12657
12658 /// If the !callee metadata was present, this set will contain all potential
12659 /// callees (superset).
12660 SmallSetVector<Function *, 4> PotentialCallees;
12661
12662 /// This set contains all currently assumed calllees, which might grow over
12663 /// time.
12664 SmallSetVector<Function *, 4> AssumedCallees;
12665
12666 /// Flag to indicate if all possible callees are in the AssumedCallees set or
12667 /// if there could be others.
12668 bool AllCalleesKnown = true;
12669};
12670} // namespace
12671
12672/// --------------------- Invariant Load Pointer -------------------------------
12673namespace {
12674
12675struct AAInvariantLoadPointerImpl
12676 : public StateWrapper<BitIntegerState<uint8_t, 15>,
12677 AAInvariantLoadPointer> {
12678
12679 enum {
12680 // pointer does not alias within the bounds of the function
12681 IS_NOALIAS = 1 << 0,
12682 // pointer is not involved in any effectful instructions within the bounds
12683 // of the function
12684 IS_NOEFFECT = 1 << 1,
12685 // loads are invariant within the bounds of the function
12686 IS_LOCALLY_INVARIANT = 1 << 2,
12687 // memory lifetime is constrained within the bounds of the function
12688 IS_LOCALLY_CONSTRAINED = 1 << 3,
12689
12690 IS_BEST_STATE = IS_NOALIAS | IS_NOEFFECT | IS_LOCALLY_INVARIANT |
12691 IS_LOCALLY_CONSTRAINED,
12692 };
12693 static_assert(getBestState() == IS_BEST_STATE, "Unexpected best state");
12694
12695 using Base =
12696 StateWrapper<BitIntegerState<uint8_t, 15>, AAInvariantLoadPointer>;
12697
12698 // the BitIntegerState is optimistic about IS_NOALIAS and IS_NOEFFECT, but
12699 // pessimistic about IS_KNOWN_INVARIANT
12700 AAInvariantLoadPointerImpl(const IRPosition &IRP, Attributor &A)
12701 : Base(IRP) {}
12702
12703 bool isKnownInvariant() const final {
12704 return isKnownLocallyInvariant() && isKnown(IS_LOCALLY_CONSTRAINED);
12705 }
12706
12707 bool isKnownLocallyInvariant() const final {
12708 if (isKnown(IS_LOCALLY_INVARIANT))
12709 return true;
12710 return isKnown(IS_NOALIAS | IS_NOEFFECT);
12711 }
12712
12713 bool isAssumedInvariant() const final {
12714 return isAssumedLocallyInvariant() && isAssumed(IS_LOCALLY_CONSTRAINED);
12715 }
12716
12717 bool isAssumedLocallyInvariant() const final {
12718 if (isAssumed(IS_LOCALLY_INVARIANT))
12719 return true;
12720 return isAssumed(IS_NOALIAS | IS_NOEFFECT);
12721 }
12722
12723 ChangeStatus updateImpl(Attributor &A) override {
12724 ChangeStatus Changed = ChangeStatus::UNCHANGED;
12725
12726 Changed |= updateNoAlias(A);
12727 if (requiresNoAlias() && !isAssumed(IS_NOALIAS))
12728 return indicatePessimisticFixpoint();
12729
12730 Changed |= updateNoEffect(A);
12731
12732 Changed |= updateLocalInvariance(A);
12733
12734 return Changed;
12735 }
12736
12737 ChangeStatus manifest(Attributor &A) override {
12738 if (!isKnownInvariant())
12739 return ChangeStatus::UNCHANGED;
12740
12741 ChangeStatus Changed = ChangeStatus::UNCHANGED;
12742 const Value *Ptr = &getAssociatedValue();
12743 const auto TagInvariantLoads = [&](const Use &U, bool &) {
12744 if (U.get() != Ptr)
12745 return true;
12746 auto *I = dyn_cast<Instruction>(U.getUser());
12747 if (!I)
12748 return true;
12749
12750 // Ensure that we are only changing uses from the corresponding callgraph
12751 // SSC in the case that the AA isn't run on the entire module
12752 if (!A.isRunOn(I->getFunction()))
12753 return true;
12754
12755 if (I->hasMetadata(LLVMContext::MD_invariant_load))
12756 return true;
12757
12758 if (auto *LI = dyn_cast<LoadInst>(I)) {
12759 LI->setMetadata(LLVMContext::MD_invariant_load,
12760 MDNode::get(LI->getContext(), {}));
12761 Changed = ChangeStatus::CHANGED;
12762 }
12763 return true;
12764 };
12765
12766 (void)A.checkForAllUses(TagInvariantLoads, *this, *Ptr);
12767 return Changed;
12768 }
12769
12770 /// See AbstractAttribute::getAsStr().
12771 const std::string getAsStr(Attributor *) const override {
12772 if (isKnownInvariant())
12773 return "load-invariant pointer";
12774 return "non-invariant pointer";
12775 }
12776
12777 /// See AbstractAttribute::trackStatistics().
12778 void trackStatistics() const override {}
12779
12780private:
12781 /// Indicate that noalias is required for the pointer to be invariant.
12782 bool requiresNoAlias() const {
12783 switch (getPositionKind()) {
12784 default:
12785 // Conservatively default to require noalias.
12786 return true;
12787 case IRP_FLOAT:
12788 case IRP_RETURNED:
12789 case IRP_CALL_SITE:
12790 return false;
12791 case IRP_CALL_SITE_RETURNED: {
12792 const auto &CB = cast<CallBase>(getAnchorValue());
12794 &CB, /*MustPreserveOffset=*/false);
12795 }
12796 case IRP_ARGUMENT: {
12797 const Function *F = getAssociatedFunction();
12798 assert(F && "no associated function for argument");
12799 return !isCallableCC(F->getCallingConv());
12800 }
12801 }
12802 }
12803
12804 bool isExternal() const {
12805 const Function *F = getAssociatedFunction();
12806 if (!F)
12807 return true;
12808 return isCallableCC(F->getCallingConv()) &&
12809 getPositionKind() != IRP_CALL_SITE_RETURNED;
12810 }
12811
12812 ChangeStatus updateNoAlias(Attributor &A) {
12813 if (isKnown(IS_NOALIAS) || !isAssumed(IS_NOALIAS))
12814 return ChangeStatus::UNCHANGED;
12815
12816 // Try to use AANoAlias.
12817 if (const auto *ANoAlias = A.getOrCreateAAFor<AANoAlias>(
12818 getIRPosition(), this, DepClassTy::REQUIRED)) {
12819 if (ANoAlias->isKnownNoAlias()) {
12820 addKnownBits(IS_NOALIAS);
12821 return ChangeStatus::CHANGED;
12822 }
12823
12824 if (!ANoAlias->isAssumedNoAlias()) {
12825 removeAssumedBits(IS_NOALIAS);
12826 return ChangeStatus::CHANGED;
12827 }
12828
12829 return ChangeStatus::UNCHANGED;
12830 }
12831
12832 // Try to infer noalias from argument attribute, since it is applicable for
12833 // the duration of the function.
12834 if (const Argument *Arg = getAssociatedArgument()) {
12835 if (Arg->hasNoAliasAttr()) {
12836 addKnownBits(IS_NOALIAS);
12837 return ChangeStatus::UNCHANGED;
12838 }
12839
12840 // Noalias information is not provided, and cannot be inferred,
12841 // so we conservatively assume the pointer aliases.
12842 removeAssumedBits(IS_NOALIAS);
12843 return ChangeStatus::CHANGED;
12844 }
12845
12846 return ChangeStatus::UNCHANGED;
12847 }
12848
12849 ChangeStatus updateNoEffect(Attributor &A) {
12850 if (isKnown(IS_NOEFFECT) || !isAssumed(IS_NOEFFECT))
12851 return ChangeStatus::UNCHANGED;
12852
12853 if (!getAssociatedFunction())
12854 return indicatePessimisticFixpoint();
12855
12856 if (isa<AllocaInst>(&getAssociatedValue()))
12857 return indicatePessimisticFixpoint();
12858
12859 const auto HasNoEffectLoads = [&](const Use &U, bool &) {
12860 const auto *LI = dyn_cast<LoadInst>(U.getUser());
12861 return !LI || !LI->mayHaveSideEffects();
12862 };
12863 if (!A.checkForAllUses(HasNoEffectLoads, *this, getAssociatedValue()))
12864 return indicatePessimisticFixpoint();
12865
12866 if (const auto *AMemoryBehavior = A.getOrCreateAAFor<AAMemoryBehavior>(
12867 getIRPosition(), this, DepClassTy::REQUIRED)) {
12868 // For non-instructions, try to use AAMemoryBehavior to infer the readonly
12869 // attribute
12870 if (!AMemoryBehavior->isAssumedReadOnly())
12871 return indicatePessimisticFixpoint();
12872
12873 if (AMemoryBehavior->isKnownReadOnly()) {
12874 addKnownBits(IS_NOEFFECT);
12875 return ChangeStatus::UNCHANGED;
12876 }
12877
12878 return ChangeStatus::UNCHANGED;
12879 }
12880
12881 if (const Argument *Arg = getAssociatedArgument()) {
12882 if (Arg->onlyReadsMemory()) {
12883 addKnownBits(IS_NOEFFECT);
12884 return ChangeStatus::UNCHANGED;
12885 }
12886
12887 // Readonly information is not provided, and cannot be inferred from
12888 // AAMemoryBehavior.
12889 return indicatePessimisticFixpoint();
12890 }
12891
12892 return ChangeStatus::UNCHANGED;
12893 }
12894
12895 ChangeStatus updateLocalInvariance(Attributor &A) {
12896 if (isKnown(IS_LOCALLY_INVARIANT) || !isAssumed(IS_LOCALLY_INVARIANT))
12897 return ChangeStatus::UNCHANGED;
12898
12899 // try to infer invariance from underlying objects
12900 const auto *AUO = A.getOrCreateAAFor<AAUnderlyingObjects>(
12901 getIRPosition(), this, DepClassTy::REQUIRED);
12902 if (!AUO)
12903 return ChangeStatus::UNCHANGED;
12904
12905 bool UsedAssumedInformation = false;
12906 const auto IsLocallyInvariantLoadIfPointer = [&](const Value &V) {
12907 if (!V.getType()->isPointerTy())
12908 return true;
12909 const auto *IsInvariantLoadPointer =
12910 A.getOrCreateAAFor<AAInvariantLoadPointer>(IRPosition::value(V), this,
12911 DepClassTy::REQUIRED);
12912 // Conservatively fail if invariance cannot be inferred.
12913 if (!IsInvariantLoadPointer)
12914 return false;
12915
12916 if (IsInvariantLoadPointer->isKnownLocallyInvariant())
12917 return true;
12918 if (!IsInvariantLoadPointer->isAssumedLocallyInvariant())
12919 return false;
12920
12921 UsedAssumedInformation = true;
12922 return true;
12923 };
12924 if (!AUO->forallUnderlyingObjects(IsLocallyInvariantLoadIfPointer))
12925 return indicatePessimisticFixpoint();
12926
12927 if (const auto *CB = dyn_cast<CallBase>(&getAnchorValue())) {
12929 CB, /*MustPreserveOffset=*/false)) {
12930 for (const Value *Arg : CB->args()) {
12931 if (!IsLocallyInvariantLoadIfPointer(*Arg))
12932 return indicatePessimisticFixpoint();
12933 }
12934 }
12935 }
12936
12937 if (!UsedAssumedInformation) {
12938 // Pointer is known and not just assumed to be locally invariant.
12939 addKnownBits(IS_LOCALLY_INVARIANT);
12940 return ChangeStatus::CHANGED;
12941 }
12942
12943 return ChangeStatus::UNCHANGED;
12944 }
12945};
12946
12947struct AAInvariantLoadPointerFloating final : AAInvariantLoadPointerImpl {
12948 AAInvariantLoadPointerFloating(const IRPosition &IRP, Attributor &A)
12949 : AAInvariantLoadPointerImpl(IRP, A) {}
12950};
12951
12952struct AAInvariantLoadPointerReturned final : AAInvariantLoadPointerImpl {
12953 AAInvariantLoadPointerReturned(const IRPosition &IRP, Attributor &A)
12954 : AAInvariantLoadPointerImpl(IRP, A) {}
12955
12956 void initialize(Attributor &) override {
12957 removeAssumedBits(IS_LOCALLY_CONSTRAINED);
12958 }
12959};
12960
12961struct AAInvariantLoadPointerCallSiteReturned final
12962 : AAInvariantLoadPointerImpl {
12963 AAInvariantLoadPointerCallSiteReturned(const IRPosition &IRP, Attributor &A)
12964 : AAInvariantLoadPointerImpl(IRP, A) {}
12965
12966 void initialize(Attributor &A) override {
12967 const Function *F = getAssociatedFunction();
12968 assert(F && "no associated function for return from call");
12969
12970 if (!F->isDeclaration() && !F->isIntrinsic())
12971 return AAInvariantLoadPointerImpl::initialize(A);
12972
12973 const auto &CB = cast<CallBase>(getAnchorValue());
12975 &CB, /*MustPreserveOffset=*/false))
12976 return AAInvariantLoadPointerImpl::initialize(A);
12977
12978 if (F->onlyReadsMemory() && F->hasNoSync())
12979 return AAInvariantLoadPointerImpl::initialize(A);
12980
12981 // At this point, the function is opaque, so we conservatively assume
12982 // non-invariance.
12983 indicatePessimisticFixpoint();
12984 }
12985};
12986
12987struct AAInvariantLoadPointerArgument final : AAInvariantLoadPointerImpl {
12988 AAInvariantLoadPointerArgument(const IRPosition &IRP, Attributor &A)
12989 : AAInvariantLoadPointerImpl(IRP, A) {}
12990
12991 void initialize(Attributor &) override {
12992 const Function *F = getAssociatedFunction();
12993 assert(F && "no associated function for argument");
12994
12995 if (!isCallableCC(F->getCallingConv())) {
12996 addKnownBits(IS_LOCALLY_CONSTRAINED);
12997 return;
12998 }
12999
13000 if (!F->hasLocalLinkage())
13001 removeAssumedBits(IS_LOCALLY_CONSTRAINED);
13002 }
13003};
13004
13005struct AAInvariantLoadPointerCallSiteArgument final
13006 : AAInvariantLoadPointerImpl {
13007 AAInvariantLoadPointerCallSiteArgument(const IRPosition &IRP, Attributor &A)
13008 : AAInvariantLoadPointerImpl(IRP, A) {}
13009};
13010} // namespace
13011
13012/// ------------------------ Address Space ------------------------------------
13013namespace {
13014
13015template <typename InstType>
13016static bool makeChange(Attributor &A, InstType *MemInst, const Use &U,
13017 Value *OriginalValue, PointerType *NewPtrTy,
13018 bool UseOriginalValue) {
13019 if (U.getOperandNo() != InstType::getPointerOperandIndex())
13020 return false;
13021
13022 if (MemInst->isVolatile()) {
13023 auto *TTI = A.getInfoCache().getAnalysisResultForFunction<TargetIRAnalysis>(
13024 *MemInst->getFunction());
13025 unsigned NewAS = NewPtrTy->getPointerAddressSpace();
13026 if (!TTI || !TTI->hasVolatileVariant(MemInst, NewAS))
13027 return false;
13028 }
13029
13030 if (UseOriginalValue) {
13031 A.changeUseAfterManifest(const_cast<Use &>(U), *OriginalValue);
13032 return true;
13033 }
13034
13035 Instruction *CastInst = new AddrSpaceCastInst(OriginalValue, NewPtrTy);
13036 CastInst->insertBefore(MemInst->getIterator());
13037 A.changeUseAfterManifest(const_cast<Use &>(U), *CastInst);
13038 return true;
13039}
13040
13041struct AAAddressSpaceImpl : public AAAddressSpace {
13042 AAAddressSpaceImpl(const IRPosition &IRP, Attributor &A)
13043 : AAAddressSpace(IRP, A) {}
13044
13045 uint32_t getAddressSpace() const override {
13046 assert(isValidState() && "the AA is invalid");
13047 return AssumedAddressSpace;
13048 }
13049
13050 /// See AbstractAttribute::initialize(...).
13051 void initialize(Attributor &A) override {
13052 assert(getAssociatedType()->isPtrOrPtrVectorTy() &&
13053 "Associated value is not a pointer");
13054
13055 if (!A.getInfoCache().getFlatAddressSpace().has_value()) {
13056 indicatePessimisticFixpoint();
13057 return;
13058 }
13059
13060 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13061 unsigned AS = getAssociatedType()->getPointerAddressSpace();
13062 if (AS != FlatAS) {
13063 [[maybe_unused]] bool R = takeAddressSpace(AS);
13064 assert(R && "The take should happen");
13065 indicateOptimisticFixpoint();
13066 }
13067 }
13068
13069 ChangeStatus updateImpl(Attributor &A) override {
13070 uint32_t OldAddressSpace = AssumedAddressSpace;
13071 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13072
13073 auto CheckAddressSpace = [&](Value &Obj) {
13074 // Ignore undef.
13075 if (isa<UndefValue>(&Obj))
13076 return true;
13077
13078 // If the object already has a non-flat address space, we simply take it.
13079 unsigned ObjAS = Obj.getType()->getPointerAddressSpace();
13080 if (ObjAS != FlatAS)
13081 return takeAddressSpace(ObjAS);
13082
13083 // At this point, we know Obj is in the flat address space. For a final
13084 // attempt, we want to use getAssumedAddrSpace, but first we must get the
13085 // associated function, if possible.
13086 Function *F = nullptr;
13087 if (auto *Arg = dyn_cast<Argument>(&Obj))
13088 F = Arg->getParent();
13089 else if (auto *I = dyn_cast<Instruction>(&Obj))
13090 F = I->getFunction();
13091
13092 // Use getAssumedAddrSpace if the associated function exists.
13093 if (F) {
13094 auto *TTI =
13095 A.getInfoCache().getAnalysisResultForFunction<TargetIRAnalysis>(*F);
13096 unsigned AssumedAS = TTI->getAssumedAddrSpace(&Obj);
13097 if (AssumedAS != ~0U)
13098 return takeAddressSpace(AssumedAS);
13099 }
13100
13101 // Now we can't do anything else but to take the flat AS.
13102 return takeAddressSpace(FlatAS);
13103 };
13104
13105 auto *AUO = A.getOrCreateAAFor<AAUnderlyingObjects>(getIRPosition(), this,
13106 DepClassTy::REQUIRED);
13107 if (!AUO->forallUnderlyingObjects(CheckAddressSpace))
13108 return indicatePessimisticFixpoint();
13109
13110 return OldAddressSpace == AssumedAddressSpace ? ChangeStatus::UNCHANGED
13111 : ChangeStatus::CHANGED;
13112 }
13113
13114 /// See AbstractAttribute::manifest(...).
13115 ChangeStatus manifest(Attributor &A) override {
13116 unsigned NewAS = getAddressSpace();
13117
13118 if (NewAS == InvalidAddressSpace ||
13119 NewAS == getAssociatedType()->getPointerAddressSpace())
13120 return ChangeStatus::UNCHANGED;
13121
13122 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13123
13124 Value *AssociatedValue = &getAssociatedValue();
13125 Value *OriginalValue = peelAddrspacecast(AssociatedValue, FlatAS);
13126
13127 PointerType *NewPtrTy =
13128 PointerType::get(getAssociatedType()->getContext(), NewAS);
13129 bool UseOriginalValue =
13130 OriginalValue->getType()->getPointerAddressSpace() == NewAS;
13131
13132 bool Changed = false;
13133
13134 auto Pred = [&](const Use &U, bool &) {
13135 if (U.get() != AssociatedValue)
13136 return true;
13137 auto *Inst = dyn_cast<Instruction>(U.getUser());
13138 if (!Inst)
13139 return true;
13140 // This is a WA to make sure we only change uses from the corresponding
13141 // CGSCC if the AA is run on CGSCC instead of the entire module.
13142 if (!A.isRunOn(Inst->getFunction()))
13143 return true;
13144 if (auto *LI = dyn_cast<LoadInst>(Inst)) {
13145 Changed |=
13146 makeChange(A, LI, U, OriginalValue, NewPtrTy, UseOriginalValue);
13147 } else if (auto *SI = dyn_cast<StoreInst>(Inst)) {
13148 Changed |=
13149 makeChange(A, SI, U, OriginalValue, NewPtrTy, UseOriginalValue);
13150 } else if (auto *RMW = dyn_cast<AtomicRMWInst>(Inst)) {
13151 Changed |=
13152 makeChange(A, RMW, U, OriginalValue, NewPtrTy, UseOriginalValue);
13153 } else if (auto *CmpX = dyn_cast<AtomicCmpXchgInst>(Inst)) {
13154 Changed |=
13155 makeChange(A, CmpX, U, OriginalValue, NewPtrTy, UseOriginalValue);
13156 }
13157 return true;
13158 };
13159
13160 // It doesn't matter if we can't check all uses as we can simply
13161 // conservatively ignore those that can not be visited.
13162 (void)A.checkForAllUses(Pred, *this, getAssociatedValue(),
13163 /* CheckBBLivenessOnly */ true);
13164
13165 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
13166 }
13167
13168 /// See AbstractAttribute::getAsStr().
13169 const std::string getAsStr(Attributor *A) const override {
13170 if (!isValidState())
13171 return "addrspace(<invalid>)";
13172 return "addrspace(" +
13173 (AssumedAddressSpace == InvalidAddressSpace
13174 ? "none"
13175 : std::to_string(AssumedAddressSpace)) +
13176 ")";
13177 }
13178
13179private:
13180 uint32_t AssumedAddressSpace = InvalidAddressSpace;
13181
13182 bool takeAddressSpace(uint32_t AS) {
13183 if (AssumedAddressSpace == InvalidAddressSpace) {
13184 AssumedAddressSpace = AS;
13185 return true;
13186 }
13187 return AssumedAddressSpace == AS;
13188 }
13189
13190 static Value *peelAddrspacecast(Value *V, unsigned FlatAS) {
13191 if (auto *I = dyn_cast<AddrSpaceCastInst>(V)) {
13192 assert(I->getSrcAddressSpace() != FlatAS &&
13193 "there should not be flat AS -> non-flat AS");
13194 return I->getPointerOperand();
13195 }
13196 if (auto *C = dyn_cast<ConstantExpr>(V))
13197 if (C->getOpcode() == Instruction::AddrSpaceCast) {
13198 assert(C->getOperand(0)->getType()->getPointerAddressSpace() !=
13199 FlatAS &&
13200 "there should not be flat AS -> non-flat AS X");
13201 return C->getOperand(0);
13202 }
13203 return V;
13204 }
13205};
13206
13207struct AAAddressSpaceFloating final : AAAddressSpaceImpl {
13208 AAAddressSpaceFloating(const IRPosition &IRP, Attributor &A)
13209 : AAAddressSpaceImpl(IRP, A) {}
13210
13211 void trackStatistics() const override {
13213 }
13214};
13215
13216struct AAAddressSpaceReturned final : AAAddressSpaceImpl {
13217 AAAddressSpaceReturned(const IRPosition &IRP, Attributor &A)
13218 : AAAddressSpaceImpl(IRP, A) {}
13219
13220 /// See AbstractAttribute::initialize(...).
13221 void initialize(Attributor &A) override {
13222 // TODO: we don't rewrite function argument for now because it will need to
13223 // rewrite the function signature and all call sites.
13224 (void)indicatePessimisticFixpoint();
13225 }
13226
13227 void trackStatistics() const override {
13228 STATS_DECLTRACK_FNRET_ATTR(addrspace);
13229 }
13230};
13231
13232struct AAAddressSpaceCallSiteReturned final : AAAddressSpaceImpl {
13233 AAAddressSpaceCallSiteReturned(const IRPosition &IRP, Attributor &A)
13234 : AAAddressSpaceImpl(IRP, A) {}
13235
13236 void trackStatistics() const override {
13237 STATS_DECLTRACK_CSRET_ATTR(addrspace);
13238 }
13239};
13240
13241struct AAAddressSpaceArgument final : AAAddressSpaceImpl {
13242 AAAddressSpaceArgument(const IRPosition &IRP, Attributor &A)
13243 : AAAddressSpaceImpl(IRP, A) {}
13244
13245 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(addrspace); }
13246};
13247
13248struct AAAddressSpaceCallSiteArgument final : AAAddressSpaceImpl {
13249 AAAddressSpaceCallSiteArgument(const IRPosition &IRP, Attributor &A)
13250 : AAAddressSpaceImpl(IRP, A) {}
13251
13252 /// See AbstractAttribute::initialize(...).
13253 void initialize(Attributor &A) override {
13254 // TODO: we don't rewrite call site argument for now because it will need to
13255 // rewrite the function signature of the callee.
13256 (void)indicatePessimisticFixpoint();
13257 }
13258
13259 void trackStatistics() const override {
13260 STATS_DECLTRACK_CSARG_ATTR(addrspace);
13261 }
13262};
13263} // namespace
13264
13265/// ------------------------ No Alias Address Space ---------------------------
13266// This attribute assumes flat address space can alias all other address space
13267
13268// TODO: this is similar to AAAddressSpace, most of the code should be merged.
13269// But merging it created failing cased on gateway test that cannot be
13270// reproduced locally. So should open a separated PR to handle the merge of
13271// AANoAliasAddrSpace and AAAddressSpace attribute
13272
13273namespace {
13274struct AANoAliasAddrSpaceImpl : public AANoAliasAddrSpace {
13275 AANoAliasAddrSpaceImpl(const IRPosition &IRP, Attributor &A)
13276 : AANoAliasAddrSpace(IRP, A) {}
13277
13278 void initialize(Attributor &A) override {
13279 assert(getAssociatedType()->isPtrOrPtrVectorTy() &&
13280 "Associated value is not a pointer");
13281
13282 resetASRanges(A);
13283
13284 std::optional<unsigned> FlatAS = A.getInfoCache().getFlatAddressSpace();
13285 if (!FlatAS.has_value()) {
13286 indicatePessimisticFixpoint();
13287 return;
13288 }
13289
13290 removeAS(*FlatAS);
13291
13292 unsigned AS = getAssociatedType()->getPointerAddressSpace();
13293 if (AS != *FlatAS) {
13294 removeAS(AS);
13295 indicateOptimisticFixpoint();
13296 }
13297 }
13298
13299 ChangeStatus updateImpl(Attributor &A) override {
13300 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13301 uint32_t OldAssumed = getAssumed();
13302
13303 auto CheckAddressSpace = [&](Value &Obj) {
13304 if (isa<PoisonValue>(&Obj))
13305 return true;
13306
13307 unsigned AS = Obj.getType()->getPointerAddressSpace();
13308 if (AS == FlatAS)
13309 return false;
13310
13311 removeAS(Obj.getType()->getPointerAddressSpace());
13312 return true;
13313 };
13314
13315 const AAUnderlyingObjects *AUO = A.getOrCreateAAFor<AAUnderlyingObjects>(
13316 getIRPosition(), this, DepClassTy::REQUIRED);
13317 if (!AUO->forallUnderlyingObjects(CheckAddressSpace))
13318 return indicatePessimisticFixpoint();
13319
13320 return OldAssumed == getAssumed() ? ChangeStatus::UNCHANGED
13321 : ChangeStatus::CHANGED;
13322 }
13323
13324 /// See AbstractAttribute::manifest(...).
13325 ChangeStatus manifest(Attributor &A) override {
13326 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13327
13328 unsigned AS = getAssociatedType()->getPointerAddressSpace();
13329 if (AS != FlatAS || Map.empty())
13330 return ChangeStatus::UNCHANGED;
13331
13332 LLVMContext &Ctx = getAssociatedValue().getContext();
13333 MDNode *NoAliasASNode = nullptr;
13334 MDBuilder MDB(Ctx);
13335 // Has to use iterator to get the range info.
13336 for (RangeMap::const_iterator I = Map.begin(); I != Map.end(); I++) {
13337 if (!I.value())
13338 continue;
13339 unsigned Upper = I.stop();
13340 unsigned Lower = I.start();
13341 if (!NoAliasASNode) {
13342 NoAliasASNode = MDB.createRange(APInt(32, Lower), APInt(32, Upper + 1));
13343 continue;
13344 }
13345 MDNode *ASRange = MDB.createRange(APInt(32, Lower), APInt(32, Upper + 1));
13346 NoAliasASNode = MDNode::getMostGenericRange(NoAliasASNode, ASRange);
13347 }
13348
13349 Value *AssociatedValue = &getAssociatedValue();
13350 bool Changed = false;
13351
13352 auto AddNoAliasAttr = [&](const Use &U, bool &) {
13353 if (U.get() != AssociatedValue)
13354 return true;
13355 Instruction *Inst = dyn_cast<Instruction>(U.getUser());
13356 if (!Inst || Inst->hasMetadata(LLVMContext::MD_noalias_addrspace))
13357 return true;
13358 if (!isa<LoadInst>(Inst) && !isa<StoreInst>(Inst) &&
13360 return true;
13361 if (!A.isRunOn(Inst->getFunction()))
13362 return true;
13363 Inst->setMetadata(LLVMContext::MD_noalias_addrspace, NoAliasASNode);
13364 Changed = true;
13365 return true;
13366 };
13367 (void)A.checkForAllUses(AddNoAliasAttr, *this, *AssociatedValue,
13368 /*CheckBBLivenessOnly=*/true);
13369 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
13370 }
13371
13372 /// See AbstractAttribute::getAsStr().
13373 const std::string getAsStr(Attributor *A) const override {
13374 if (!isValidState())
13375 return "<invalid>";
13376 std::string Str;
13377 raw_string_ostream OS(Str);
13378 OS << "CanNotBeAddrSpace(";
13379 for (RangeMap::const_iterator I = Map.begin(); I != Map.end(); I++) {
13380 unsigned Upper = I.stop();
13381 unsigned Lower = I.start();
13382 OS << ' ' << '[' << Upper << ',' << Lower + 1 << ')';
13383 }
13384 OS << " )";
13385 return OS.str();
13386 }
13387
13388private:
13389 void removeAS(unsigned AS) {
13390 RangeMap::iterator I = Map.find(AS);
13391
13392 if (I != Map.end()) {
13393 unsigned Upper = I.stop();
13394 unsigned Lower = I.start();
13395 I.erase();
13396 if (Upper == Lower)
13397 return;
13398 if (AS != ~((unsigned)0) && AS + 1 <= Upper)
13399 Map.insert(AS + 1, Upper, /*what ever this variable name is=*/true);
13400 if (AS != 0 && Lower <= AS - 1)
13401 Map.insert(Lower, AS - 1, true);
13402 }
13403 }
13404
13405 void resetASRanges(Attributor &A) {
13406 Map.clear();
13407 Map.insert(0, A.getInfoCache().getMaxAddrSpace(), true);
13408 }
13409};
13410
13411struct AANoAliasAddrSpaceFloating final : AANoAliasAddrSpaceImpl {
13412 AANoAliasAddrSpaceFloating(const IRPosition &IRP, Attributor &A)
13413 : AANoAliasAddrSpaceImpl(IRP, A) {}
13414
13415 void trackStatistics() const override {
13416 STATS_DECLTRACK_FLOATING_ATTR(noaliasaddrspace);
13417 }
13418};
13419
13420struct AANoAliasAddrSpaceReturned final : AANoAliasAddrSpaceImpl {
13421 AANoAliasAddrSpaceReturned(const IRPosition &IRP, Attributor &A)
13422 : AANoAliasAddrSpaceImpl(IRP, A) {}
13423
13424 void trackStatistics() const override {
13425 STATS_DECLTRACK_FNRET_ATTR(noaliasaddrspace);
13426 }
13427};
13428
13429struct AANoAliasAddrSpaceCallSiteReturned final : AANoAliasAddrSpaceImpl {
13430 AANoAliasAddrSpaceCallSiteReturned(const IRPosition &IRP, Attributor &A)
13431 : AANoAliasAddrSpaceImpl(IRP, A) {}
13432
13433 void trackStatistics() const override {
13434 STATS_DECLTRACK_CSRET_ATTR(noaliasaddrspace);
13435 }
13436};
13437
13438struct AANoAliasAddrSpaceArgument final : AANoAliasAddrSpaceImpl {
13439 AANoAliasAddrSpaceArgument(const IRPosition &IRP, Attributor &A)
13440 : AANoAliasAddrSpaceImpl(IRP, A) {}
13441
13442 void trackStatistics() const override {
13443 STATS_DECLTRACK_ARG_ATTR(noaliasaddrspace);
13444 }
13445};
13446
13447struct AANoAliasAddrSpaceCallSiteArgument final : AANoAliasAddrSpaceImpl {
13448 AANoAliasAddrSpaceCallSiteArgument(const IRPosition &IRP, Attributor &A)
13449 : AANoAliasAddrSpaceImpl(IRP, A) {}
13450
13451 void trackStatistics() const override {
13452 STATS_DECLTRACK_CSARG_ATTR(noaliasaddrspace);
13453 }
13454};
13455} // namespace
13456/// ----------- Allocation Info ----------
13457namespace {
13458struct AAAllocationInfoImpl : public AAAllocationInfo {
13459 AAAllocationInfoImpl(const IRPosition &IRP, Attributor &A)
13460 : AAAllocationInfo(IRP, A) {}
13461
13462 std::optional<TypeSize> getAllocatedSize() const override {
13463 assert(isValidState() && "the AA is invalid");
13464 return AssumedAllocatedSize;
13465 }
13466
13467 std::optional<TypeSize> findInitialAllocationSize(Instruction *I,
13468 const DataLayout &DL) {
13469
13470 // TODO: implement case for malloc like instructions
13471 switch (I->getOpcode()) {
13472 case Instruction::Alloca: {
13473 AllocaInst *AI = cast<AllocaInst>(I);
13474 return AI->getAllocationSize(DL);
13475 }
13476 default:
13477 return std::nullopt;
13478 }
13479 }
13480
13481 ChangeStatus updateImpl(Attributor &A) override {
13482
13483 const IRPosition &IRP = getIRPosition();
13484 Instruction *I = IRP.getCtxI();
13485
13486 // TODO: update check for malloc like calls
13487 if (!isa<AllocaInst>(I))
13488 return indicatePessimisticFixpoint();
13489
13490 bool IsKnownNoCapture;
13492 A, this, IRP, DepClassTy::OPTIONAL, IsKnownNoCapture))
13493 return indicatePessimisticFixpoint();
13494
13495 const AAPointerInfo *PI =
13496 A.getOrCreateAAFor<AAPointerInfo>(IRP, *this, DepClassTy::REQUIRED);
13497
13498 if (!PI)
13499 return indicatePessimisticFixpoint();
13500
13501 if (!PI->getState().isValidState() || PI->reachesReturn())
13502 return indicatePessimisticFixpoint();
13503
13504 const DataLayout &DL = A.getDataLayout();
13505 const auto AllocationSize = findInitialAllocationSize(I, DL);
13506
13507 // If allocation size is nullopt, we give up.
13508 if (!AllocationSize)
13509 return indicatePessimisticFixpoint();
13510
13511 // For zero sized allocations, we give up.
13512 // Since we can't reduce further
13513 if (*AllocationSize == 0)
13514 return indicatePessimisticFixpoint();
13515
13516 int64_t BinSize = PI->numOffsetBins();
13517
13518 // TODO: implement for multiple bins
13519 if (BinSize > 1)
13520 return indicatePessimisticFixpoint();
13521
13522 if (BinSize == 0) {
13523 auto NewAllocationSize = std::make_optional<TypeSize>(0, false);
13524 if (!changeAllocationSize(NewAllocationSize))
13525 return ChangeStatus::UNCHANGED;
13526 return ChangeStatus::CHANGED;
13527 }
13528
13529 // TODO: refactor this to be part of multiple bin case
13530 const auto &It = PI->begin();
13531
13532 // TODO: handle if Offset is not zero
13533 if (It->first.Offset != 0)
13534 return indicatePessimisticFixpoint();
13535
13536 uint64_t SizeOfBin = It->first.Offset + It->first.Size;
13537
13538 if (SizeOfBin >= *AllocationSize)
13539 return indicatePessimisticFixpoint();
13540
13541 auto NewAllocationSize = std::make_optional<TypeSize>(SizeOfBin * 8, false);
13542
13543 if (!changeAllocationSize(NewAllocationSize))
13544 return ChangeStatus::UNCHANGED;
13545
13546 return ChangeStatus::CHANGED;
13547 }
13548
13549 /// See AbstractAttribute::manifest(...).
13550 ChangeStatus manifest(Attributor &A) override {
13551
13552 assert(isValidState() &&
13553 "Manifest should only be called if the state is valid.");
13554
13555 Instruction *I = getIRPosition().getCtxI();
13556
13557 auto FixedAllocatedSizeInBits = getAllocatedSize()->getFixedValue();
13558
13559 unsigned long NumBytesToAllocate = (FixedAllocatedSizeInBits + 7) / 8;
13560
13561 switch (I->getOpcode()) {
13562 // TODO: add case for malloc like calls
13563 case Instruction::Alloca: {
13564
13565 AllocaInst *AI = cast<AllocaInst>(I);
13566
13567 Type *CharType = Type::getInt8Ty(I->getContext());
13568
13569 auto *NumBytesToValue =
13570 ConstantInt::get(I->getContext(), APInt(32, NumBytesToAllocate));
13571
13572 BasicBlock::iterator insertPt = AI->getIterator();
13573 insertPt = std::next(insertPt);
13574 AllocaInst *NewAllocaInst =
13575 new AllocaInst(CharType, AI->getAddressSpace(), NumBytesToValue,
13576 AI->getAlign(), AI->getName(), insertPt);
13577
13578 if (A.changeAfterManifest(IRPosition::inst(*AI), *NewAllocaInst))
13579 return ChangeStatus::CHANGED;
13580
13581 break;
13582 }
13583 default:
13584 break;
13585 }
13586
13587 return ChangeStatus::UNCHANGED;
13588 }
13589
13590 /// See AbstractAttribute::getAsStr().
13591 const std::string getAsStr(Attributor *A) const override {
13592 if (!isValidState())
13593 return "allocationinfo(<invalid>)";
13594 return "allocationinfo(" +
13595 (AssumedAllocatedSize == HasNoAllocationSize
13596 ? "none"
13597 : std::to_string(AssumedAllocatedSize->getFixedValue())) +
13598 ")";
13599 }
13600
13601private:
13602 std::optional<TypeSize> AssumedAllocatedSize = HasNoAllocationSize;
13603
13604 // Maintain the computed allocation size of the object.
13605 // Returns (bool) weather the size of the allocation was modified or not.
13606 bool changeAllocationSize(std::optional<TypeSize> Size) {
13607 if (AssumedAllocatedSize == HasNoAllocationSize ||
13608 AssumedAllocatedSize != Size) {
13609 AssumedAllocatedSize = Size;
13610 return true;
13611 }
13612 return false;
13613 }
13614};
13615
13616struct AAAllocationInfoFloating : AAAllocationInfoImpl {
13617 AAAllocationInfoFloating(const IRPosition &IRP, Attributor &A)
13618 : AAAllocationInfoImpl(IRP, A) {}
13619
13620 void trackStatistics() const override {
13621 STATS_DECLTRACK_FLOATING_ATTR(allocationinfo);
13622 }
13623};
13624
13625struct AAAllocationInfoReturned : AAAllocationInfoImpl {
13626 AAAllocationInfoReturned(const IRPosition &IRP, Attributor &A)
13627 : AAAllocationInfoImpl(IRP, A) {}
13628
13629 /// See AbstractAttribute::initialize(...).
13630 void initialize(Attributor &A) override {
13631 // TODO: we don't rewrite function argument for now because it will need to
13632 // rewrite the function signature and all call sites
13633 (void)indicatePessimisticFixpoint();
13634 }
13635
13636 void trackStatistics() const override {
13637 STATS_DECLTRACK_FNRET_ATTR(allocationinfo);
13638 }
13639};
13640
13641struct AAAllocationInfoCallSiteReturned : AAAllocationInfoImpl {
13642 AAAllocationInfoCallSiteReturned(const IRPosition &IRP, Attributor &A)
13643 : AAAllocationInfoImpl(IRP, A) {}
13644
13645 void trackStatistics() const override {
13646 STATS_DECLTRACK_CSRET_ATTR(allocationinfo);
13647 }
13648};
13649
13650struct AAAllocationInfoArgument : AAAllocationInfoImpl {
13651 AAAllocationInfoArgument(const IRPosition &IRP, Attributor &A)
13652 : AAAllocationInfoImpl(IRP, A) {}
13653
13654 void trackStatistics() const override {
13655 STATS_DECLTRACK_ARG_ATTR(allocationinfo);
13656 }
13657};
13658
13659struct AAAllocationInfoCallSiteArgument : AAAllocationInfoImpl {
13660 AAAllocationInfoCallSiteArgument(const IRPosition &IRP, Attributor &A)
13661 : AAAllocationInfoImpl(IRP, A) {}
13662
13663 /// See AbstractAttribute::initialize(...).
13664 void initialize(Attributor &A) override {
13665
13666 (void)indicatePessimisticFixpoint();
13667 }
13668
13669 void trackStatistics() const override {
13670 STATS_DECLTRACK_CSARG_ATTR(allocationinfo);
13671 }
13672};
13673} // namespace
13674
13675const char AANoUnwind::ID = 0;
13676const char AANoSync::ID = 0;
13677const char AANoFree::ID = 0;
13678const char AANonNull::ID = 0;
13679const char AAMustProgress::ID = 0;
13680const char AANoRecurse::ID = 0;
13681const char AANonConvergent::ID = 0;
13682const char AAWillReturn::ID = 0;
13683const char AAUndefinedBehavior::ID = 0;
13684const char AANoAlias::ID = 0;
13685const char AAIntraFnReachability::ID = 0;
13686const char AANoReturn::ID = 0;
13687const char AAIsDead::ID = 0;
13688const char AADereferenceable::ID = 0;
13689const char AAAlign::ID = 0;
13690const char AAInstanceInfo::ID = 0;
13691const char AANoCapture::ID = 0;
13692const char AAValueSimplify::ID = 0;
13693const char AAHeapToStack::ID = 0;
13694const char AAPrivatizablePtr::ID = 0;
13695const char AAMemoryBehavior::ID = 0;
13696const char AAMemoryLocation::ID = 0;
13697const char AAValueConstantRange::ID = 0;
13698const char AAPotentialConstantValues::ID = 0;
13699const char AAPotentialValues::ID = 0;
13700const char AANoUndef::ID = 0;
13701const char AANoFPClass::ID = 0;
13702const char AACallEdges::ID = 0;
13703const char AAInterFnReachability::ID = 0;
13704const char AAPointerInfo::ID = 0;
13705const char AAAssumptionInfo::ID = 0;
13706const char AAUnderlyingObjects::ID = 0;
13707const char AAInvariantLoadPointer::ID = 0;
13708const char AAAddressSpace::ID = 0;
13709const char AANoAliasAddrSpace::ID = 0;
13710const char AAAllocationInfo::ID = 0;
13711const char AAIndirectCallInfo::ID = 0;
13712const char AAGlobalValueInfo::ID = 0;
13713const char AADenormalFPMath::ID = 0;
13714
13715// Macro magic to create the static generator function for attributes that
13716// follow the naming scheme.
13717
13718#define SWITCH_PK_INV(CLASS, PK, POS_NAME) \
13719 case IRPosition::PK: \
13720 llvm_unreachable("Cannot create " #CLASS " for a " POS_NAME " position!");
13721
13722#define SWITCH_PK_CREATE(CLASS, IRP, PK, SUFFIX) \
13723 case IRPosition::PK: \
13724 AA = new (A.Allocator) CLASS##SUFFIX(IRP, A); \
13725 ++NumAAs; \
13726 break;
13727
13728#define CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13729 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13730 CLASS *AA = nullptr; \
13731 switch (IRP.getPositionKind()) { \
13732 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13733 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
13734 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
13735 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
13736 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
13737 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
13738 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
13739 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
13740 } \
13741 return *AA; \
13742 }
13743
13744#define CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13745 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13746 CLASS *AA = nullptr; \
13747 switch (IRP.getPositionKind()) { \
13748 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13749 SWITCH_PK_INV(CLASS, IRP_FUNCTION, "function") \
13750 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
13751 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
13752 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
13753 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
13754 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
13755 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
13756 } \
13757 return *AA; \
13758 }
13759
13760#define CREATE_ABSTRACT_ATTRIBUTE_FOR_ONE_POSITION(POS, SUFFIX, CLASS) \
13761 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13762 CLASS *AA = nullptr; \
13763 switch (IRP.getPositionKind()) { \
13764 SWITCH_PK_CREATE(CLASS, IRP, POS, SUFFIX) \
13765 default: \
13766 llvm_unreachable("Cannot create " #CLASS " for position otherthan " #POS \
13767 " position!"); \
13768 } \
13769 return *AA; \
13770 }
13771
13772#define CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13773 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13774 CLASS *AA = nullptr; \
13775 switch (IRP.getPositionKind()) { \
13776 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13777 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
13778 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
13779 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
13780 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
13781 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
13782 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
13783 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
13784 } \
13785 return *AA; \
13786 }
13787
13788#define CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13789 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13790 CLASS *AA = nullptr; \
13791 switch (IRP.getPositionKind()) { \
13792 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13793 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
13794 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
13795 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
13796 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
13797 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
13798 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
13799 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
13800 } \
13801 return *AA; \
13802 }
13803
13804#define CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13805 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13806 CLASS *AA = nullptr; \
13807 switch (IRP.getPositionKind()) { \
13808 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13809 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
13810 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
13811 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
13812 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
13813 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
13814 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
13815 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
13816 } \
13817 return *AA; \
13818 }
13819
13829
13847
13852
13857
13864
13866
13867#undef CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION
13868#undef CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION
13869#undef CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION
13870#undef CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION
13871#undef CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION
13872#undef CREATE_ABSTRACT_ATTRIBUTE_FOR_ONE_POSITION
13873#undef SWITCH_PK_CREATE
13874#undef SWITCH_PK_INV
#define Success
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
aarch64 promote const
AMDGPU Register Bank Select
Rewrite undef for PHI
This file implements a class to represent arbitrary precision integral constant values and operations...
ReachingDefInfo InstSet & ToRemove
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis false
This file contains the simple types necessary to represent the attributes associated with functions a...
#define STATS_DECLTRACK(NAME, TYPE, MSG)
static std::optional< Constant * > askForAssumedConstant(Attributor &A, const AbstractAttribute &QueryingAA, const IRPosition &IRP, Type &Ty)
static cl::opt< unsigned, true > MaxPotentialValues("attributor-max-potential-values", cl::Hidden, cl::desc("Maximum number of potential values to be " "tracked for each position."), cl::location(llvm::PotentialConstantIntValuesState::MaxPotentialValues), cl::init(7))
static void clampReturnedValueStates(Attributor &A, const AAType &QueryingAA, StateType &S, const IRPosition::CallBaseContext *CBContext=nullptr)
Clamp the information known for all returned values of a function (identified by QueryingAA) into S.
#define STATS_DECLTRACK_FN_ATTR(NAME)
#define CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
static cl::opt< int > MaxPotentialValuesIterations("attributor-max-potential-values-iterations", cl::Hidden, cl::desc("Maximum number of iterations we keep dismantling potential values."), cl::init(64))
#define STATS_DECLTRACK_CS_ATTR(NAME)
#define PIPE_OPERATOR(CLASS)
#define DefineKeys(ToTy)
static bool mayBeInCycle(const CycleInfo *CI, const Instruction *I, bool HeaderOnly, Cycle **CPtr=nullptr)
#define STATS_DECLTRACK_ARG_ATTR(NAME)
static const Value * stripAndAccumulateOffsets(Attributor &A, const AbstractAttribute &QueryingAA, const Value *Val, const DataLayout &DL, APInt &Offset, bool GetMinOffset, bool AllowNonInbounds, bool UseAssumed=false)
#define STATS_DECLTRACK_CSRET_ATTR(NAME)
static cl::opt< bool > ManifestInternal("attributor-manifest-internal", cl::Hidden, cl::desc("Manifest Attributor internal string attributes."), cl::init(false))
static Value * constructPointer(Value *Ptr, int64_t Offset, IRBuilder< NoFolder > &IRB)
Helper function to create a pointer based on Ptr, and advanced by Offset bytes.
#define CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
#define BUILD_STAT_NAME(NAME, TYPE)
static bool isDenselyPacked(Type *Ty, const DataLayout &DL)
Checks if a type could have padding bytes.
#define CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
static const Value * getMinimalBaseOfPointer(Attributor &A, const AbstractAttribute &QueryingAA, const Value *Ptr, int64_t &BytesOffset, const DataLayout &DL, bool AllowNonInbounds=false)
#define STATS_DECLTRACK_FNRET_ATTR(NAME)
#define STATS_DECLTRACK_CSARG_ATTR(NAME)
#define CREATE_ABSTRACT_ATTRIBUTE_FOR_ONE_POSITION(POS, SUFFIX, CLASS)
#define CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
static cl::opt< int > MaxHeapToStackSize("max-heap-to-stack-size", cl::init(128), cl::Hidden)
#define CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
#define STATS_DECLTRACK_FLOATING_ATTR(NAME)
#define STATS_DECL(NAME, TYPE, MSG)
basic Basic Alias true
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static bool isReachableImpl(SmallVectorImpl< BasicBlock * > &Worklist, const StopSetT &StopSet, const SmallPtrSetImpl< BasicBlock * > *ExclusionSet, const DominatorTree *DT, const LoopInfo *LI, const CycleInfo *CI)
Definition CFG.cpp:145
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file declares an analysis pass that computes CycleInfo for LLVM IR, specialized from GenericCycl...
DXIL Forward Handle Accesses
DXIL Resource Access
dxil translate DXIL Translate Metadata
This file defines DenseMapInfo traits for DenseMap.
#define Check(C,...)
Hexagon Common GEP
IRTranslator LLVM IR MI
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
Machine Check Debug Module
This file implements a map that provides insertion order iteration.
#define T
#define T1
static unsigned getAddressSpace(const Value *V, unsigned MaxLookup)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
uint64_t IntrinsicInst * II
if(PassOpts->AAPipeline)
static StringRef getName(Value *V)
Basic Register Allocator
dot regions Print regions of function to dot true view regions View regions of function(with no function bodies)"
Remove Loads Into Fake Uses
This builds on the llvm/ADT/GraphTraits.h file to find the strongly connected components (SCCs) of a ...
bool IsDead
std::pair< BasicBlock *, BasicBlock * > Edge
This file contains some templates that are useful if you are working with the STL at all.
BaseType
A given derived pointer can have multiple base pointers through phi/selects.
This file defines generic set operations that may be used on set's of different types,...
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition Statistic.h:171
This file contains some functions that are useful when dealing with strings.
#define LLVM_DEBUG(...)
Definition Debug.h: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:272
LLVM_ABI bool onlyReadsMemory() const
Return true if this argument has the readonly or readnone attribute.
Definition Function.cpp:308
LLVM_ABI bool hasPointeeInMemoryValueAttr() const
Return true if this argument has the byval, sret, inalloca, preallocated, or byref attribute.
Definition Function.cpp:171
LLVM_ABI bool hasReturnedAttr() const
Return true if this argument has the returned attribute.
Definition Function.cpp:296
LLVM_ABI bool hasByValAttr() const
Return true if this argument has the byval attribute.
Definition Function.cpp:128
const Function * getParent() const
Definition Argument.h:44
unsigned getArgNo() const
Return the index of this formal argument in its containing function.
Definition Argument.h:50
A function analysis which provides an AssumptionCache.
A cache of @llvm.assume calls within a function.
Functions, function parameters, and return types can have attributes to indicate how they should be t...
Definition Attributes.h:105
static LLVM_ABI Attribute get(LLVMContext &Context, AttrKind Kind, uint64_t Val=0)
Return a uniquified Attribute object.
LLVM_ABI FPClassTest getNoFPClass() const
Return the FPClassTest for nofpclass.
LLVM_ABI Attribute::AttrKind getKindAsEnum() const
Return the attribute's kind as an enum (Attribute::AttrKind).
LLVM_ABI MemoryEffects getMemoryEffects() const
Returns memory effects.
AttrKind
This enumeration lists the attributes that can be associated with parameters, function results,...
Definition Attributes.h:124
static LLVM_ABI Attribute getWithCaptureInfo(LLVMContext &Context, CaptureInfo CI)
static bool isEnumAttrKind(AttrKind Kind)
Definition Attributes.h:137
bool isValid() const
Return true if the attribute is any kind of attribute.
Definition Attributes.h:261
LLVM_ABI CaptureInfo getCaptureInfo() const
Returns information from captures attribute.
LLVM Basic Block Representation.
Definition BasicBlock.h:62
LLVM_ABI const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
const Function * getParent() const
Return the enclosing method, or null if none.
Definition BasicBlock.h:213
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition BasicBlock.h:206
const Instruction & front() const
Definition BasicBlock.h:484
InstListType::iterator iterator
Instruction iterators...
Definition BasicBlock.h:170
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
Definition BasicBlock.h:237
BinaryOps getOpcode() const
Definition InstrTypes.h: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:178
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
Definition DenseMap.h:254
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
Definition DenseMap.h:174
iterator end()
Definition DenseMap.h:85
bool contains(const_arg_type_t< KeyT > Val) const
Return true if the specified key is in the map, false otherwise.
Definition DenseMap.h:169
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition DenseMap.h:239
Analysis pass which computes a DominatorTree.
Definition Dominators.h:278
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition Dominators.h:159
LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
const BasicBlock & getEntryBlock() const
Definition Function.h:809
Argument * arg_iterator
Definition Function.h:73
iterator_range< arg_iterator > args()
Definition Function.h:892
const Function & getFunction() const
Definition Function.h:166
size_t arg_size() const
Definition Function.h:901
Argument * getArg(unsigned i) const
Definition Function.h:886
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition Function.cpp:728
CycleT * getCycle(const BlockT *Block) const
Find the innermost cycle containing a given block.
LLVM_ABI bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
Definition Globals.cpp:392
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:2091
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:2858
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:1572
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:549
LLVMContext & getContext() const
All values hold a context through their type.
Definition Value.h:258
iterator_range< user_iterator > users()
Definition Value.h:426
LLVM_ABI const Value * stripAndAccumulateConstantOffsets(const DataLayout &DL, APInt &Offset, bool AllowNonInbounds, bool AllowInvariantGroup=false, function_ref< bool(Value &Value, APInt &Offset)> ExternalAnalysis=nullptr, bool LookThroughIntToPtr=false) const
Accumulate the constant offset this value has compared to a base pointer.
bool use_empty() const
Definition Value.h:346
static constexpr unsigned MaxAlignmentExponent
The maximum alignment for instructions.
Definition Value.h: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
constexpr double e
@ User
could "use" a pointer
NodeAddr< UseNode * > Use
Definition RDFGraph.h:385
Context & getContext() const
Definition BasicBlock.h:99
iterator end() const
Definition BasicBlock.h:89
friend class Instruction
Iterator for Instructions in a `BasicBlock.
Definition BasicBlock.h:73
LLVM_ABI iterator begin() const
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp: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:377
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:371
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:508
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:520
@ NONE
Do not track a dependence between source and target.
Definition Attributor.h:521
@ REQUIRED
The target cannot be valid if the source is not.
Definition Attributor.h:519
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:876
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)
static Access getTombstoneKey()
DenseMapInfo< Instruction * > Base
static bool isEqual(const Access &LHS, const Access &RHS)
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
Definition Alignment.h:77
std::function< void( const ArgumentReplacementInfo &, Function &, Function::arg_iterator)> CalleeRepairCBTy
Callee repair callback type.
const Argument & getReplacedArg() const
std::function< void(const ArgumentReplacementInfo &, AbstractCallSite, SmallVectorImpl< Value * > &)> ACSRepairCBTy
Abstract call site (ACS) repair callback type.
The fixpoint analysis framework that orchestrates the attribute deduction.
std::function< std::optional< Value * >( const IRPosition &, const AbstractAttribute *, bool &)> SimplifictionCallbackTy
Register CB as a simplification callback.
Specialization of the integer state for a bit-wise encoding.
BitIntegerState & addKnownBits(base_t Bits)
Add the bits in BitsEncoding to the "known bits".
Simple wrapper for a single bit (boolean) state.
static constexpr DenormalFPEnv getDefault()
static unsigned getHashValue(const Access &A)
static bool isEqual(const Access &LHS, const Access &RHS)
static bool isEqual(const AA::RangeTy &A, const AA::RangeTy B)
static unsigned getHashValue(const AA::RangeTy &Range)
DenseMapInfo< std::pair< const Instruction *, const ToTy * > > PairDMI
static ReachabilityQueryInfo< ToTy > * getTombstoneKey()
static bool isEqual(const ReachabilityQueryInfo< ToTy > *LHS, const ReachabilityQueryInfo< ToTy > *RHS)
DenseMapInfo< const AA::InstExclusionSetTy * > InstSetDMI
static unsigned getHashValue(const ReachabilityQueryInfo< ToTy > *RQI)
An information struct used to provide DenseMap with the various necessary components for a given valu...
State for dereferenceable attribute.
IncIntegerState DerefBytesState
State representing for dereferenceable bytes.
ChangeStatus manifest(Attributor &A) override
See AbstractAttribute::manifest(...).
Helper to describe and deal with positions in the LLVM-IR.
Definition Attributor.h:605
Function * getAssociatedFunction() const
Return the associated function, if any.
Definition Attributor.h:736
static const IRPosition callsite_returned(const CallBase &CB)
Create a position describing the returned value of CB.
Definition Attributor.h:673
static const IRPosition returned(const Function &F, const CallBaseContext *CBContext=nullptr)
Create a position describing the returned value of F.
Definition Attributor.h:655
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:629
CallBase CallBaseContext
Definition Attributor.h:608
int getCalleeArgNo() const
Return the callee argument number of the associated value if it is an argument or call site argument,...
Definition Attributor.h:823
static const IRPosition inst(const Instruction &I, const CallBaseContext *CBContext=nullptr)
Create a position describing the instruction I.
Definition Attributor.h:641
static const IRPosition callsite_argument(const CallBase &CB, unsigned ArgNo)
Create a position describing the argument of CB at position ArgNo.
Definition Attributor.h:678
@ IRP_ARGUMENT
An attribute for a function argument.
Definition Attributor.h:619
@ IRP_RETURNED
An attribute for the function return value.
Definition Attributor.h:615
@ IRP_CALL_SITE
An attribute for a call site (function scope).
Definition Attributor.h:618
@ IRP_CALL_SITE_RETURNED
An attribute for a call site return value.
Definition Attributor.h:616
@ IRP_FUNCTION
An attribute for a function (scope).
Definition Attributor.h:617
@ IRP_CALL_SITE_ARGUMENT
An attribute for a call site argument.
Definition Attributor.h:620
@ IRP_INVALID
An invalid position.
Definition Attributor.h:612
Instruction * getCtxI() const
Return the context instruction, if any.
Definition Attributor.h:789
static const IRPosition argument(const Argument &Arg, const CallBaseContext *CBContext=nullptr)
Create a position describing the argument Arg.
Definition Attributor.h:662
Type * getAssociatedType() const
Return the type this abstract attribute is associated with.
Definition Attributor.h:812
static const IRPosition function(const Function &F, const CallBaseContext *CBContext=nullptr)
Create a position describing the function scope of F.
Definition Attributor.h:648
const CallBaseContext * getCallBaseContext() const
Get the call base context from the position.
Definition Attributor.h:951
Value & getAssociatedValue() const
Return the value this abstract attribute is associated with.
Definition Attributor.h:803
Value & getAnchorValue() const
Return the value this abstract attribute is anchored with.
Definition Attributor.h:722
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:832
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:701
Kind getPositionKind() const
Return the associated position kind.
Definition Attributor.h:901
bool isArgumentPosition() const
Return true if the position is an argument or call site argument.
Definition Attributor.h:933
static const IRPosition callsite_function(const CallBase &CB)
Create a position describing the function scope of CB.
Definition Attributor.h:668
Function * getAnchorScope() const
Return the Function surrounding the anchor value.
Definition Attributor.h:777
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.