LLVM 20.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"
40#include "llvm/IR/Argument.h"
41#include "llvm/IR/Assumptions.h"
42#include "llvm/IR/Attributes.h"
43#include "llvm/IR/BasicBlock.h"
44#include "llvm/IR/Constant.h"
45#include "llvm/IR/Constants.h"
46#include "llvm/IR/DataLayout.h"
48#include "llvm/IR/GlobalValue.h"
49#include "llvm/IR/IRBuilder.h"
50#include "llvm/IR/InlineAsm.h"
51#include "llvm/IR/InstrTypes.h"
52#include "llvm/IR/Instruction.h"
55#include "llvm/IR/IntrinsicsAMDGPU.h"
56#include "llvm/IR/IntrinsicsNVPTX.h"
57#include "llvm/IR/LLVMContext.h"
58#include "llvm/IR/MDBuilder.h"
59#include "llvm/IR/NoFolder.h"
60#include "llvm/IR/Value.h"
61#include "llvm/IR/ValueHandle.h"
74#include <cassert>
75#include <numeric>
76#include <optional>
77#include <string>
78
79using namespace llvm;
80
81#define DEBUG_TYPE "attributor"
82
84 "attributor-manifest-internal", cl::Hidden,
85 cl::desc("Manifest Attributor internal string attributes."),
86 cl::init(false));
87
88static cl::opt<int> MaxHeapToStackSize("max-heap-to-stack-size", cl::init(128),
90
91template <>
93
95
97 "attributor-max-potential-values", cl::Hidden,
98 cl::desc("Maximum number of potential values to be "
99 "tracked for each position."),
101 cl::init(7));
102
104 "attributor-max-potential-values-iterations", cl::Hidden,
105 cl::desc(
106 "Maximum number of iterations we keep dismantling potential values."),
107 cl::init(64));
108
109STATISTIC(NumAAs, "Number of abstract attributes created");
110
111// Some helper macros to deal with statistics tracking.
112//
113// Usage:
114// For simple IR attribute tracking overload trackStatistics in the abstract
115// attribute and choose the right STATS_DECLTRACK_********* macro,
116// e.g.,:
117// void trackStatistics() const override {
118// STATS_DECLTRACK_ARG_ATTR(returned)
119// }
120// If there is a single "increment" side one can use the macro
121// STATS_DECLTRACK with a custom message. If there are multiple increment
122// sides, STATS_DECL and STATS_TRACK can also be used separately.
123//
124#define BUILD_STAT_MSG_IR_ATTR(TYPE, NAME) \
125 ("Number of " #TYPE " marked '" #NAME "'")
126#define BUILD_STAT_NAME(NAME, TYPE) NumIR##TYPE##_##NAME
127#define STATS_DECL_(NAME, MSG) STATISTIC(NAME, MSG);
128#define STATS_DECL(NAME, TYPE, MSG) \
129 STATS_DECL_(BUILD_STAT_NAME(NAME, TYPE), MSG);
130#define STATS_TRACK(NAME, TYPE) ++(BUILD_STAT_NAME(NAME, TYPE));
131#define STATS_DECLTRACK(NAME, TYPE, MSG) \
132 { \
133 STATS_DECL(NAME, TYPE, MSG) \
134 STATS_TRACK(NAME, TYPE) \
135 }
136#define STATS_DECLTRACK_ARG_ATTR(NAME) \
137 STATS_DECLTRACK(NAME, Arguments, BUILD_STAT_MSG_IR_ATTR(arguments, NAME))
138#define STATS_DECLTRACK_CSARG_ATTR(NAME) \
139 STATS_DECLTRACK(NAME, CSArguments, \
140 BUILD_STAT_MSG_IR_ATTR(call site arguments, NAME))
141#define STATS_DECLTRACK_FN_ATTR(NAME) \
142 STATS_DECLTRACK(NAME, Function, BUILD_STAT_MSG_IR_ATTR(functions, NAME))
143#define STATS_DECLTRACK_CS_ATTR(NAME) \
144 STATS_DECLTRACK(NAME, CS, BUILD_STAT_MSG_IR_ATTR(call site, NAME))
145#define STATS_DECLTRACK_FNRET_ATTR(NAME) \
146 STATS_DECLTRACK(NAME, FunctionReturn, \
147 BUILD_STAT_MSG_IR_ATTR(function returns, NAME))
148#define STATS_DECLTRACK_CSRET_ATTR(NAME) \
149 STATS_DECLTRACK(NAME, CSReturn, \
150 BUILD_STAT_MSG_IR_ATTR(call site returns, NAME))
151#define STATS_DECLTRACK_FLOATING_ATTR(NAME) \
152 STATS_DECLTRACK(NAME, Floating, \
153 ("Number of floating values known to be '" #NAME "'"))
154
155// Specialization of the operator<< for abstract attributes subclasses. This
156// disambiguates situations where multiple operators are applicable.
157namespace llvm {
158#define PIPE_OPERATOR(CLASS) \
159 raw_ostream &operator<<(raw_ostream &OS, const CLASS &AA) { \
160 return OS << static_cast<const AbstractAttribute &>(AA); \
161 }
162
200
201#undef PIPE_OPERATOR
202
203template <>
205 const DerefState &R) {
206 ChangeStatus CS0 =
207 clampStateAndIndicateChange(S.DerefBytesState, R.DerefBytesState);
208 ChangeStatus CS1 = clampStateAndIndicateChange(S.GlobalState, R.GlobalState);
209 return CS0 | CS1;
210}
211
212} // namespace llvm
213
214static bool mayBeInCycle(const CycleInfo *CI, const Instruction *I,
215 bool HeaderOnly, Cycle **CPtr = nullptr) {
216 if (!CI)
217 return true;
218 auto *BB = I->getParent();
219 auto *C = CI->getCycle(BB);
220 if (!C)
221 return false;
222 if (CPtr)
223 *CPtr = C;
224 return !HeaderOnly || BB == C->getHeader();
225}
226
227/// Checks if a type could have padding bytes.
228static bool isDenselyPacked(Type *Ty, const DataLayout &DL) {
229 // There is no size information, so be conservative.
230 if (!Ty->isSized())
231 return false;
232
233 // If the alloc size is not equal to the storage size, then there are padding
234 // bytes. For x86_fp80 on x86-64, size: 80 alloc size: 128.
235 if (DL.getTypeSizeInBits(Ty) != DL.getTypeAllocSizeInBits(Ty))
236 return false;
237
238 // FIXME: This isn't the right way to check for padding in vectors with
239 // non-byte-size elements.
240 if (VectorType *SeqTy = dyn_cast<VectorType>(Ty))
241 return isDenselyPacked(SeqTy->getElementType(), DL);
242
243 // For array types, check for padding within members.
244 if (ArrayType *SeqTy = dyn_cast<ArrayType>(Ty))
245 return isDenselyPacked(SeqTy->getElementType(), DL);
246
247 if (!isa<StructType>(Ty))
248 return true;
249
250 // Check for padding within and between elements of a struct.
251 StructType *StructTy = cast<StructType>(Ty);
252 const StructLayout *Layout = DL.getStructLayout(StructTy);
253 uint64_t StartPos = 0;
254 for (unsigned I = 0, E = StructTy->getNumElements(); I < E; ++I) {
255 Type *ElTy = StructTy->getElementType(I);
256 if (!isDenselyPacked(ElTy, DL))
257 return false;
258 if (StartPos != Layout->getElementOffsetInBits(I))
259 return false;
260 StartPos += DL.getTypeAllocSizeInBits(ElTy);
261 }
262
263 return true;
264}
265
266/// Get pointer operand of memory accessing instruction. If \p I is
267/// not a memory accessing instruction, return nullptr. If \p AllowVolatile,
268/// is set to false and the instruction is volatile, return nullptr.
270 bool AllowVolatile) {
271 if (!AllowVolatile && I->isVolatile())
272 return nullptr;
273
274 if (auto *LI = dyn_cast<LoadInst>(I)) {
275 return LI->getPointerOperand();
276 }
277
278 if (auto *SI = dyn_cast<StoreInst>(I)) {
279 return SI->getPointerOperand();
280 }
281
282 if (auto *CXI = dyn_cast<AtomicCmpXchgInst>(I)) {
283 return CXI->getPointerOperand();
284 }
285
286 if (auto *RMWI = dyn_cast<AtomicRMWInst>(I)) {
287 return RMWI->getPointerOperand();
288 }
289
290 return nullptr;
291}
292
293/// Helper function to create a pointer based on \p Ptr, and advanced by \p
294/// Offset bytes.
296 IRBuilder<NoFolder> &IRB) {
297 LLVM_DEBUG(dbgs() << "Construct pointer: " << *Ptr << " + " << Offset
298 << "-bytes\n");
299
300 if (Offset)
301 Ptr = IRB.CreatePtrAdd(Ptr, IRB.getInt64(Offset),
302 Ptr->getName() + ".b" + Twine(Offset));
303 return Ptr;
304}
305
306static const Value *
308 const Value *Val, const DataLayout &DL, APInt &Offset,
309 bool GetMinOffset, bool AllowNonInbounds,
310 bool UseAssumed = false) {
311
312 auto AttributorAnalysis = [&](Value &V, APInt &ROffset) -> bool {
313 const IRPosition &Pos = IRPosition::value(V);
314 // Only track dependence if we are going to use the assumed info.
315 const AAValueConstantRange *ValueConstantRangeAA =
316 A.getAAFor<AAValueConstantRange>(QueryingAA, Pos,
317 UseAssumed ? DepClassTy::OPTIONAL
318 : DepClassTy::NONE);
319 if (!ValueConstantRangeAA)
320 return false;
321 ConstantRange Range = UseAssumed ? ValueConstantRangeAA->getAssumed()
322 : ValueConstantRangeAA->getKnown();
323 if (Range.isFullSet())
324 return false;
325
326 // We can only use the lower part of the range because the upper part can
327 // be higher than what the value can really be.
328 if (GetMinOffset)
329 ROffset = Range.getSignedMin();
330 else
331 ROffset = Range.getSignedMax();
332 return true;
333 };
334
335 return Val->stripAndAccumulateConstantOffsets(DL, Offset, AllowNonInbounds,
336 /* AllowInvariant */ true,
337 AttributorAnalysis);
338}
339
340static const Value *
342 const Value *Ptr, int64_t &BytesOffset,
343 const DataLayout &DL, bool AllowNonInbounds = false) {
344 APInt OffsetAPInt(DL.getIndexTypeSizeInBits(Ptr->getType()), 0);
345 const Value *Base =
346 stripAndAccumulateOffsets(A, QueryingAA, Ptr, DL, OffsetAPInt,
347 /* GetMinOffset */ true, AllowNonInbounds);
348
349 BytesOffset = OffsetAPInt.getSExtValue();
350 return Base;
351}
352
353/// Clamp the information known for all returned values of a function
354/// (identified by \p QueryingAA) into \p S.
355template <typename AAType, typename StateType = typename AAType::StateType,
356 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind,
357 bool RecurseForSelectAndPHI = true>
359 Attributor &A, const AAType &QueryingAA, StateType &S,
360 const IRPosition::CallBaseContext *CBContext = nullptr) {
361 LLVM_DEBUG(dbgs() << "[Attributor] Clamp return value states for "
362 << QueryingAA << " into " << S << "\n");
363
364 assert((QueryingAA.getIRPosition().getPositionKind() ==
366 QueryingAA.getIRPosition().getPositionKind() ==
368 "Can only clamp returned value states for a function returned or call "
369 "site returned position!");
370
371 // Use an optional state as there might not be any return values and we want
372 // to join (IntegerState::operator&) the state of all there are.
373 std::optional<StateType> T;
374
375 // Callback for each possibly returned value.
376 auto CheckReturnValue = [&](Value &RV) -> bool {
377 const IRPosition &RVPos = IRPosition::value(RV, CBContext);
378 // If possible, use the hasAssumedIRAttr interface.
379 if (Attribute::isEnumAttrKind(IRAttributeKind)) {
380 bool IsKnown;
381 return AA::hasAssumedIRAttr<IRAttributeKind>(
382 A, &QueryingAA, RVPos, DepClassTy::REQUIRED, IsKnown);
383 }
384
385 const AAType *AA =
386 A.getAAFor<AAType>(QueryingAA, RVPos, DepClassTy::REQUIRED);
387 if (!AA)
388 return false;
389 LLVM_DEBUG(dbgs() << "[Attributor] RV: " << RV
390 << " AA: " << AA->getAsStr(&A) << " @ " << RVPos << "\n");
391 const StateType &AAS = AA->getState();
392 if (!T)
393 T = StateType::getBestState(AAS);
394 *T &= AAS;
395 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS << " RV State: " << T
396 << "\n");
397 return T->isValidState();
398 };
399
400 if (!A.checkForAllReturnedValues(CheckReturnValue, QueryingAA,
401 AA::ValueScope::Intraprocedural,
402 RecurseForSelectAndPHI))
403 S.indicatePessimisticFixpoint();
404 else if (T)
405 S ^= *T;
406}
407
408namespace {
409/// Helper class for generic deduction: return value -> returned position.
410template <typename AAType, typename BaseType,
411 typename StateType = typename BaseType::StateType,
412 bool PropagateCallBaseContext = false,
413 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind,
414 bool RecurseForSelectAndPHI = true>
415struct AAReturnedFromReturnedValues : public BaseType {
416 AAReturnedFromReturnedValues(const IRPosition &IRP, Attributor &A)
417 : BaseType(IRP, A) {}
418
419 /// See AbstractAttribute::updateImpl(...).
420 ChangeStatus updateImpl(Attributor &A) override {
421 StateType S(StateType::getBestState(this->getState()));
422 clampReturnedValueStates<AAType, StateType, IRAttributeKind,
423 RecurseForSelectAndPHI>(
424 A, *this, S,
425 PropagateCallBaseContext ? this->getCallBaseContext() : nullptr);
426 // TODO: If we know we visited all returned values, thus no are assumed
427 // dead, we can take the known information from the state T.
428 return clampStateAndIndicateChange<StateType>(this->getState(), S);
429 }
430};
431
432/// Clamp the information known at all call sites for a given argument
433/// (identified by \p QueryingAA) into \p S.
434template <typename AAType, typename StateType = typename AAType::StateType,
435 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind>
436static void clampCallSiteArgumentStates(Attributor &A, const AAType &QueryingAA,
437 StateType &S) {
438 LLVM_DEBUG(dbgs() << "[Attributor] Clamp call site argument states for "
439 << QueryingAA << " into " << S << "\n");
440
441 assert(QueryingAA.getIRPosition().getPositionKind() ==
443 "Can only clamp call site argument states for an argument position!");
444
445 // Use an optional state as there might not be any return values and we want
446 // to join (IntegerState::operator&) the state of all there are.
447 std::optional<StateType> T;
448
449 // The argument number which is also the call site argument number.
450 unsigned ArgNo = QueryingAA.getIRPosition().getCallSiteArgNo();
451
452 auto CallSiteCheck = [&](AbstractCallSite ACS) {
453 const IRPosition &ACSArgPos = IRPosition::callsite_argument(ACS, ArgNo);
454 // Check if a coresponding argument was found or if it is on not associated
455 // (which can happen for callback calls).
456 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
457 return false;
458
459 // If possible, use the hasAssumedIRAttr interface.
460 if (Attribute::isEnumAttrKind(IRAttributeKind)) {
461 bool IsKnown;
462 return AA::hasAssumedIRAttr<IRAttributeKind>(
463 A, &QueryingAA, ACSArgPos, DepClassTy::REQUIRED, IsKnown);
464 }
465
466 const AAType *AA =
467 A.getAAFor<AAType>(QueryingAA, ACSArgPos, DepClassTy::REQUIRED);
468 if (!AA)
469 return false;
470 LLVM_DEBUG(dbgs() << "[Attributor] ACS: " << *ACS.getInstruction()
471 << " AA: " << AA->getAsStr(&A) << " @" << ACSArgPos
472 << "\n");
473 const StateType &AAS = AA->getState();
474 if (!T)
475 T = StateType::getBestState(AAS);
476 *T &= AAS;
477 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS << " CSA State: " << T
478 << "\n");
479 return T->isValidState();
480 };
481
482 bool UsedAssumedInformation = false;
483 if (!A.checkForAllCallSites(CallSiteCheck, QueryingAA, true,
484 UsedAssumedInformation))
485 S.indicatePessimisticFixpoint();
486 else if (T)
487 S ^= *T;
488}
489
490/// This function is the bridge between argument position and the call base
491/// context.
492template <typename AAType, typename BaseType,
493 typename StateType = typename AAType::StateType,
494 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind>
495bool getArgumentStateFromCallBaseContext(Attributor &A,
496 BaseType &QueryingAttribute,
497 IRPosition &Pos, StateType &State) {
499 "Expected an 'argument' position !");
500 const CallBase *CBContext = Pos.getCallBaseContext();
501 if (!CBContext)
502 return false;
503
504 int ArgNo = Pos.getCallSiteArgNo();
505 assert(ArgNo >= 0 && "Invalid Arg No!");
506 const IRPosition CBArgPos = IRPosition::callsite_argument(*CBContext, ArgNo);
507
508 // If possible, use the hasAssumedIRAttr interface.
509 if (Attribute::isEnumAttrKind(IRAttributeKind)) {
510 bool IsKnown;
511 return AA::hasAssumedIRAttr<IRAttributeKind>(
512 A, &QueryingAttribute, CBArgPos, DepClassTy::REQUIRED, IsKnown);
513 }
514
515 const auto *AA =
516 A.getAAFor<AAType>(QueryingAttribute, CBArgPos, DepClassTy::REQUIRED);
517 if (!AA)
518 return false;
519 const StateType &CBArgumentState =
520 static_cast<const StateType &>(AA->getState());
521
522 LLVM_DEBUG(dbgs() << "[Attributor] Briding Call site context to argument"
523 << "Position:" << Pos << "CB Arg state:" << CBArgumentState
524 << "\n");
525
526 // NOTE: If we want to do call site grouping it should happen here.
527 State ^= CBArgumentState;
528 return true;
529}
530
531/// Helper class for generic deduction: call site argument -> argument position.
532template <typename AAType, typename BaseType,
533 typename StateType = typename AAType::StateType,
534 bool BridgeCallBaseContext = false,
535 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind>
536struct AAArgumentFromCallSiteArguments : public BaseType {
537 AAArgumentFromCallSiteArguments(const IRPosition &IRP, Attributor &A)
538 : BaseType(IRP, A) {}
539
540 /// See AbstractAttribute::updateImpl(...).
541 ChangeStatus updateImpl(Attributor &A) override {
542 StateType S = StateType::getBestState(this->getState());
543
544 if (BridgeCallBaseContext) {
545 bool Success =
546 getArgumentStateFromCallBaseContext<AAType, BaseType, StateType,
547 IRAttributeKind>(
548 A, *this, this->getIRPosition(), S);
549 if (Success)
550 return clampStateAndIndicateChange<StateType>(this->getState(), S);
551 }
552 clampCallSiteArgumentStates<AAType, StateType, IRAttributeKind>(A, *this,
553 S);
554
555 // TODO: If we know we visited all incoming values, thus no are assumed
556 // dead, we can take the known information from the state T.
557 return clampStateAndIndicateChange<StateType>(this->getState(), S);
558 }
559};
560
561/// Helper class for generic replication: function returned -> cs returned.
562template <typename AAType, typename BaseType,
563 typename StateType = typename BaseType::StateType,
564 bool IntroduceCallBaseContext = false,
565 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind>
566struct AACalleeToCallSite : public BaseType {
567 AACalleeToCallSite(const IRPosition &IRP, Attributor &A) : BaseType(IRP, A) {}
568
569 /// See AbstractAttribute::updateImpl(...).
570 ChangeStatus updateImpl(Attributor &A) override {
571 auto IRPKind = this->getIRPosition().getPositionKind();
573 IRPKind == IRPosition::IRP_CALL_SITE) &&
574 "Can only wrap function returned positions for call site "
575 "returned positions!");
576 auto &S = this->getState();
577
578 CallBase &CB = cast<CallBase>(this->getAnchorValue());
579 if (IntroduceCallBaseContext)
580 LLVM_DEBUG(dbgs() << "[Attributor] Introducing call base context:" << CB
581 << "\n");
582
583 ChangeStatus Changed = ChangeStatus::UNCHANGED;
584 auto CalleePred = [&](ArrayRef<const Function *> Callees) {
585 for (const Function *Callee : Callees) {
586 IRPosition FnPos =
588 ? IRPosition::returned(*Callee,
589 IntroduceCallBaseContext ? &CB : nullptr)
591 *Callee, IntroduceCallBaseContext ? &CB : nullptr);
592 // If possible, use the hasAssumedIRAttr interface.
593 if (Attribute::isEnumAttrKind(IRAttributeKind)) {
594 bool IsKnown;
595 if (!AA::hasAssumedIRAttr<IRAttributeKind>(
596 A, this, FnPos, DepClassTy::REQUIRED, IsKnown))
597 return false;
598 continue;
599 }
600
601 const AAType *AA =
602 A.getAAFor<AAType>(*this, FnPos, DepClassTy::REQUIRED);
603 if (!AA)
604 return false;
605 Changed |= clampStateAndIndicateChange(S, AA->getState());
606 if (S.isAtFixpoint())
607 return S.isValidState();
608 }
609 return true;
610 };
611 if (!A.checkForAllCallees(CalleePred, *this, CB))
612 return S.indicatePessimisticFixpoint();
613 return Changed;
614 }
615};
616
617/// Helper function to accumulate uses.
618template <class AAType, typename StateType = typename AAType::StateType>
619static void followUsesInContext(AAType &AA, Attributor &A,
621 const Instruction *CtxI,
623 StateType &State) {
624 auto EIt = Explorer.begin(CtxI), EEnd = Explorer.end(CtxI);
625 for (unsigned u = 0; u < Uses.size(); ++u) {
626 const Use *U = Uses[u];
627 if (const Instruction *UserI = dyn_cast<Instruction>(U->getUser())) {
628 bool Found = Explorer.findInContextOf(UserI, EIt, EEnd);
629 if (Found && AA.followUseInMBEC(A, U, UserI, State))
630 for (const Use &Us : UserI->uses())
631 Uses.insert(&Us);
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) {
649 A.getInfoCache().getMustBeExecutedContextExplorer();
650 if (!Explorer)
651 return;
652
653 // Container for (transitive) uses of the associated value.
655 for (const Use &U : AA.getIRPosition().getAssociatedValue().uses())
656 Uses.insert(&U);
657
658 followUsesInContext<AAType>(AA, A, *Explorer, &CtxI, Uses, S);
659
660 if (S.isAtFixpoint())
661 return;
662
664 auto Pred = [&](const Instruction *I) {
665 if (const BranchInst *Br = dyn_cast<BranchInst>(I))
666 if (Br->isConditional())
667 BrInsts.push_back(Br);
668 return true;
669 };
670
671 // Here, accumulate conditional branch instructions in the context. We
672 // explore the child paths and collect the known states. The disjunction of
673 // those states can be merged to its own state. Let ParentState_i be a state
674 // to indicate the known information for an i-th branch instruction in the
675 // context. ChildStates are created for its successors respectively.
676 //
677 // ParentS_1 = ChildS_{1, 1} /\ ChildS_{1, 2} /\ ... /\ ChildS_{1, n_1}
678 // ParentS_2 = ChildS_{2, 1} /\ ChildS_{2, 2} /\ ... /\ ChildS_{2, n_2}
679 // ...
680 // ParentS_m = ChildS_{m, 1} /\ ChildS_{m, 2} /\ ... /\ ChildS_{m, n_m}
681 //
682 // Known State |= ParentS_1 \/ ParentS_2 \/... \/ ParentS_m
683 //
684 // FIXME: Currently, recursive branches are not handled. For example, we
685 // can't deduce that ptr must be dereferenced in below function.
686 //
687 // void f(int a, int c, int *ptr) {
688 // if(a)
689 // if (b) {
690 // *ptr = 0;
691 // } else {
692 // *ptr = 1;
693 // }
694 // else {
695 // if (b) {
696 // *ptr = 0;
697 // } else {
698 // *ptr = 1;
699 // }
700 // }
701 // }
702
703 Explorer->checkForAllContext(&CtxI, Pred);
704 for (const BranchInst *Br : BrInsts) {
705 StateType ParentState;
706
707 // The known state of the parent state is a conjunction of children's
708 // known states so it is initialized with a best state.
709 ParentState.indicateOptimisticFixpoint();
710
711 for (const BasicBlock *BB : Br->successors()) {
712 StateType ChildState;
713
714 size_t BeforeSize = Uses.size();
715 followUsesInContext(AA, A, *Explorer, &BB->front(), Uses, ChildState);
716
717 // Erase uses which only appear in the child.
718 for (auto It = Uses.begin() + BeforeSize; It != Uses.end();)
719 It = Uses.erase(It);
720
721 ParentState &= ChildState;
722 }
723
724 // Use only known state.
725 S += ParentState;
726 }
727}
728} // namespace
729
730/// ------------------------ PointerInfo ---------------------------------------
731
732namespace llvm {
733namespace AA {
734namespace PointerInfo {
735
736struct State;
737
738} // namespace PointerInfo
739} // namespace AA
740
741/// Helper for AA::PointerInfo::Access DenseMap/Set usage.
742template <>
745 static inline Access getEmptyKey();
746 static inline Access getTombstoneKey();
747 static unsigned getHashValue(const Access &A);
748 static bool isEqual(const Access &LHS, const Access &RHS);
749};
750
751/// Helper that allows RangeTy as a key in a DenseMap.
752template <> struct DenseMapInfo<AA::RangeTy> {
753 static inline AA::RangeTy getEmptyKey() {
754 auto EmptyKey = DenseMapInfo<int64_t>::getEmptyKey();
755 return AA::RangeTy{EmptyKey, EmptyKey};
756 }
757
758 static inline AA::RangeTy getTombstoneKey() {
759 auto TombstoneKey = DenseMapInfo<int64_t>::getTombstoneKey();
760 return AA::RangeTy{TombstoneKey, TombstoneKey};
761 }
762
763 static unsigned getHashValue(const AA::RangeTy &Range) {
767 }
768
769 static bool isEqual(const AA::RangeTy &A, const AA::RangeTy B) {
770 return A == B;
771 }
772};
773
774/// Helper for AA::PointerInfo::Access DenseMap/Set usage ignoring everythign
775/// but the instruction
776struct AccessAsInstructionInfo : DenseMapInfo<Instruction *> {
779 static inline Access getEmptyKey();
780 static inline Access getTombstoneKey();
781 static unsigned getHashValue(const Access &A);
782 static bool isEqual(const Access &LHS, const Access &RHS);
783};
784
785} // namespace llvm
786
787/// A type to track pointer/struct usage and accesses for AAPointerInfo.
789 /// Return the best possible representable state.
790 static State getBestState(const State &SIS) { return State(); }
791
792 /// Return the worst possible representable state.
793 static State getWorstState(const State &SIS) {
794 State R;
795 R.indicatePessimisticFixpoint();
796 return R;
797 }
798
799 State() = default;
800 State(State &&SIS) = default;
801
802 const State &getAssumed() const { return *this; }
803
804 /// See AbstractState::isValidState().
805 bool isValidState() const override { return BS.isValidState(); }
806
807 /// See AbstractState::isAtFixpoint().
808 bool isAtFixpoint() const override { return BS.isAtFixpoint(); }
809
810 /// See AbstractState::indicateOptimisticFixpoint().
814 }
815
816 /// See AbstractState::indicatePessimisticFixpoint().
820 }
821
822 State &operator=(const State &R) {
823 if (this == &R)
824 return *this;
825 BS = R.BS;
826 AccessList = R.AccessList;
827 OffsetBins = R.OffsetBins;
828 RemoteIMap = R.RemoteIMap;
829 return *this;
830 }
831
833 if (this == &R)
834 return *this;
835 std::swap(BS, R.BS);
836 std::swap(AccessList, R.AccessList);
837 std::swap(OffsetBins, R.OffsetBins);
838 std::swap(RemoteIMap, R.RemoteIMap);
839 return *this;
840 }
841
842 /// Add a new Access to the state at offset \p Offset and with size \p Size.
843 /// The access is associated with \p I, writes \p Content (if anything), and
844 /// is of kind \p Kind. If an Access already exists for the same \p I and same
845 /// \p RemoteI, the two are combined, potentially losing information about
846 /// offset and size. The resulting access must now be moved from its original
847 /// OffsetBin to the bin for its new offset.
848 ///
849 /// \Returns CHANGED, if the state changed, UNCHANGED otherwise.
851 Instruction &I, std::optional<Value *> Content,
853 Instruction *RemoteI = nullptr);
854
857 int64_t numOffsetBins() const { return OffsetBins.size(); }
858
859 const AAPointerInfo::Access &getAccess(unsigned Index) const {
860 return AccessList[Index];
861 }
862
863protected:
864 // Every memory instruction results in an Access object. We maintain a list of
865 // all Access objects that we own, along with the following maps:
866 //
867 // - OffsetBins: RangeTy -> { Access }
868 // - RemoteIMap: RemoteI x LocalI -> Access
869 //
870 // A RemoteI is any instruction that accesses memory. RemoteI is different
871 // from LocalI if and only if LocalI is a call; then RemoteI is some
872 // instruction in the callgraph starting from LocalI. Multiple paths in the
873 // callgraph from LocalI to RemoteI may produce multiple accesses, but these
874 // are all combined into a single Access object. This may result in loss of
875 // information in RangeTy in the Access object.
879
880 /// See AAPointerInfo::forallInterferingAccesses.
883 function_ref<bool(const AAPointerInfo::Access &, bool)> CB) const {
884 if (!isValidState())
885 return false;
886
887 for (const auto &It : OffsetBins) {
888 AA::RangeTy ItRange = It.getFirst();
889 if (!Range.mayOverlap(ItRange))
890 continue;
891 bool IsExact = Range == ItRange && !Range.offsetOrSizeAreUnknown();
892 for (auto Index : It.getSecond()) {
893 auto &Access = AccessList[Index];
894 if (!CB(Access, IsExact))
895 return false;
896 }
897 }
898 return true;
899 }
900
901 /// See AAPointerInfo::forallInterferingAccesses.
903 Instruction &I,
904 function_ref<bool(const AAPointerInfo::Access &, bool)> CB,
905 AA::RangeTy &Range) const {
906 if (!isValidState())
907 return false;
908
909 auto LocalList = RemoteIMap.find(&I);
910 if (LocalList == RemoteIMap.end()) {
911 return true;
912 }
913
914 for (unsigned Index : LocalList->getSecond()) {
915 for (auto &R : AccessList[Index]) {
916 Range &= R;
917 if (Range.offsetAndSizeAreUnknown())
918 break;
919 }
920 }
922 }
923
924private:
925 /// State to track fixpoint and validity.
926 BooleanState BS;
927};
928
931 std::optional<Value *> Content, AAPointerInfo::AccessKind Kind, Type *Ty,
932 Instruction *RemoteI) {
933 RemoteI = RemoteI ? RemoteI : &I;
934
935 // Check if we have an access for this instruction, if not, simply add it.
936 auto &LocalList = RemoteIMap[RemoteI];
937 bool AccExists = false;
938 unsigned AccIndex = AccessList.size();
939 for (auto Index : LocalList) {
940 auto &A = AccessList[Index];
941 if (A.getLocalInst() == &I) {
942 AccExists = true;
943 AccIndex = Index;
944 break;
945 }
946 }
947
948 auto AddToBins = [&](const AAPointerInfo::RangeList &ToAdd) {
949 LLVM_DEBUG(if (ToAdd.size()) dbgs()
950 << "[AAPointerInfo] Inserting access in new offset bins\n";);
951
952 for (auto Key : ToAdd) {
953 LLVM_DEBUG(dbgs() << " key " << Key << "\n");
954 OffsetBins[Key].insert(AccIndex);
955 }
956 };
957
958 if (!AccExists) {
959 AccessList.emplace_back(&I, RemoteI, Ranges, Content, Kind, Ty);
960 assert((AccessList.size() == AccIndex + 1) &&
961 "New Access should have been at AccIndex");
962 LocalList.push_back(AccIndex);
963 AddToBins(AccessList[AccIndex].getRanges());
965 }
966
967 // Combine the new Access with the existing Access, and then update the
968 // mapping in the offset bins.
969 AAPointerInfo::Access Acc(&I, RemoteI, Ranges, Content, Kind, Ty);
970 auto &Current = AccessList[AccIndex];
971 auto Before = Current;
972 Current &= Acc;
973 if (Current == Before)
975
976 auto &ExistingRanges = Before.getRanges();
977 auto &NewRanges = Current.getRanges();
978
979 // Ranges that are in the old access but not the new access need to be removed
980 // from the offset bins.
982 AAPointerInfo::RangeList::set_difference(ExistingRanges, NewRanges, ToRemove);
983 LLVM_DEBUG(if (ToRemove.size()) dbgs()
984 << "[AAPointerInfo] Removing access from old offset bins\n";);
985
986 for (auto Key : ToRemove) {
987 LLVM_DEBUG(dbgs() << " key " << Key << "\n");
988 assert(OffsetBins.count(Key) && "Existing Access must be in some bin.");
989 auto &Bin = OffsetBins[Key];
990 assert(Bin.count(AccIndex) &&
991 "Expected bin to actually contain the Access.");
992 Bin.erase(AccIndex);
993 }
994
995 // Ranges that are in the new access but not the old access need to be added
996 // to the offset bins.
998 AAPointerInfo::RangeList::set_difference(NewRanges, ExistingRanges, ToAdd);
999 AddToBins(ToAdd);
1000 return ChangeStatus::CHANGED;
1001}
1002
1003namespace {
1004
1005/// A helper containing a list of offsets computed for a Use. Ideally this
1006/// list should be strictly ascending, but we ensure that only when we
1007/// actually translate the list of offsets to a RangeList.
1008struct OffsetInfo {
1009 using VecTy = SmallVector<int64_t>;
1010 using const_iterator = VecTy::const_iterator;
1011 VecTy Offsets;
1012
1013 const_iterator begin() const { return Offsets.begin(); }
1014 const_iterator end() const { return Offsets.end(); }
1015
1016 bool operator==(const OffsetInfo &RHS) const {
1017 return Offsets == RHS.Offsets;
1018 }
1019
1020 bool operator!=(const OffsetInfo &RHS) const { return !(*this == RHS); }
1021
1022 void insert(int64_t Offset) { Offsets.push_back(Offset); }
1023 bool isUnassigned() const { return Offsets.size() == 0; }
1024
1025 bool isUnknown() const {
1026 if (isUnassigned())
1027 return false;
1028 if (Offsets.size() == 1)
1029 return Offsets.front() == AA::RangeTy::Unknown;
1030 return false;
1031 }
1032
1033 void setUnknown() {
1034 Offsets.clear();
1035 Offsets.push_back(AA::RangeTy::Unknown);
1036 }
1037
1038 void addToAll(int64_t Inc) {
1039 for (auto &Offset : Offsets) {
1040 Offset += Inc;
1041 }
1042 }
1043
1044 /// Copy offsets from \p R into the current list.
1045 ///
1046 /// Ideally all lists should be strictly ascending, but we defer that to the
1047 /// actual use of the list. So we just blindly append here.
1048 void merge(const OffsetInfo &R) { Offsets.append(R.Offsets); }
1049};
1050
1051#ifndef NDEBUG
1052static raw_ostream &operator<<(raw_ostream &OS, const OffsetInfo &OI) {
1053 ListSeparator LS;
1054 OS << "[";
1055 for (auto Offset : OI) {
1056 OS << LS << Offset;
1057 }
1058 OS << "]";
1059 return OS;
1060}
1061#endif // NDEBUG
1062
1063struct AAPointerInfoImpl
1064 : public StateWrapper<AA::PointerInfo::State, AAPointerInfo> {
1066 AAPointerInfoImpl(const IRPosition &IRP, Attributor &A) : BaseTy(IRP) {}
1067
1068 /// See AbstractAttribute::getAsStr().
1069 const std::string getAsStr(Attributor *A) const override {
1070 return std::string("PointerInfo ") +
1071 (isValidState() ? (std::string("#") +
1072 std::to_string(OffsetBins.size()) + " bins")
1073 : "<invalid>");
1074 }
1075
1076 /// See AbstractAttribute::manifest(...).
1077 ChangeStatus manifest(Attributor &A) override {
1078 return AAPointerInfo::manifest(A);
1079 }
1080
1081 virtual const_bin_iterator begin() const override { return State::begin(); }
1082 virtual const_bin_iterator end() const override { return State::end(); }
1083 virtual int64_t numOffsetBins() const override {
1084 return State::numOffsetBins();
1085 }
1086
1087 bool forallInterferingAccesses(
1089 function_ref<bool(const AAPointerInfo::Access &, bool)> CB)
1090 const override {
1091 return State::forallInterferingAccesses(Range, CB);
1092 }
1093
1094 bool forallInterferingAccesses(
1095 Attributor &A, const AbstractAttribute &QueryingAA, Instruction &I,
1096 bool FindInterferingWrites, bool FindInterferingReads,
1097 function_ref<bool(const Access &, bool)> UserCB, bool &HasBeenWrittenTo,
1099 function_ref<bool(const Access &)> SkipCB) const override {
1100 HasBeenWrittenTo = false;
1101
1102 SmallPtrSet<const Access *, 8> DominatingWrites;
1103 SmallVector<std::pair<const Access *, bool>, 8> InterferingAccesses;
1104
1105 Function &Scope = *I.getFunction();
1106 bool IsKnownNoSync;
1107 bool IsAssumedNoSync = AA::hasAssumedIRAttr<Attribute::NoSync>(
1108 A, &QueryingAA, IRPosition::function(Scope), DepClassTy::OPTIONAL,
1109 IsKnownNoSync);
1110 const auto *ExecDomainAA = A.lookupAAFor<AAExecutionDomain>(
1111 IRPosition::function(Scope), &QueryingAA, DepClassTy::NONE);
1112 bool AllInSameNoSyncFn = IsAssumedNoSync;
1113 bool InstIsExecutedByInitialThreadOnly =
1114 ExecDomainAA && ExecDomainAA->isExecutedByInitialThreadOnly(I);
1115
1116 // If the function is not ending in aligned barriers, we need the stores to
1117 // be in aligned barriers. The load being in one is not sufficient since the
1118 // store might be executed by a thread that disappears after, causing the
1119 // aligned barrier guarding the load to unblock and the load to read a value
1120 // that has no CFG path to the load.
1121 bool InstIsExecutedInAlignedRegion =
1122 FindInterferingReads && ExecDomainAA &&
1123 ExecDomainAA->isExecutedInAlignedRegion(A, I);
1124
1125 if (InstIsExecutedInAlignedRegion || InstIsExecutedByInitialThreadOnly)
1126 A.recordDependence(*ExecDomainAA, QueryingAA, DepClassTy::OPTIONAL);
1127
1128 InformationCache &InfoCache = A.getInfoCache();
1129 bool IsThreadLocalObj =
1130 AA::isAssumedThreadLocalObject(A, getAssociatedValue(), *this);
1131
1132 // Helper to determine if we need to consider threading, which we cannot
1133 // right now. However, if the function is (assumed) nosync or the thread
1134 // executing all instructions is the main thread only we can ignore
1135 // threading. Also, thread-local objects do not require threading reasoning.
1136 // Finally, we can ignore threading if either access is executed in an
1137 // aligned region.
1138 auto CanIgnoreThreadingForInst = [&](const Instruction &I) -> bool {
1139 if (IsThreadLocalObj || AllInSameNoSyncFn)
1140 return true;
1141 const auto *FnExecDomainAA =
1142 I.getFunction() == &Scope
1143 ? ExecDomainAA
1144 : A.lookupAAFor<AAExecutionDomain>(
1145 IRPosition::function(*I.getFunction()), &QueryingAA,
1146 DepClassTy::NONE);
1147 if (!FnExecDomainAA)
1148 return false;
1149 if (InstIsExecutedInAlignedRegion ||
1150 (FindInterferingWrites &&
1151 FnExecDomainAA->isExecutedInAlignedRegion(A, I))) {
1152 A.recordDependence(*FnExecDomainAA, QueryingAA, DepClassTy::OPTIONAL);
1153 return true;
1154 }
1155 if (InstIsExecutedByInitialThreadOnly &&
1156 FnExecDomainAA->isExecutedByInitialThreadOnly(I)) {
1157 A.recordDependence(*FnExecDomainAA, QueryingAA, DepClassTy::OPTIONAL);
1158 return true;
1159 }
1160 return false;
1161 };
1162
1163 // Helper to determine if the access is executed by the same thread as the
1164 // given instruction, for now it is sufficient to avoid any potential
1165 // threading effects as we cannot deal with them anyway.
1166 auto CanIgnoreThreading = [&](const Access &Acc) -> bool {
1167 return CanIgnoreThreadingForInst(*Acc.getRemoteInst()) ||
1168 (Acc.getRemoteInst() != Acc.getLocalInst() &&
1169 CanIgnoreThreadingForInst(*Acc.getLocalInst()));
1170 };
1171
1172 // TODO: Use inter-procedural reachability and dominance.
1173 bool IsKnownNoRecurse;
1174 AA::hasAssumedIRAttr<Attribute::NoRecurse>(
1175 A, this, IRPosition::function(Scope), DepClassTy::OPTIONAL,
1176 IsKnownNoRecurse);
1177
1178 // TODO: Use reaching kernels from AAKernelInfo (or move it to
1179 // AAExecutionDomain) such that we allow scopes other than kernels as long
1180 // as the reaching kernels are disjoint.
1181 bool InstInKernel = Scope.hasFnAttribute("kernel");
1182 bool ObjHasKernelLifetime = false;
1183 const bool UseDominanceReasoning =
1184 FindInterferingWrites && IsKnownNoRecurse;
1185 const DominatorTree *DT =
1187
1188 // Helper to check if a value has "kernel lifetime", that is it will not
1189 // outlive a GPU kernel. This is true for shared, constant, and local
1190 // globals on AMD and NVIDIA GPUs.
1191 auto HasKernelLifetime = [&](Value *V, Module &M) {
1192 if (!AA::isGPU(M))
1193 return false;
1194 switch (AA::GPUAddressSpace(V->getType()->getPointerAddressSpace())) {
1195 case AA::GPUAddressSpace::Shared:
1196 case AA::GPUAddressSpace::Constant:
1197 case AA::GPUAddressSpace::Local:
1198 return true;
1199 default:
1200 return false;
1201 };
1202 };
1203
1204 // The IsLiveInCalleeCB will be used by the AA::isPotentiallyReachable query
1205 // to determine if we should look at reachability from the callee. For
1206 // certain pointers we know the lifetime and we do not have to step into the
1207 // callee to determine reachability as the pointer would be dead in the
1208 // callee. See the conditional initialization below.
1209 std::function<bool(const Function &)> IsLiveInCalleeCB;
1210
1211 if (auto *AI = dyn_cast<AllocaInst>(&getAssociatedValue())) {
1212 // If the alloca containing function is not recursive the alloca
1213 // must be dead in the callee.
1214 const Function *AIFn = AI->getFunction();
1215 ObjHasKernelLifetime = AIFn->hasFnAttribute("kernel");
1216 bool IsKnownNoRecurse;
1217 if (AA::hasAssumedIRAttr<Attribute::NoRecurse>(
1218 A, this, IRPosition::function(*AIFn), DepClassTy::OPTIONAL,
1219 IsKnownNoRecurse)) {
1220 IsLiveInCalleeCB = [AIFn](const Function &Fn) { return AIFn != &Fn; };
1221 }
1222 } else if (auto *GV = dyn_cast<GlobalValue>(&getAssociatedValue())) {
1223 // If the global has kernel lifetime we can stop if we reach a kernel
1224 // as it is "dead" in the (unknown) callees.
1225 ObjHasKernelLifetime = HasKernelLifetime(GV, *GV->getParent());
1226 if (ObjHasKernelLifetime)
1227 IsLiveInCalleeCB = [](const Function &Fn) {
1228 return !Fn.hasFnAttribute("kernel");
1229 };
1230 }
1231
1232 // Set of accesses/instructions that will overwrite the result and are
1233 // therefore blockers in the reachability traversal.
1234 AA::InstExclusionSetTy ExclusionSet;
1235
1236 auto AccessCB = [&](const Access &Acc, bool Exact) {
1237 Function *AccScope = Acc.getRemoteInst()->getFunction();
1238 bool AccInSameScope = AccScope == &Scope;
1239
1240 // If the object has kernel lifetime we can ignore accesses only reachable
1241 // by other kernels. For now we only skip accesses *in* other kernels.
1242 if (InstInKernel && ObjHasKernelLifetime && !AccInSameScope &&
1243 AccScope->hasFnAttribute("kernel"))
1244 return true;
1245
1246 if (Exact && Acc.isMustAccess() && Acc.getRemoteInst() != &I) {
1247 if (Acc.isWrite() || (isa<LoadInst>(I) && Acc.isWriteOrAssumption()))
1248 ExclusionSet.insert(Acc.getRemoteInst());
1249 }
1250
1251 if ((!FindInterferingWrites || !Acc.isWriteOrAssumption()) &&
1252 (!FindInterferingReads || !Acc.isRead()))
1253 return true;
1254
1255 bool Dominates = FindInterferingWrites && DT && Exact &&
1256 Acc.isMustAccess() && AccInSameScope &&
1257 DT->dominates(Acc.getRemoteInst(), &I);
1258 if (Dominates)
1259 DominatingWrites.insert(&Acc);
1260
1261 // Track if all interesting accesses are in the same `nosync` function as
1262 // the given instruction.
1263 AllInSameNoSyncFn &= Acc.getRemoteInst()->getFunction() == &Scope;
1264
1265 InterferingAccesses.push_back({&Acc, Exact});
1266 return true;
1267 };
1268 if (!State::forallInterferingAccesses(I, AccessCB, Range))
1269 return false;
1270
1271 HasBeenWrittenTo = !DominatingWrites.empty();
1272
1273 // Dominating writes form a chain, find the least/lowest member.
1274 Instruction *LeastDominatingWriteInst = nullptr;
1275 for (const Access *Acc : DominatingWrites) {
1276 if (!LeastDominatingWriteInst) {
1277 LeastDominatingWriteInst = Acc->getRemoteInst();
1278 } else if (DT->dominates(LeastDominatingWriteInst,
1279 Acc->getRemoteInst())) {
1280 LeastDominatingWriteInst = Acc->getRemoteInst();
1281 }
1282 }
1283
1284 // Helper to determine if we can skip a specific write access.
1285 auto CanSkipAccess = [&](const Access &Acc, bool Exact) {
1286 if (SkipCB && SkipCB(Acc))
1287 return true;
1288 if (!CanIgnoreThreading(Acc))
1289 return false;
1290
1291 // Check read (RAW) dependences and write (WAR) dependences as necessary.
1292 // If we successfully excluded all effects we are interested in, the
1293 // access can be skipped.
1294 bool ReadChecked = !FindInterferingReads;
1295 bool WriteChecked = !FindInterferingWrites;
1296
1297 // If the instruction cannot reach the access, the former does not
1298 // interfere with what the access reads.
1299 if (!ReadChecked) {
1300 if (!AA::isPotentiallyReachable(A, I, *Acc.getRemoteInst(), QueryingAA,
1301 &ExclusionSet, IsLiveInCalleeCB))
1302 ReadChecked = true;
1303 }
1304 // If the instruction cannot be reach from the access, the latter does not
1305 // interfere with what the instruction reads.
1306 if (!WriteChecked) {
1307 if (!AA::isPotentiallyReachable(A, *Acc.getRemoteInst(), I, QueryingAA,
1308 &ExclusionSet, IsLiveInCalleeCB))
1309 WriteChecked = true;
1310 }
1311
1312 // If we still might be affected by the write of the access but there are
1313 // dominating writes in the function of the instruction
1314 // (HasBeenWrittenTo), we can try to reason that the access is overwritten
1315 // by them. This would have happend above if they are all in the same
1316 // function, so we only check the inter-procedural case. Effectively, we
1317 // want to show that there is no call after the dominting write that might
1318 // reach the access, and when it returns reach the instruction with the
1319 // updated value. To this end, we iterate all call sites, check if they
1320 // might reach the instruction without going through another access
1321 // (ExclusionSet) and at the same time might reach the access. However,
1322 // that is all part of AAInterFnReachability.
1323 if (!WriteChecked && HasBeenWrittenTo &&
1324 Acc.getRemoteInst()->getFunction() != &Scope) {
1325
1326 const auto *FnReachabilityAA = A.getAAFor<AAInterFnReachability>(
1327 QueryingAA, IRPosition::function(Scope), DepClassTy::OPTIONAL);
1328
1329 // Without going backwards in the call tree, can we reach the access
1330 // from the least dominating write. Do not allow to pass the instruction
1331 // itself either.
1332 bool Inserted = ExclusionSet.insert(&I).second;
1333
1334 if (!FnReachabilityAA ||
1335 !FnReachabilityAA->instructionCanReach(
1336 A, *LeastDominatingWriteInst,
1337 *Acc.getRemoteInst()->getFunction(), &ExclusionSet))
1338 WriteChecked = true;
1339
1340 if (Inserted)
1341 ExclusionSet.erase(&I);
1342 }
1343
1344 if (ReadChecked && WriteChecked)
1345 return true;
1346
1347 if (!DT || !UseDominanceReasoning)
1348 return false;
1349 if (!DominatingWrites.count(&Acc))
1350 return false;
1351 return LeastDominatingWriteInst != Acc.getRemoteInst();
1352 };
1353
1354 // Run the user callback on all accesses we cannot skip and return if
1355 // that succeeded for all or not.
1356 for (auto &It : InterferingAccesses) {
1357 if ((!AllInSameNoSyncFn && !IsThreadLocalObj && !ExecDomainAA) ||
1358 !CanSkipAccess(*It.first, It.second)) {
1359 if (!UserCB(*It.first, It.second))
1360 return false;
1361 }
1362 }
1363 return true;
1364 }
1365
1366 ChangeStatus translateAndAddStateFromCallee(Attributor &A,
1367 const AAPointerInfo &OtherAA,
1368 CallBase &CB) {
1369 using namespace AA::PointerInfo;
1370 if (!OtherAA.getState().isValidState() || !isValidState())
1371 return indicatePessimisticFixpoint();
1372
1373 const auto &OtherAAImpl = static_cast<const AAPointerInfoImpl &>(OtherAA);
1374 bool IsByval = OtherAAImpl.getAssociatedArgument()->hasByValAttr();
1375
1376 // Combine the accesses bin by bin.
1377 ChangeStatus Changed = ChangeStatus::UNCHANGED;
1378 const auto &State = OtherAAImpl.getState();
1379 for (const auto &It : State) {
1380 for (auto Index : It.getSecond()) {
1381 const auto &RAcc = State.getAccess(Index);
1382 if (IsByval && !RAcc.isRead())
1383 continue;
1384 bool UsedAssumedInformation = false;
1385 AccessKind AK = RAcc.getKind();
1386 auto Content = A.translateArgumentToCallSiteContent(
1387 RAcc.getContent(), CB, *this, UsedAssumedInformation);
1388 AK = AccessKind(AK & (IsByval ? AccessKind::AK_R : AccessKind::AK_RW));
1389 AK = AccessKind(AK | (RAcc.isMayAccess() ? AK_MAY : AK_MUST));
1390
1391 Changed |= addAccess(A, RAcc.getRanges(), CB, Content, AK,
1392 RAcc.getType(), RAcc.getRemoteInst());
1393 }
1394 }
1395 return Changed;
1396 }
1397
1398 ChangeStatus translateAndAddState(Attributor &A, const AAPointerInfo &OtherAA,
1399 const OffsetInfo &Offsets, CallBase &CB) {
1400 using namespace AA::PointerInfo;
1401 if (!OtherAA.getState().isValidState() || !isValidState())
1402 return indicatePessimisticFixpoint();
1403
1404 const auto &OtherAAImpl = static_cast<const AAPointerInfoImpl &>(OtherAA);
1405
1406 // Combine the accesses bin by bin.
1407 ChangeStatus Changed = ChangeStatus::UNCHANGED;
1408 const auto &State = OtherAAImpl.getState();
1409 for (const auto &It : State) {
1410 for (auto Index : It.getSecond()) {
1411 const auto &RAcc = State.getAccess(Index);
1412 for (auto Offset : Offsets) {
1413 auto NewRanges = Offset == AA::RangeTy::Unknown
1415 : RAcc.getRanges();
1416 if (!NewRanges.isUnknown()) {
1417 NewRanges.addToAllOffsets(Offset);
1418 }
1419 Changed |=
1420 addAccess(A, NewRanges, CB, RAcc.getContent(), RAcc.getKind(),
1421 RAcc.getType(), RAcc.getRemoteInst());
1422 }
1423 }
1424 }
1425 return Changed;
1426 }
1427
1428 /// Statistic tracking for all AAPointerInfo implementations.
1429 /// See AbstractAttribute::trackStatistics().
1430 void trackPointerInfoStatistics(const IRPosition &IRP) const {}
1431
1432 /// Dump the state into \p O.
1433 void dumpState(raw_ostream &O) {
1434 for (auto &It : OffsetBins) {
1435 O << "[" << It.first.Offset << "-" << It.first.Offset + It.first.Size
1436 << "] : " << It.getSecond().size() << "\n";
1437 for (auto AccIndex : It.getSecond()) {
1438 auto &Acc = AccessList[AccIndex];
1439 O << " - " << Acc.getKind() << " - " << *Acc.getLocalInst() << "\n";
1440 if (Acc.getLocalInst() != Acc.getRemoteInst())
1441 O << " --> " << *Acc.getRemoteInst()
1442 << "\n";
1443 if (!Acc.isWrittenValueYetUndetermined()) {
1444 if (isa_and_nonnull<Function>(Acc.getWrittenValue()))
1445 O << " - c: func " << Acc.getWrittenValue()->getName()
1446 << "\n";
1447 else if (Acc.getWrittenValue())
1448 O << " - c: " << *Acc.getWrittenValue() << "\n";
1449 else
1450 O << " - c: <unknown>\n";
1451 }
1452 }
1453 }
1454 }
1455};
1456
1457struct AAPointerInfoFloating : public AAPointerInfoImpl {
1459 AAPointerInfoFloating(const IRPosition &IRP, Attributor &A)
1460 : AAPointerInfoImpl(IRP, A) {}
1461
1462 /// Deal with an access and signal if it was handled successfully.
1463 bool handleAccess(Attributor &A, Instruction &I,
1464 std::optional<Value *> Content, AccessKind Kind,
1465 SmallVectorImpl<int64_t> &Offsets, ChangeStatus &Changed,
1466 Type &Ty) {
1467 using namespace AA::PointerInfo;
1469 const DataLayout &DL = A.getDataLayout();
1470 TypeSize AccessSize = DL.getTypeStoreSize(&Ty);
1471 if (!AccessSize.isScalable())
1472 Size = AccessSize.getFixedValue();
1473
1474 // Make a strictly ascending list of offsets as required by addAccess()
1475 llvm::sort(Offsets);
1476 auto *Last = llvm::unique(Offsets);
1477 Offsets.erase(Last, Offsets.end());
1478
1479 VectorType *VT = dyn_cast<VectorType>(&Ty);
1480 if (!VT || VT->getElementCount().isScalable() ||
1481 !Content.value_or(nullptr) || !isa<Constant>(*Content) ||
1482 (*Content)->getType() != VT ||
1483 DL.getTypeStoreSize(VT->getElementType()).isScalable()) {
1484 Changed = Changed | addAccess(A, {Offsets, Size}, I, Content, Kind, &Ty);
1485 } else {
1486 // Handle vector stores with constant content element-wise.
1487 // TODO: We could look for the elements or create instructions
1488 // representing them.
1489 // TODO: We need to push the Content into the range abstraction
1490 // (AA::RangeTy) to allow different content values for different
1491 // ranges. ranges. Hence, support vectors storing different values.
1492 Type *ElementType = VT->getElementType();
1493 int64_t ElementSize = DL.getTypeStoreSize(ElementType).getFixedValue();
1494 auto *ConstContent = cast<Constant>(*Content);
1495 Type *Int32Ty = Type::getInt32Ty(ElementType->getContext());
1496 SmallVector<int64_t> ElementOffsets(Offsets.begin(), Offsets.end());
1497
1498 for (int i = 0, e = VT->getElementCount().getFixedValue(); i != e; ++i) {
1499 Value *ElementContent = ConstantExpr::getExtractElement(
1500 ConstContent, ConstantInt::get(Int32Ty, i));
1501
1502 // Add the element access.
1503 Changed = Changed | addAccess(A, {ElementOffsets, ElementSize}, I,
1504 ElementContent, Kind, ElementType);
1505
1506 // Advance the offsets for the next element.
1507 for (auto &ElementOffset : ElementOffsets)
1508 ElementOffset += ElementSize;
1509 }
1510 }
1511 return true;
1512 };
1513
1514 /// See AbstractAttribute::updateImpl(...).
1515 ChangeStatus updateImpl(Attributor &A) override;
1516
1517 /// If the indices to \p GEP can be traced to constants, incorporate all
1518 /// of these into \p UsrOI.
1519 ///
1520 /// \return true iff \p UsrOI is updated.
1521 bool collectConstantsForGEP(Attributor &A, const DataLayout &DL,
1522 OffsetInfo &UsrOI, const OffsetInfo &PtrOI,
1523 const GEPOperator *GEP);
1524
1525 /// See AbstractAttribute::trackStatistics()
1526 void trackStatistics() const override {
1527 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
1528 }
1529};
1530
1531bool AAPointerInfoFloating::collectConstantsForGEP(Attributor &A,
1532 const DataLayout &DL,
1533 OffsetInfo &UsrOI,
1534 const OffsetInfo &PtrOI,
1535 const GEPOperator *GEP) {
1536 unsigned BitWidth = DL.getIndexTypeSizeInBits(GEP->getType());
1537 MapVector<Value *, APInt> VariableOffsets;
1538 APInt ConstantOffset(BitWidth, 0);
1539
1540 assert(!UsrOI.isUnknown() && !PtrOI.isUnknown() &&
1541 "Don't look for constant values if the offset has already been "
1542 "determined to be unknown.");
1543
1544 if (!GEP->collectOffset(DL, BitWidth, VariableOffsets, ConstantOffset)) {
1545 UsrOI.setUnknown();
1546 return true;
1547 }
1548
1549 LLVM_DEBUG(dbgs() << "[AAPointerInfo] GEP offset is "
1550 << (VariableOffsets.empty() ? "" : "not") << " constant "
1551 << *GEP << "\n");
1552
1553 auto Union = PtrOI;
1554 Union.addToAll(ConstantOffset.getSExtValue());
1555
1556 // Each VI in VariableOffsets has a set of potential constant values. Every
1557 // combination of elements, picked one each from these sets, is separately
1558 // added to the original set of offsets, thus resulting in more offsets.
1559 for (const auto &VI : VariableOffsets) {
1560 auto *PotentialConstantsAA = A.getAAFor<AAPotentialConstantValues>(
1561 *this, IRPosition::value(*VI.first), DepClassTy::OPTIONAL);
1562 if (!PotentialConstantsAA || !PotentialConstantsAA->isValidState()) {
1563 UsrOI.setUnknown();
1564 return true;
1565 }
1566
1567 // UndefValue is treated as a zero, which leaves Union as is.
1568 if (PotentialConstantsAA->undefIsContained())
1569 continue;
1570
1571 // We need at least one constant in every set to compute an actual offset.
1572 // Otherwise, we end up pessimizing AAPointerInfo by respecting offsets that
1573 // don't actually exist. In other words, the absence of constant values
1574 // implies that the operation can be assumed dead for now.
1575 auto &AssumedSet = PotentialConstantsAA->getAssumedSet();
1576 if (AssumedSet.empty())
1577 return false;
1578
1579 OffsetInfo Product;
1580 for (const auto &ConstOffset : AssumedSet) {
1581 auto CopyPerOffset = Union;
1582 CopyPerOffset.addToAll(ConstOffset.getSExtValue() *
1583 VI.second.getZExtValue());
1584 Product.merge(CopyPerOffset);
1585 }
1586 Union = Product;
1587 }
1588
1589 UsrOI = std::move(Union);
1590 return true;
1591}
1592
1593ChangeStatus AAPointerInfoFloating::updateImpl(Attributor &A) {
1594 using namespace AA::PointerInfo;
1596 const DataLayout &DL = A.getDataLayout();
1597 Value &AssociatedValue = getAssociatedValue();
1598
1599 DenseMap<Value *, OffsetInfo> OffsetInfoMap;
1600 OffsetInfoMap[&AssociatedValue].insert(0);
1601
1602 auto HandlePassthroughUser = [&](Value *Usr, Value *CurPtr, bool &Follow) {
1603 // One does not simply walk into a map and assign a reference to a possibly
1604 // new location. That can cause an invalidation before the assignment
1605 // happens, like so:
1606 //
1607 // OffsetInfoMap[Usr] = OffsetInfoMap[CurPtr]; /* bad idea! */
1608 //
1609 // The RHS is a reference that may be invalidated by an insertion caused by
1610 // the LHS. So we ensure that the side-effect of the LHS happens first.
1611
1612 assert(OffsetInfoMap.contains(CurPtr) &&
1613 "CurPtr does not exist in the map!");
1614
1615 auto &UsrOI = OffsetInfoMap[Usr];
1616 auto &PtrOI = OffsetInfoMap[CurPtr];
1617 assert(!PtrOI.isUnassigned() &&
1618 "Cannot pass through if the input Ptr was not visited!");
1619 UsrOI.merge(PtrOI);
1620 Follow = true;
1621 return true;
1622 };
1623
1624 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
1625 Value *CurPtr = U.get();
1626 User *Usr = U.getUser();
1627 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Analyze " << *CurPtr << " in " << *Usr
1628 << "\n");
1629 assert(OffsetInfoMap.count(CurPtr) &&
1630 "The current pointer offset should have been seeded!");
1631
1632 if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Usr)) {
1633 if (CE->isCast())
1634 return HandlePassthroughUser(Usr, CurPtr, Follow);
1635 if (!isa<GEPOperator>(CE)) {
1636 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Unhandled constant user " << *CE
1637 << "\n");
1638 return false;
1639 }
1640 }
1641 if (auto *GEP = dyn_cast<GEPOperator>(Usr)) {
1642 // Note the order here, the Usr access might change the map, CurPtr is
1643 // already in it though.
1644 auto &UsrOI = OffsetInfoMap[Usr];
1645 auto &PtrOI = OffsetInfoMap[CurPtr];
1646
1647 if (UsrOI.isUnknown())
1648 return true;
1649
1650 if (PtrOI.isUnknown()) {
1651 Follow = true;
1652 UsrOI.setUnknown();
1653 return true;
1654 }
1655
1656 Follow = collectConstantsForGEP(A, DL, UsrOI, PtrOI, GEP);
1657 return true;
1658 }
1659 if (isa<PtrToIntInst>(Usr))
1660 return false;
1661 if (isa<CastInst>(Usr) || isa<SelectInst>(Usr) || isa<ReturnInst>(Usr))
1662 return HandlePassthroughUser(Usr, CurPtr, Follow);
1663
1664 // For PHIs we need to take care of the recurrence explicitly as the value
1665 // might change while we iterate through a loop. For now, we give up if
1666 // the PHI is not invariant.
1667 if (auto *PHI = dyn_cast<PHINode>(Usr)) {
1668 // Note the order here, the Usr access might change the map, CurPtr is
1669 // already in it though.
1670 bool IsFirstPHIUser = !OffsetInfoMap.count(PHI);
1671 auto &UsrOI = OffsetInfoMap[PHI];
1672 auto &PtrOI = OffsetInfoMap[CurPtr];
1673
1674 // Check if the PHI operand has already an unknown offset as we can't
1675 // improve on that anymore.
1676 if (PtrOI.isUnknown()) {
1677 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI operand offset unknown "
1678 << *CurPtr << " in " << *PHI << "\n");
1679 Follow = !UsrOI.isUnknown();
1680 UsrOI.setUnknown();
1681 return true;
1682 }
1683
1684 // Check if the PHI is invariant (so far).
1685 if (UsrOI == PtrOI) {
1686 assert(!PtrOI.isUnassigned() &&
1687 "Cannot assign if the current Ptr was not visited!");
1688 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI is invariant (so far)");
1689 return true;
1690 }
1691
1692 // Check if the PHI operand can be traced back to AssociatedValue.
1693 APInt Offset(
1694 DL.getIndexSizeInBits(CurPtr->getType()->getPointerAddressSpace()),
1695 0);
1696 Value *CurPtrBase = CurPtr->stripAndAccumulateConstantOffsets(
1697 DL, Offset, /* AllowNonInbounds */ true);
1698 auto It = OffsetInfoMap.find(CurPtrBase);
1699 if (It == OffsetInfoMap.end()) {
1700 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI operand is too complex "
1701 << *CurPtr << " in " << *PHI
1702 << " (base: " << *CurPtrBase << ")\n");
1703 UsrOI.setUnknown();
1704 Follow = true;
1705 return true;
1706 }
1707
1708 // Check if the PHI operand is not dependent on the PHI itself. Every
1709 // recurrence is a cyclic net of PHIs in the data flow, and has an
1710 // equivalent Cycle in the control flow. One of those PHIs must be in the
1711 // header of that control flow Cycle. This is independent of the choice of
1712 // Cycles reported by CycleInfo. It is sufficient to check the PHIs in
1713 // every Cycle header; if such a node is marked unknown, this will
1714 // eventually propagate through the whole net of PHIs in the recurrence.
1715 const auto *CI =
1716 A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>(
1717 *PHI->getFunction());
1718 if (mayBeInCycle(CI, cast<Instruction>(Usr), /* HeaderOnly */ true)) {
1719 auto BaseOI = It->getSecond();
1720 BaseOI.addToAll(Offset.getZExtValue());
1721 if (IsFirstPHIUser || BaseOI == UsrOI) {
1722 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI is invariant " << *CurPtr
1723 << " in " << *Usr << "\n");
1724 return HandlePassthroughUser(Usr, CurPtr, Follow);
1725 }
1726
1727 LLVM_DEBUG(
1728 dbgs() << "[AAPointerInfo] PHI operand pointer offset mismatch "
1729 << *CurPtr << " in " << *PHI << "\n");
1730 UsrOI.setUnknown();
1731 Follow = true;
1732 return true;
1733 }
1734
1735 UsrOI.merge(PtrOI);
1736 Follow = true;
1737 return true;
1738 }
1739
1740 if (auto *LoadI = dyn_cast<LoadInst>(Usr)) {
1741 // If the access is to a pointer that may or may not be the associated
1742 // value, e.g. due to a PHI, we cannot assume it will be read.
1743 AccessKind AK = AccessKind::AK_R;
1744 if (getUnderlyingObject(CurPtr) == &AssociatedValue)
1745 AK = AccessKind(AK | AccessKind::AK_MUST);
1746 else
1747 AK = AccessKind(AK | AccessKind::AK_MAY);
1748 if (!handleAccess(A, *LoadI, /* Content */ nullptr, AK,
1749 OffsetInfoMap[CurPtr].Offsets, Changed,
1750 *LoadI->getType()))
1751 return false;
1752
1753 auto IsAssumption = [](Instruction &I) {
1754 if (auto *II = dyn_cast<IntrinsicInst>(&I))
1755 return II->isAssumeLikeIntrinsic();
1756 return false;
1757 };
1758
1759 auto IsImpactedInRange = [&](Instruction *FromI, Instruction *ToI) {
1760 // Check if the assumption and the load are executed together without
1761 // memory modification.
1762 do {
1763 if (FromI->mayWriteToMemory() && !IsAssumption(*FromI))
1764 return true;
1765 FromI = FromI->getNextNonDebugInstruction();
1766 } while (FromI && FromI != ToI);
1767 return false;
1768 };
1769
1770 BasicBlock *BB = LoadI->getParent();
1771 auto IsValidAssume = [&](IntrinsicInst &IntrI) {
1772 if (IntrI.getIntrinsicID() != Intrinsic::assume)
1773 return false;
1774 BasicBlock *IntrBB = IntrI.getParent();
1775 if (IntrI.getParent() == BB) {
1776 if (IsImpactedInRange(LoadI->getNextNonDebugInstruction(), &IntrI))
1777 return false;
1778 } else {
1779 auto PredIt = pred_begin(IntrBB);
1780 if (PredIt == pred_end(IntrBB))
1781 return false;
1782 if ((*PredIt) != BB)
1783 return false;
1784 if (++PredIt != pred_end(IntrBB))
1785 return false;
1786 for (auto *SuccBB : successors(BB)) {
1787 if (SuccBB == IntrBB)
1788 continue;
1789 if (isa<UnreachableInst>(SuccBB->getTerminator()))
1790 continue;
1791 return false;
1792 }
1793 if (IsImpactedInRange(LoadI->getNextNonDebugInstruction(),
1794 BB->getTerminator()))
1795 return false;
1796 if (IsImpactedInRange(&IntrBB->front(), &IntrI))
1797 return false;
1798 }
1799 return true;
1800 };
1801
1802 std::pair<Value *, IntrinsicInst *> Assumption;
1803 for (const Use &LoadU : LoadI->uses()) {
1804 if (auto *CmpI = dyn_cast<CmpInst>(LoadU.getUser())) {
1805 if (!CmpI->isEquality() || !CmpI->isTrueWhenEqual())
1806 continue;
1807 for (const Use &CmpU : CmpI->uses()) {
1808 if (auto *IntrI = dyn_cast<IntrinsicInst>(CmpU.getUser())) {
1809 if (!IsValidAssume(*IntrI))
1810 continue;
1811 int Idx = CmpI->getOperandUse(0) == LoadU;
1812 Assumption = {CmpI->getOperand(Idx), IntrI};
1813 break;
1814 }
1815 }
1816 }
1817 if (Assumption.first)
1818 break;
1819 }
1820
1821 // Check if we found an assumption associated with this load.
1822 if (!Assumption.first || !Assumption.second)
1823 return true;
1824
1825 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Assumption found "
1826 << *Assumption.second << ": " << *LoadI
1827 << " == " << *Assumption.first << "\n");
1828 bool UsedAssumedInformation = false;
1829 std::optional<Value *> Content = nullptr;
1830 if (Assumption.first)
1831 Content =
1832 A.getAssumedSimplified(*Assumption.first, *this,
1833 UsedAssumedInformation, AA::Interprocedural);
1834 return handleAccess(
1835 A, *Assumption.second, Content, AccessKind::AK_ASSUMPTION,
1836 OffsetInfoMap[CurPtr].Offsets, Changed, *LoadI->getType());
1837 }
1838
1839 auto HandleStoreLike = [&](Instruction &I, Value *ValueOp, Type &ValueTy,
1840 ArrayRef<Value *> OtherOps, AccessKind AK) {
1841 for (auto *OtherOp : OtherOps) {
1842 if (OtherOp == CurPtr) {
1843 LLVM_DEBUG(
1844 dbgs()
1845 << "[AAPointerInfo] Escaping use in store like instruction " << I
1846 << "\n");
1847 return false;
1848 }
1849 }
1850
1851 // If the access is to a pointer that may or may not be the associated
1852 // value, e.g. due to a PHI, we cannot assume it will be written.
1853 if (getUnderlyingObject(CurPtr) == &AssociatedValue)
1854 AK = AccessKind(AK | AccessKind::AK_MUST);
1855 else
1856 AK = AccessKind(AK | AccessKind::AK_MAY);
1857 bool UsedAssumedInformation = false;
1858 std::optional<Value *> Content = nullptr;
1859 if (ValueOp)
1860 Content = A.getAssumedSimplified(
1861 *ValueOp, *this, UsedAssumedInformation, AA::Interprocedural);
1862 return handleAccess(A, I, Content, AK, OffsetInfoMap[CurPtr].Offsets,
1863 Changed, ValueTy);
1864 };
1865
1866 if (auto *StoreI = dyn_cast<StoreInst>(Usr))
1867 return HandleStoreLike(*StoreI, StoreI->getValueOperand(),
1868 *StoreI->getValueOperand()->getType(),
1869 {StoreI->getValueOperand()}, AccessKind::AK_W);
1870 if (auto *RMWI = dyn_cast<AtomicRMWInst>(Usr))
1871 return HandleStoreLike(*RMWI, nullptr, *RMWI->getValOperand()->getType(),
1872 {RMWI->getValOperand()}, AccessKind::AK_RW);
1873 if (auto *CXI = dyn_cast<AtomicCmpXchgInst>(Usr))
1874 return HandleStoreLike(
1875 *CXI, nullptr, *CXI->getNewValOperand()->getType(),
1876 {CXI->getCompareOperand(), CXI->getNewValOperand()},
1877 AccessKind::AK_RW);
1878
1879 if (auto *CB = dyn_cast<CallBase>(Usr)) {
1880 if (CB->isLifetimeStartOrEnd())
1881 return true;
1882 const auto *TLI =
1883 A.getInfoCache().getTargetLibraryInfoForFunction(*CB->getFunction());
1884 if (getFreedOperand(CB, TLI) == U)
1885 return true;
1886 if (CB->isArgOperand(&U)) {
1887 unsigned ArgNo = CB->getArgOperandNo(&U);
1888 const auto *CSArgPI = A.getAAFor<AAPointerInfo>(
1889 *this, IRPosition::callsite_argument(*CB, ArgNo),
1891 if (!CSArgPI)
1892 return false;
1893 Changed =
1894 translateAndAddState(A, *CSArgPI, OffsetInfoMap[CurPtr], *CB) |
1895 Changed;
1896 return isValidState();
1897 }
1898 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Call user not handled " << *CB
1899 << "\n");
1900 // TODO: Allow some call uses
1901 return false;
1902 }
1903
1904 LLVM_DEBUG(dbgs() << "[AAPointerInfo] User not handled " << *Usr << "\n");
1905 return false;
1906 };
1907 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) {
1908 assert(OffsetInfoMap.count(OldU) && "Old use should be known already!");
1909 if (OffsetInfoMap.count(NewU)) {
1910 LLVM_DEBUG({
1911 if (!(OffsetInfoMap[NewU] == OffsetInfoMap[OldU])) {
1912 dbgs() << "[AAPointerInfo] Equivalent use callback failed: "
1913 << OffsetInfoMap[NewU] << " vs " << OffsetInfoMap[OldU]
1914 << "\n";
1915 }
1916 });
1917 return OffsetInfoMap[NewU] == OffsetInfoMap[OldU];
1918 }
1919 OffsetInfoMap[NewU] = OffsetInfoMap[OldU];
1920 return true;
1921 };
1922 if (!A.checkForAllUses(UsePred, *this, AssociatedValue,
1923 /* CheckBBLivenessOnly */ true, DepClassTy::OPTIONAL,
1924 /* IgnoreDroppableUses */ true, EquivalentUseCB)) {
1925 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Check for all uses failed, abort!\n");
1926 return indicatePessimisticFixpoint();
1927 }
1928
1929 LLVM_DEBUG({
1930 dbgs() << "Accesses by bin after update:\n";
1931 dumpState(dbgs());
1932 });
1933
1934 return Changed;
1935}
1936
1937struct AAPointerInfoReturned final : AAPointerInfoImpl {
1938 AAPointerInfoReturned(const IRPosition &IRP, Attributor &A)
1939 : AAPointerInfoImpl(IRP, A) {}
1940
1941 /// See AbstractAttribute::updateImpl(...).
1942 ChangeStatus updateImpl(Attributor &A) override {
1943 return indicatePessimisticFixpoint();
1944 }
1945
1946 /// See AbstractAttribute::trackStatistics()
1947 void trackStatistics() const override {
1948 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
1949 }
1950};
1951
1952struct AAPointerInfoArgument final : AAPointerInfoFloating {
1953 AAPointerInfoArgument(const IRPosition &IRP, Attributor &A)
1954 : AAPointerInfoFloating(IRP, A) {}
1955
1956 /// See AbstractAttribute::trackStatistics()
1957 void trackStatistics() const override {
1958 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
1959 }
1960};
1961
1962struct AAPointerInfoCallSiteArgument final : AAPointerInfoFloating {
1963 AAPointerInfoCallSiteArgument(const IRPosition &IRP, Attributor &A)
1964 : AAPointerInfoFloating(IRP, A) {}
1965
1966 /// See AbstractAttribute::updateImpl(...).
1967 ChangeStatus updateImpl(Attributor &A) override {
1968 using namespace AA::PointerInfo;
1969 // We handle memory intrinsics explicitly, at least the first (=
1970 // destination) and second (=source) arguments as we know how they are
1971 // accessed.
1972 if (auto *MI = dyn_cast_or_null<MemIntrinsic>(getCtxI())) {
1973 ConstantInt *Length = dyn_cast<ConstantInt>(MI->getLength());
1974 int64_t LengthVal = AA::RangeTy::Unknown;
1975 if (Length)
1976 LengthVal = Length->getSExtValue();
1977 unsigned ArgNo = getIRPosition().getCallSiteArgNo();
1978 ChangeStatus Changed = ChangeStatus::UNCHANGED;
1979 if (ArgNo > 1) {
1980 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Unhandled memory intrinsic "
1981 << *MI << "\n");
1982 return indicatePessimisticFixpoint();
1983 } else {
1984 auto Kind =
1985 ArgNo == 0 ? AccessKind::AK_MUST_WRITE : AccessKind::AK_MUST_READ;
1986 Changed =
1987 Changed | addAccess(A, {0, LengthVal}, *MI, nullptr, Kind, nullptr);
1988 }
1989 LLVM_DEBUG({
1990 dbgs() << "Accesses by bin after update:\n";
1991 dumpState(dbgs());
1992 });
1993
1994 return Changed;
1995 }
1996
1997 // TODO: Once we have call site specific value information we can provide
1998 // call site specific liveness information and then it makes
1999 // sense to specialize attributes for call sites arguments instead of
2000 // redirecting requests to the callee argument.
2001 Argument *Arg = getAssociatedArgument();
2002 if (Arg) {
2003 const IRPosition &ArgPos = IRPosition::argument(*Arg);
2004 auto *ArgAA =
2005 A.getAAFor<AAPointerInfo>(*this, ArgPos, DepClassTy::REQUIRED);
2006 if (ArgAA && ArgAA->getState().isValidState())
2007 return translateAndAddStateFromCallee(A, *ArgAA,
2008 *cast<CallBase>(getCtxI()));
2009 if (!Arg->getParent()->isDeclaration())
2010 return indicatePessimisticFixpoint();
2011 }
2012
2013 bool IsKnownNoCapture;
2014 if (!AA::hasAssumedIRAttr<Attribute::NoCapture>(
2015 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNoCapture))
2016 return indicatePessimisticFixpoint();
2017
2018 bool IsKnown = false;
2019 if (AA::isAssumedReadNone(A, getIRPosition(), *this, IsKnown))
2020 return ChangeStatus::UNCHANGED;
2021 bool ReadOnly = AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown);
2022 auto Kind =
2023 ReadOnly ? AccessKind::AK_MAY_READ : AccessKind::AK_MAY_READ_WRITE;
2024 return addAccess(A, AA::RangeTy::getUnknown(), *getCtxI(), nullptr, Kind,
2025 nullptr);
2026 }
2027
2028 /// See AbstractAttribute::trackStatistics()
2029 void trackStatistics() const override {
2030 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
2031 }
2032};
2033
2034struct AAPointerInfoCallSiteReturned final : AAPointerInfoFloating {
2035 AAPointerInfoCallSiteReturned(const IRPosition &IRP, Attributor &A)
2036 : AAPointerInfoFloating(IRP, A) {}
2037
2038 /// See AbstractAttribute::trackStatistics()
2039 void trackStatistics() const override {
2040 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
2041 }
2042};
2043} // namespace
2044
2045/// -----------------------NoUnwind Function Attribute--------------------------
2046
2047namespace {
2048struct AANoUnwindImpl : AANoUnwind {
2049 AANoUnwindImpl(const IRPosition &IRP, Attributor &A) : AANoUnwind(IRP, A) {}
2050
2051 /// See AbstractAttribute::initialize(...).
2052 void initialize(Attributor &A) override {
2053 bool IsKnown;
2054 assert(!AA::hasAssumedIRAttr<Attribute::NoUnwind>(
2055 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
2056 (void)IsKnown;
2057 }
2058
2059 const std::string getAsStr(Attributor *A) const override {
2060 return getAssumed() ? "nounwind" : "may-unwind";
2061 }
2062
2063 /// See AbstractAttribute::updateImpl(...).
2064 ChangeStatus updateImpl(Attributor &A) override {
2065 auto Opcodes = {
2066 (unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,
2067 (unsigned)Instruction::Call, (unsigned)Instruction::CleanupRet,
2068 (unsigned)Instruction::CatchSwitch, (unsigned)Instruction::Resume};
2069
2070 auto CheckForNoUnwind = [&](Instruction &I) {
2071 if (!I.mayThrow(/* IncludePhaseOneUnwind */ true))
2072 return true;
2073
2074 if (const auto *CB = dyn_cast<CallBase>(&I)) {
2075 bool IsKnownNoUnwind;
2076 return AA::hasAssumedIRAttr<Attribute::NoUnwind>(
2077 A, this, IRPosition::callsite_function(*CB), DepClassTy::REQUIRED,
2078 IsKnownNoUnwind);
2079 }
2080 return false;
2081 };
2082
2083 bool UsedAssumedInformation = false;
2084 if (!A.checkForAllInstructions(CheckForNoUnwind, *this, Opcodes,
2085 UsedAssumedInformation))
2086 return indicatePessimisticFixpoint();
2087
2088 return ChangeStatus::UNCHANGED;
2089 }
2090};
2091
2092struct AANoUnwindFunction final : public AANoUnwindImpl {
2093 AANoUnwindFunction(const IRPosition &IRP, Attributor &A)
2094 : AANoUnwindImpl(IRP, A) {}
2095
2096 /// See AbstractAttribute::trackStatistics()
2097 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nounwind) }
2098};
2099
2100/// NoUnwind attribute deduction for a call sites.
2101struct AANoUnwindCallSite final
2102 : AACalleeToCallSite<AANoUnwind, AANoUnwindImpl> {
2103 AANoUnwindCallSite(const IRPosition &IRP, Attributor &A)
2104 : AACalleeToCallSite<AANoUnwind, AANoUnwindImpl>(IRP, A) {}
2105
2106 /// See AbstractAttribute::trackStatistics()
2107 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nounwind); }
2108};
2109} // namespace
2110
2111/// ------------------------ NoSync Function Attribute -------------------------
2112
2113bool AANoSync::isAlignedBarrier(const CallBase &CB, bool ExecutedAligned) {
2114 switch (CB.getIntrinsicID()) {
2115 case Intrinsic::nvvm_barrier0:
2116 case Intrinsic::nvvm_barrier0_and:
2117 case Intrinsic::nvvm_barrier0_or:
2118 case Intrinsic::nvvm_barrier0_popc:
2119 return true;
2120 case Intrinsic::amdgcn_s_barrier:
2121 if (ExecutedAligned)
2122 return true;
2123 break;
2124 default:
2125 break;
2126 }
2127 return hasAssumption(CB, KnownAssumptionString("ompx_aligned_barrier"));
2128}
2129
2131 if (!I->isAtomic())
2132 return false;
2133
2134 if (auto *FI = dyn_cast<FenceInst>(I))
2135 // All legal orderings for fence are stronger than monotonic.
2136 return FI->getSyncScopeID() != SyncScope::SingleThread;
2137 if (auto *AI = dyn_cast<AtomicCmpXchgInst>(I)) {
2138 // Unordered is not a legal ordering for cmpxchg.
2139 return (AI->getSuccessOrdering() != AtomicOrdering::Monotonic ||
2140 AI->getFailureOrdering() != AtomicOrdering::Monotonic);
2141 }
2142
2143 AtomicOrdering Ordering;
2144 switch (I->getOpcode()) {
2145 case Instruction::AtomicRMW:
2146 Ordering = cast<AtomicRMWInst>(I)->getOrdering();
2147 break;
2148 case Instruction::Store:
2149 Ordering = cast<StoreInst>(I)->getOrdering();
2150 break;
2151 case Instruction::Load:
2152 Ordering = cast<LoadInst>(I)->getOrdering();
2153 break;
2154 default:
2156 "New atomic operations need to be known in the attributor.");
2157 }
2158
2159 return (Ordering != AtomicOrdering::Unordered &&
2160 Ordering != AtomicOrdering::Monotonic);
2161}
2162
2163/// Return true if this intrinsic is nosync. This is only used for intrinsics
2164/// which would be nosync except that they have a volatile flag. All other
2165/// intrinsics are simply annotated with the nosync attribute in Intrinsics.td.
2167 if (auto *MI = dyn_cast<MemIntrinsic>(I))
2168 return !MI->isVolatile();
2169 return false;
2170}
2171
2172namespace {
2173struct AANoSyncImpl : AANoSync {
2174 AANoSyncImpl(const IRPosition &IRP, Attributor &A) : AANoSync(IRP, A) {}
2175
2176 /// See AbstractAttribute::initialize(...).
2177 void initialize(Attributor &A) override {
2178 bool IsKnown;
2179 assert(!AA::hasAssumedIRAttr<Attribute::NoSync>(A, nullptr, getIRPosition(),
2180 DepClassTy::NONE, IsKnown));
2181 (void)IsKnown;
2182 }
2183
2184 const std::string getAsStr(Attributor *A) const override {
2185 return getAssumed() ? "nosync" : "may-sync";
2186 }
2187
2188 /// See AbstractAttribute::updateImpl(...).
2189 ChangeStatus updateImpl(Attributor &A) override;
2190};
2191
2192ChangeStatus AANoSyncImpl::updateImpl(Attributor &A) {
2193
2194 auto CheckRWInstForNoSync = [&](Instruction &I) {
2195 return AA::isNoSyncInst(A, I, *this);
2196 };
2197
2198 auto CheckForNoSync = [&](Instruction &I) {
2199 // At this point we handled all read/write effects and they are all
2200 // nosync, so they can be skipped.
2201 if (I.mayReadOrWriteMemory())
2202 return true;
2203
2204 bool IsKnown;
2205 CallBase &CB = cast<CallBase>(I);
2206 if (AA::hasAssumedIRAttr<Attribute::NoSync>(
2208 IsKnown))
2209 return true;
2210
2211 // non-convergent and readnone imply nosync.
2212 return !CB.isConvergent();
2213 };
2214
2215 bool UsedAssumedInformation = false;
2216 if (!A.checkForAllReadWriteInstructions(CheckRWInstForNoSync, *this,
2217 UsedAssumedInformation) ||
2218 !A.checkForAllCallLikeInstructions(CheckForNoSync, *this,
2219 UsedAssumedInformation))
2220 return indicatePessimisticFixpoint();
2221
2223}
2224
2225struct AANoSyncFunction final : public AANoSyncImpl {
2226 AANoSyncFunction(const IRPosition &IRP, Attributor &A)
2227 : AANoSyncImpl(IRP, A) {}
2228
2229 /// See AbstractAttribute::trackStatistics()
2230 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nosync) }
2231};
2232
2233/// NoSync attribute deduction for a call sites.
2234struct AANoSyncCallSite final : AACalleeToCallSite<AANoSync, AANoSyncImpl> {
2235 AANoSyncCallSite(const IRPosition &IRP, Attributor &A)
2236 : AACalleeToCallSite<AANoSync, AANoSyncImpl>(IRP, A) {}
2237
2238 /// See AbstractAttribute::trackStatistics()
2239 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nosync); }
2240};
2241} // namespace
2242
2243/// ------------------------ No-Free Attributes ----------------------------
2244
2245namespace {
2246struct AANoFreeImpl : public AANoFree {
2247 AANoFreeImpl(const IRPosition &IRP, Attributor &A) : AANoFree(IRP, A) {}
2248
2249 /// See AbstractAttribute::initialize(...).
2250 void initialize(Attributor &A) override {
2251 bool IsKnown;
2252 assert(!AA::hasAssumedIRAttr<Attribute::NoFree>(A, nullptr, getIRPosition(),
2253 DepClassTy::NONE, IsKnown));
2254 (void)IsKnown;
2255 }
2256
2257 /// See AbstractAttribute::updateImpl(...).
2258 ChangeStatus updateImpl(Attributor &A) override {
2259 auto CheckForNoFree = [&](Instruction &I) {
2260 bool IsKnown;
2261 return AA::hasAssumedIRAttr<Attribute::NoFree>(
2262 A, this, IRPosition::callsite_function(cast<CallBase>(I)),
2263 DepClassTy::REQUIRED, IsKnown);
2264 };
2265
2266 bool UsedAssumedInformation = false;
2267 if (!A.checkForAllCallLikeInstructions(CheckForNoFree, *this,
2268 UsedAssumedInformation))
2269 return indicatePessimisticFixpoint();
2270 return ChangeStatus::UNCHANGED;
2271 }
2272
2273 /// See AbstractAttribute::getAsStr().
2274 const std::string getAsStr(Attributor *A) const override {
2275 return getAssumed() ? "nofree" : "may-free";
2276 }
2277};
2278
2279struct AANoFreeFunction final : public AANoFreeImpl {
2280 AANoFreeFunction(const IRPosition &IRP, Attributor &A)
2281 : AANoFreeImpl(IRP, A) {}
2282
2283 /// See AbstractAttribute::trackStatistics()
2284 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nofree) }
2285};
2286
2287/// NoFree attribute deduction for a call sites.
2288struct AANoFreeCallSite final : AACalleeToCallSite<AANoFree, AANoFreeImpl> {
2289 AANoFreeCallSite(const IRPosition &IRP, Attributor &A)
2290 : AACalleeToCallSite<AANoFree, AANoFreeImpl>(IRP, A) {}
2291
2292 /// See AbstractAttribute::trackStatistics()
2293 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nofree); }
2294};
2295
2296/// NoFree attribute for floating values.
2297struct AANoFreeFloating : AANoFreeImpl {
2298 AANoFreeFloating(const IRPosition &IRP, Attributor &A)
2299 : AANoFreeImpl(IRP, A) {}
2300
2301 /// See AbstractAttribute::trackStatistics()
2302 void trackStatistics() const override{STATS_DECLTRACK_FLOATING_ATTR(nofree)}
2303
2304 /// See Abstract Attribute::updateImpl(...).
2305 ChangeStatus updateImpl(Attributor &A) override {
2306 const IRPosition &IRP = getIRPosition();
2307
2308 bool IsKnown;
2309 if (AA::hasAssumedIRAttr<Attribute::NoFree>(A, this,
2311 DepClassTy::OPTIONAL, IsKnown))
2312 return ChangeStatus::UNCHANGED;
2313
2314 Value &AssociatedValue = getIRPosition().getAssociatedValue();
2315 auto Pred = [&](const Use &U, bool &Follow) -> bool {
2316 Instruction *UserI = cast<Instruction>(U.getUser());
2317 if (auto *CB = dyn_cast<CallBase>(UserI)) {
2318 if (CB->isBundleOperand(&U))
2319 return false;
2320 if (!CB->isArgOperand(&U))
2321 return true;
2322 unsigned ArgNo = CB->getArgOperandNo(&U);
2323
2324 bool IsKnown;
2325 return AA::hasAssumedIRAttr<Attribute::NoFree>(
2326 A, this, IRPosition::callsite_argument(*CB, ArgNo),
2327 DepClassTy::REQUIRED, IsKnown);
2328 }
2329
2330 if (isa<GetElementPtrInst>(UserI) || isa<BitCastInst>(UserI) ||
2331 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) {
2332 Follow = true;
2333 return true;
2334 }
2335 if (isa<StoreInst>(UserI) || isa<LoadInst>(UserI) ||
2336 isa<ReturnInst>(UserI))
2337 return true;
2338
2339 // Unknown user.
2340 return false;
2341 };
2342 if (!A.checkForAllUses(Pred, *this, AssociatedValue))
2343 return indicatePessimisticFixpoint();
2344
2345 return ChangeStatus::UNCHANGED;
2346 }
2347};
2348
2349/// NoFree attribute for a call site argument.
2350struct AANoFreeArgument final : AANoFreeFloating {
2351 AANoFreeArgument(const IRPosition &IRP, Attributor &A)
2352 : AANoFreeFloating(IRP, A) {}
2353
2354 /// See AbstractAttribute::trackStatistics()
2355 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nofree) }
2356};
2357
2358/// NoFree attribute for call site arguments.
2359struct AANoFreeCallSiteArgument final : AANoFreeFloating {
2360 AANoFreeCallSiteArgument(const IRPosition &IRP, Attributor &A)
2361 : AANoFreeFloating(IRP, A) {}
2362
2363 /// See AbstractAttribute::updateImpl(...).
2364 ChangeStatus updateImpl(Attributor &A) override {
2365 // TODO: Once we have call site specific value information we can provide
2366 // call site specific liveness information and then it makes
2367 // sense to specialize attributes for call sites arguments instead of
2368 // redirecting requests to the callee argument.
2369 Argument *Arg = getAssociatedArgument();
2370 if (!Arg)
2371 return indicatePessimisticFixpoint();
2372 const IRPosition &ArgPos = IRPosition::argument(*Arg);
2373 bool IsKnown;
2374 if (AA::hasAssumedIRAttr<Attribute::NoFree>(A, this, ArgPos,
2375 DepClassTy::REQUIRED, IsKnown))
2376 return ChangeStatus::UNCHANGED;
2377 return indicatePessimisticFixpoint();
2378 }
2379
2380 /// See AbstractAttribute::trackStatistics()
2381 void trackStatistics() const override{STATS_DECLTRACK_CSARG_ATTR(nofree)};
2382};
2383
2384/// NoFree attribute for function return value.
2385struct AANoFreeReturned final : AANoFreeFloating {
2386 AANoFreeReturned(const IRPosition &IRP, Attributor &A)
2387 : AANoFreeFloating(IRP, A) {
2388 llvm_unreachable("NoFree is not applicable to function returns!");
2389 }
2390
2391 /// See AbstractAttribute::initialize(...).
2392 void initialize(Attributor &A) override {
2393 llvm_unreachable("NoFree is not applicable to function returns!");
2394 }
2395
2396 /// See AbstractAttribute::updateImpl(...).
2397 ChangeStatus updateImpl(Attributor &A) override {
2398 llvm_unreachable("NoFree is not applicable to function returns!");
2399 }
2400
2401 /// See AbstractAttribute::trackStatistics()
2402 void trackStatistics() const override {}
2403};
2404
2405/// NoFree attribute deduction for a call site return value.
2406struct AANoFreeCallSiteReturned final : AANoFreeFloating {
2407 AANoFreeCallSiteReturned(const IRPosition &IRP, Attributor &A)
2408 : AANoFreeFloating(IRP, A) {}
2409
2410 ChangeStatus manifest(Attributor &A) override {
2411 return ChangeStatus::UNCHANGED;
2412 }
2413 /// See AbstractAttribute::trackStatistics()
2414 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(nofree) }
2415};
2416} // namespace
2417
2418/// ------------------------ NonNull Argument Attribute ------------------------
2419
2421 Attribute::AttrKind ImpliedAttributeKind,
2422 bool IgnoreSubsumingPositions) {
2424 AttrKinds.push_back(Attribute::NonNull);
2427 AttrKinds.push_back(Attribute::Dereferenceable);
2428 if (A.hasAttr(IRP, AttrKinds, IgnoreSubsumingPositions, Attribute::NonNull))
2429 return true;
2430
2431 DominatorTree *DT = nullptr;
2432 AssumptionCache *AC = nullptr;
2433 InformationCache &InfoCache = A.getInfoCache();
2434 if (const Function *Fn = IRP.getAnchorScope()) {
2435 if (!Fn->isDeclaration()) {
2438 }
2439 }
2440
2442 if (IRP.getPositionKind() != IRP_RETURNED) {
2443 Worklist.push_back({IRP.getAssociatedValue(), IRP.getCtxI()});
2444 } else {
2445 bool UsedAssumedInformation = false;
2446 if (!A.checkForAllInstructions(
2447 [&](Instruction &I) {
2448 Worklist.push_back({*cast<ReturnInst>(I).getReturnValue(), &I});
2449 return true;
2450 },
2451 IRP.getAssociatedFunction(), nullptr, {Instruction::Ret},
2452 UsedAssumedInformation, false, /*CheckPotentiallyDead=*/true))
2453 return false;
2454 }
2455
2456 if (llvm::any_of(Worklist, [&](AA::ValueAndContext VAC) {
2457 return !isKnownNonZero(
2458 VAC.getValue(),
2459 SimplifyQuery(A.getDataLayout(), DT, AC, VAC.getCtxI()));
2460 }))
2461 return false;
2462
2463 A.manifestAttrs(IRP, {Attribute::get(IRP.getAnchorValue().getContext(),
2464 Attribute::NonNull)});
2465 return true;
2466}
2467
2468namespace {
2469static int64_t getKnownNonNullAndDerefBytesForUse(
2470 Attributor &A, const AbstractAttribute &QueryingAA, Value &AssociatedValue,
2471 const Use *U, const Instruction *I, bool &IsNonNull, bool &TrackUse) {
2472 TrackUse = false;
2473
2474 const Value *UseV = U->get();
2475 if (!UseV->getType()->isPointerTy())
2476 return 0;
2477
2478 // We need to follow common pointer manipulation uses to the accesses they
2479 // feed into. We can try to be smart to avoid looking through things we do not
2480 // like for now, e.g., non-inbounds GEPs.
2481 if (isa<CastInst>(I)) {
2482 TrackUse = true;
2483 return 0;
2484 }
2485
2486 if (isa<GetElementPtrInst>(I)) {
2487 TrackUse = true;
2488 return 0;
2489 }
2490
2491 Type *PtrTy = UseV->getType();
2492 const Function *F = I->getFunction();
2495 const DataLayout &DL = A.getInfoCache().getDL();
2496 if (const auto *CB = dyn_cast<CallBase>(I)) {
2497 if (CB->isBundleOperand(U)) {
2499 U, {Attribute::NonNull, Attribute::Dereferenceable})) {
2500 IsNonNull |=
2501 (RK.AttrKind == Attribute::NonNull || !NullPointerIsDefined);
2502 return RK.ArgValue;
2503 }
2504 return 0;
2505 }
2506
2507 if (CB->isCallee(U)) {
2508 IsNonNull |= !NullPointerIsDefined;
2509 return 0;
2510 }
2511
2512 unsigned ArgNo = CB->getArgOperandNo(U);
2513 IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo);
2514 // As long as we only use known information there is no need to track
2515 // dependences here.
2516 bool IsKnownNonNull;
2517 AA::hasAssumedIRAttr<Attribute::NonNull>(A, &QueryingAA, IRP,
2518 DepClassTy::NONE, IsKnownNonNull);
2519 IsNonNull |= IsKnownNonNull;
2520 auto *DerefAA =
2521 A.getAAFor<AADereferenceable>(QueryingAA, IRP, DepClassTy::NONE);
2522 return DerefAA ? DerefAA->getKnownDereferenceableBytes() : 0;
2523 }
2524
2525 std::optional<MemoryLocation> Loc = MemoryLocation::getOrNone(I);
2526 if (!Loc || Loc->Ptr != UseV || !Loc->Size.isPrecise() ||
2527 Loc->Size.isScalable() || I->isVolatile())
2528 return 0;
2529
2530 int64_t Offset;
2531 const Value *Base =
2532 getMinimalBaseOfPointer(A, QueryingAA, Loc->Ptr, Offset, DL);
2533 if (Base && Base == &AssociatedValue) {
2534 int64_t DerefBytes = Loc->Size.getValue() + Offset;
2535 IsNonNull |= !NullPointerIsDefined;
2536 return std::max(int64_t(0), DerefBytes);
2537 }
2538
2539 /// Corner case when an offset is 0.
2541 /*AllowNonInbounds*/ true);
2542 if (Base && Base == &AssociatedValue && Offset == 0) {
2543 int64_t DerefBytes = Loc->Size.getValue();
2544 IsNonNull |= !NullPointerIsDefined;
2545 return std::max(int64_t(0), DerefBytes);
2546 }
2547
2548 return 0;
2549}
2550
2551struct AANonNullImpl : AANonNull {
2552 AANonNullImpl(const IRPosition &IRP, Attributor &A) : AANonNull(IRP, A) {}
2553
2554 /// See AbstractAttribute::initialize(...).
2555 void initialize(Attributor &A) override {
2556 Value &V = *getAssociatedValue().stripPointerCasts();
2557 if (isa<ConstantPointerNull>(V)) {
2558 indicatePessimisticFixpoint();
2559 return;
2560 }
2561
2562 if (Instruction *CtxI = getCtxI())
2563 followUsesInMBEC(*this, A, getState(), *CtxI);
2564 }
2565
2566 /// See followUsesInMBEC
2567 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
2568 AANonNull::StateType &State) {
2569 bool IsNonNull = false;
2570 bool TrackUse = false;
2571 getKnownNonNullAndDerefBytesForUse(A, *this, getAssociatedValue(), U, I,
2572 IsNonNull, TrackUse);
2573 State.setKnown(IsNonNull);
2574 return TrackUse;
2575 }
2576
2577 /// See AbstractAttribute::getAsStr().
2578 const std::string getAsStr(Attributor *A) const override {
2579 return getAssumed() ? "nonnull" : "may-null";
2580 }
2581};
2582
2583/// NonNull attribute for a floating value.
2584struct AANonNullFloating : public AANonNullImpl {
2585 AANonNullFloating(const IRPosition &IRP, Attributor &A)
2586 : AANonNullImpl(IRP, A) {}
2587
2588 /// See AbstractAttribute::updateImpl(...).
2589 ChangeStatus updateImpl(Attributor &A) override {
2590 auto CheckIRP = [&](const IRPosition &IRP) {
2591 bool IsKnownNonNull;
2592 return AA::hasAssumedIRAttr<Attribute::NonNull>(
2593 A, *this, IRP, DepClassTy::OPTIONAL, IsKnownNonNull);
2594 };
2595
2596 bool Stripped;
2597 bool UsedAssumedInformation = false;
2598 Value *AssociatedValue = &getAssociatedValue();
2600 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
2601 AA::AnyScope, UsedAssumedInformation))
2602 Stripped = false;
2603 else
2604 Stripped =
2605 Values.size() != 1 || Values.front().getValue() != AssociatedValue;
2606
2607 if (!Stripped) {
2608 bool IsKnown;
2609 if (auto *PHI = dyn_cast<PHINode>(AssociatedValue))
2610 if (llvm::all_of(PHI->incoming_values(), [&](Value *Op) {
2611 return AA::hasAssumedIRAttr<Attribute::NonNull>(
2612 A, this, IRPosition::value(*Op), DepClassTy::OPTIONAL,
2613 IsKnown);
2614 }))
2615 return ChangeStatus::UNCHANGED;
2616 if (auto *Select = dyn_cast<SelectInst>(AssociatedValue))
2617 if (AA::hasAssumedIRAttr<Attribute::NonNull>(
2618 A, this, IRPosition::value(*Select->getFalseValue()),
2619 DepClassTy::OPTIONAL, IsKnown) &&
2620 AA::hasAssumedIRAttr<Attribute::NonNull>(
2621 A, this, IRPosition::value(*Select->getTrueValue()),
2622 DepClassTy::OPTIONAL, IsKnown))
2623 return ChangeStatus::UNCHANGED;
2624
2625 // If we haven't stripped anything we might still be able to use a
2626 // different AA, but only if the IRP changes. Effectively when we
2627 // interpret this not as a call site value but as a floating/argument
2628 // value.
2629 const IRPosition AVIRP = IRPosition::value(*AssociatedValue);
2630 if (AVIRP == getIRPosition() || !CheckIRP(AVIRP))
2631 return indicatePessimisticFixpoint();
2632 return ChangeStatus::UNCHANGED;
2633 }
2634
2635 for (const auto &VAC : Values)
2636 if (!CheckIRP(IRPosition::value(*VAC.getValue())))
2637 return indicatePessimisticFixpoint();
2638
2639 return ChangeStatus::UNCHANGED;
2640 }
2641
2642 /// See AbstractAttribute::trackStatistics()
2643 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
2644};
2645
2646/// NonNull attribute for function return value.
2647struct AANonNullReturned final
2648 : AAReturnedFromReturnedValues<AANonNull, AANonNull, AANonNull::StateType,
2649 false, AANonNull::IRAttributeKind, false> {
2650 AANonNullReturned(const IRPosition &IRP, Attributor &A)
2651 : AAReturnedFromReturnedValues<AANonNull, AANonNull, AANonNull::StateType,
2652 false, Attribute::NonNull, false>(IRP, A) {
2653 }
2654
2655 /// See AbstractAttribute::getAsStr().
2656 const std::string getAsStr(Attributor *A) const override {
2657 return getAssumed() ? "nonnull" : "may-null";
2658 }
2659
2660 /// See AbstractAttribute::trackStatistics()
2661 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
2662};
2663
2664/// NonNull attribute for function argument.
2665struct AANonNullArgument final
2666 : AAArgumentFromCallSiteArguments<AANonNull, AANonNullImpl> {
2667 AANonNullArgument(const IRPosition &IRP, Attributor &A)
2668 : AAArgumentFromCallSiteArguments<AANonNull, AANonNullImpl>(IRP, A) {}
2669
2670 /// See AbstractAttribute::trackStatistics()
2671 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nonnull) }
2672};
2673
2674struct AANonNullCallSiteArgument final : AANonNullFloating {
2675 AANonNullCallSiteArgument(const IRPosition &IRP, Attributor &A)
2676 : AANonNullFloating(IRP, A) {}
2677
2678 /// See AbstractAttribute::trackStatistics()
2679 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(nonnull) }
2680};
2681
2682/// NonNull attribute for a call site return position.
2683struct AANonNullCallSiteReturned final
2684 : AACalleeToCallSite<AANonNull, AANonNullImpl> {
2685 AANonNullCallSiteReturned(const IRPosition &IRP, Attributor &A)
2686 : AACalleeToCallSite<AANonNull, AANonNullImpl>(IRP, A) {}
2687
2688 /// See AbstractAttribute::trackStatistics()
2689 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(nonnull) }
2690};
2691} // namespace
2692
2693/// ------------------------ Must-Progress Attributes --------------------------
2694namespace {
2695struct AAMustProgressImpl : public AAMustProgress {
2696 AAMustProgressImpl(const IRPosition &IRP, Attributor &A)
2697 : AAMustProgress(IRP, A) {}
2698
2699 /// See AbstractAttribute::initialize(...).
2700 void initialize(Attributor &A) override {
2701 bool IsKnown;
2702 assert(!AA::hasAssumedIRAttr<Attribute::MustProgress>(
2703 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
2704 (void)IsKnown;
2705 }
2706
2707 /// See AbstractAttribute::getAsStr()
2708 const std::string getAsStr(Attributor *A) const override {
2709 return getAssumed() ? "mustprogress" : "may-not-progress";
2710 }
2711};
2712
2713struct AAMustProgressFunction final : AAMustProgressImpl {
2714 AAMustProgressFunction(const IRPosition &IRP, Attributor &A)
2715 : AAMustProgressImpl(IRP, A) {}
2716
2717 /// See AbstractAttribute::updateImpl(...).
2718 ChangeStatus updateImpl(Attributor &A) override {
2719 bool IsKnown;
2720 if (AA::hasAssumedIRAttr<Attribute::WillReturn>(
2721 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnown)) {
2722 if (IsKnown)
2723 return indicateOptimisticFixpoint();
2724 return ChangeStatus::UNCHANGED;
2725 }
2726
2727 auto CheckForMustProgress = [&](AbstractCallSite ACS) {
2728 IRPosition IPos = IRPosition::callsite_function(*ACS.getInstruction());
2729 bool IsKnownMustProgress;
2730 return AA::hasAssumedIRAttr<Attribute::MustProgress>(
2731 A, this, IPos, DepClassTy::REQUIRED, IsKnownMustProgress,
2732 /* IgnoreSubsumingPositions */ true);
2733 };
2734
2735 bool AllCallSitesKnown = true;
2736 if (!A.checkForAllCallSites(CheckForMustProgress, *this,
2737 /* RequireAllCallSites */ true,
2738 AllCallSitesKnown))
2739 return indicatePessimisticFixpoint();
2740
2741 return ChangeStatus::UNCHANGED;
2742 }
2743
2744 /// See AbstractAttribute::trackStatistics()
2745 void trackStatistics() const override {
2746 STATS_DECLTRACK_FN_ATTR(mustprogress)
2747 }
2748};
2749
2750/// MustProgress attribute deduction for a call sites.
2751struct AAMustProgressCallSite final : AAMustProgressImpl {
2752 AAMustProgressCallSite(const IRPosition &IRP, Attributor &A)
2753 : AAMustProgressImpl(IRP, A) {}
2754
2755 /// See AbstractAttribute::updateImpl(...).
2756 ChangeStatus updateImpl(Attributor &A) override {
2757 // TODO: Once we have call site specific value information we can provide
2758 // call site specific liveness information and then it makes
2759 // sense to specialize attributes for call sites arguments instead of
2760 // redirecting requests to the callee argument.
2761 const IRPosition &FnPos = IRPosition::function(*getAnchorScope());
2762 bool IsKnownMustProgress;
2763 if (!AA::hasAssumedIRAttr<Attribute::MustProgress>(
2764 A, this, FnPos, DepClassTy::REQUIRED, IsKnownMustProgress))
2765 return indicatePessimisticFixpoint();
2766 return ChangeStatus::UNCHANGED;
2767 }
2768
2769 /// See AbstractAttribute::trackStatistics()
2770 void trackStatistics() const override {
2771 STATS_DECLTRACK_CS_ATTR(mustprogress);
2772 }
2773};
2774} // namespace
2775
2776/// ------------------------ No-Recurse Attributes ----------------------------
2777
2778namespace {
2779struct AANoRecurseImpl : public AANoRecurse {
2780 AANoRecurseImpl(const IRPosition &IRP, Attributor &A) : AANoRecurse(IRP, A) {}
2781
2782 /// See AbstractAttribute::initialize(...).
2783 void initialize(Attributor &A) override {
2784 bool IsKnown;
2785 assert(!AA::hasAssumedIRAttr<Attribute::NoRecurse>(
2786 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
2787 (void)IsKnown;
2788 }
2789
2790 /// See AbstractAttribute::getAsStr()
2791 const std::string getAsStr(Attributor *A) const override {
2792 return getAssumed() ? "norecurse" : "may-recurse";
2793 }
2794};
2795
2796struct AANoRecurseFunction final : AANoRecurseImpl {
2797 AANoRecurseFunction(const IRPosition &IRP, Attributor &A)
2798 : AANoRecurseImpl(IRP, A) {}
2799
2800 /// See AbstractAttribute::updateImpl(...).
2801 ChangeStatus updateImpl(Attributor &A) override {
2802
2803 // If all live call sites are known to be no-recurse, we are as well.
2804 auto CallSitePred = [&](AbstractCallSite ACS) {
2805 bool IsKnownNoRecurse;
2806 if (!AA::hasAssumedIRAttr<Attribute::NoRecurse>(
2807 A, this,
2808 IRPosition::function(*ACS.getInstruction()->getFunction()),
2809 DepClassTy::NONE, IsKnownNoRecurse))
2810 return false;
2811 return IsKnownNoRecurse;
2812 };
2813 bool UsedAssumedInformation = false;
2814 if (A.checkForAllCallSites(CallSitePred, *this, true,
2815 UsedAssumedInformation)) {
2816 // If we know all call sites and all are known no-recurse, we are done.
2817 // If all known call sites, which might not be all that exist, are known
2818 // to be no-recurse, we are not done but we can continue to assume
2819 // no-recurse. If one of the call sites we have not visited will become
2820 // live, another update is triggered.
2821 if (!UsedAssumedInformation)
2822 indicateOptimisticFixpoint();
2823 return ChangeStatus::UNCHANGED;
2824 }
2825
2826 const AAInterFnReachability *EdgeReachability =
2827 A.getAAFor<AAInterFnReachability>(*this, getIRPosition(),
2828 DepClassTy::REQUIRED);
2829 if (EdgeReachability && EdgeReachability->canReach(A, *getAnchorScope()))
2830 return indicatePessimisticFixpoint();
2831 return ChangeStatus::UNCHANGED;
2832 }
2833
2834 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(norecurse) }
2835};
2836
2837/// NoRecurse attribute deduction for a call sites.
2838struct AANoRecurseCallSite final
2839 : AACalleeToCallSite<AANoRecurse, AANoRecurseImpl> {
2840 AANoRecurseCallSite(const IRPosition &IRP, Attributor &A)
2841 : AACalleeToCallSite<AANoRecurse, AANoRecurseImpl>(IRP, A) {}
2842
2843 /// See AbstractAttribute::trackStatistics()
2844 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(norecurse); }
2845};
2846} // namespace
2847
2848/// ------------------------ No-Convergent Attribute --------------------------
2849
2850namespace {
2851struct AANonConvergentImpl : public AANonConvergent {
2852 AANonConvergentImpl(const IRPosition &IRP, Attributor &A)
2853 : AANonConvergent(IRP, A) {}
2854
2855 /// See AbstractAttribute::getAsStr()
2856 const std::string getAsStr(Attributor *A) const override {
2857 return getAssumed() ? "non-convergent" : "may-be-convergent";
2858 }
2859};
2860
2861struct AANonConvergentFunction final : AANonConvergentImpl {
2862 AANonConvergentFunction(const IRPosition &IRP, Attributor &A)
2863 : AANonConvergentImpl(IRP, A) {}
2864
2865 /// See AbstractAttribute::updateImpl(...).
2866 ChangeStatus updateImpl(Attributor &A) override {
2867 // If all function calls are known to not be convergent, we are not
2868 // convergent.
2869 auto CalleeIsNotConvergent = [&](Instruction &Inst) {
2870 CallBase &CB = cast<CallBase>(Inst);
2871 auto *Callee = dyn_cast_if_present<Function>(CB.getCalledOperand());
2872 if (!Callee || Callee->isIntrinsic()) {
2873 return false;
2874 }
2875 if (Callee->isDeclaration()) {
2876 return !Callee->hasFnAttribute(Attribute::Convergent);
2877 }
2878 const auto *ConvergentAA = A.getAAFor<AANonConvergent>(
2879 *this, IRPosition::function(*Callee), DepClassTy::REQUIRED);
2880 return ConvergentAA && ConvergentAA->isAssumedNotConvergent();
2881 };
2882
2883 bool UsedAssumedInformation = false;
2884 if (!A.checkForAllCallLikeInstructions(CalleeIsNotConvergent, *this,
2885 UsedAssumedInformation)) {
2886 return indicatePessimisticFixpoint();
2887 }
2888 return ChangeStatus::UNCHANGED;
2889 }
2890
2891 ChangeStatus manifest(Attributor &A) override {
2892 if (isKnownNotConvergent() &&
2893 A.hasAttr(getIRPosition(), Attribute::Convergent)) {
2894 A.removeAttrs(getIRPosition(), {Attribute::Convergent});
2895 return ChangeStatus::CHANGED;
2896 }
2897 return ChangeStatus::UNCHANGED;
2898 }
2899
2900 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(convergent) }
2901};
2902} // namespace
2903
2904/// -------------------- Undefined-Behavior Attributes ------------------------
2905
2906namespace {
2907struct AAUndefinedBehaviorImpl : public AAUndefinedBehavior {
2908 AAUndefinedBehaviorImpl(const IRPosition &IRP, Attributor &A)
2909 : AAUndefinedBehavior(IRP, A) {}
2910
2911 /// See AbstractAttribute::updateImpl(...).
2912 // through a pointer (i.e. also branches etc.)
2913 ChangeStatus updateImpl(Attributor &A) override {
2914 const size_t UBPrevSize = KnownUBInsts.size();
2915 const size_t NoUBPrevSize = AssumedNoUBInsts.size();
2916
2917 auto InspectMemAccessInstForUB = [&](Instruction &I) {
2918 // Lang ref now states volatile store is not UB, let's skip them.
2919 if (I.isVolatile() && I.mayWriteToMemory())
2920 return true;
2921
2922 // Skip instructions that are already saved.
2923 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
2924 return true;
2925
2926 // If we reach here, we know we have an instruction
2927 // that accesses memory through a pointer operand,
2928 // for which getPointerOperand() should give it to us.
2929 Value *PtrOp =
2930 const_cast<Value *>(getPointerOperand(&I, /* AllowVolatile */ true));
2931 assert(PtrOp &&
2932 "Expected pointer operand of memory accessing instruction");
2933
2934 // Either we stopped and the appropriate action was taken,
2935 // or we got back a simplified value to continue.
2936 std::optional<Value *> SimplifiedPtrOp =
2937 stopOnUndefOrAssumed(A, PtrOp, &I);
2938 if (!SimplifiedPtrOp || !*SimplifiedPtrOp)
2939 return true;
2940 const Value *PtrOpVal = *SimplifiedPtrOp;
2941
2942 // A memory access through a pointer is considered UB
2943 // only if the pointer has constant null value.
2944 // TODO: Expand it to not only check constant values.
2945 if (!isa<ConstantPointerNull>(PtrOpVal)) {
2946 AssumedNoUBInsts.insert(&I);
2947 return true;
2948 }
2949 const Type *PtrTy = PtrOpVal->getType();
2950
2951 // Because we only consider instructions inside functions,
2952 // assume that a parent function exists.
2953 const Function *F = I.getFunction();
2954
2955 // A memory access using constant null pointer is only considered UB
2956 // if null pointer is _not_ defined for the target platform.
2958 AssumedNoUBInsts.insert(&I);
2959 else
2960 KnownUBInsts.insert(&I);
2961 return true;
2962 };
2963
2964 auto InspectBrInstForUB = [&](Instruction &I) {
2965 // A conditional branch instruction is considered UB if it has `undef`
2966 // condition.
2967
2968 // Skip instructions that are already saved.
2969 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
2970 return true;
2971
2972 // We know we have a branch instruction.
2973 auto *BrInst = cast<BranchInst>(&I);
2974
2975 // Unconditional branches are never considered UB.
2976 if (BrInst->isUnconditional())
2977 return true;
2978
2979 // Either we stopped and the appropriate action was taken,
2980 // or we got back a simplified value to continue.
2981 std::optional<Value *> SimplifiedCond =
2982 stopOnUndefOrAssumed(A, BrInst->getCondition(), BrInst);
2983 if (!SimplifiedCond || !*SimplifiedCond)
2984 return true;
2985 AssumedNoUBInsts.insert(&I);
2986 return true;
2987 };
2988
2989 auto InspectCallSiteForUB = [&](Instruction &I) {
2990 // Check whether a callsite always cause UB or not
2991
2992 // Skip instructions that are already saved.
2993 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
2994 return true;
2995
2996 // Check nonnull and noundef argument attribute violation for each
2997 // callsite.
2998 CallBase &CB = cast<CallBase>(I);
2999 auto *Callee = dyn_cast_if_present<Function>(CB.getCalledOperand());
3000 if (!Callee)
3001 return true;
3002 for (unsigned idx = 0; idx < CB.arg_size(); idx++) {
3003 // If current argument is known to be simplified to null pointer and the
3004 // corresponding argument position is known to have nonnull attribute,
3005 // the argument is poison. Furthermore, if the argument is poison and
3006 // the position is known to have noundef attriubte, this callsite is
3007 // considered UB.
3008 if (idx >= Callee->arg_size())
3009 break;
3010 Value *ArgVal = CB.getArgOperand(idx);
3011 if (!ArgVal)
3012 continue;
3013 // Here, we handle three cases.
3014 // (1) Not having a value means it is dead. (we can replace the value
3015 // with undef)
3016 // (2) Simplified to undef. The argument violate noundef attriubte.
3017 // (3) Simplified to null pointer where known to be nonnull.
3018 // The argument is a poison value and violate noundef attribute.
3019 IRPosition CalleeArgumentIRP = IRPosition::callsite_argument(CB, idx);
3020 bool IsKnownNoUndef;
3021 AA::hasAssumedIRAttr<Attribute::NoUndef>(
3022 A, this, CalleeArgumentIRP, DepClassTy::NONE, IsKnownNoUndef);
3023 if (!IsKnownNoUndef)
3024 continue;
3025 bool UsedAssumedInformation = false;
3026 std::optional<Value *> SimplifiedVal =
3027 A.getAssumedSimplified(IRPosition::value(*ArgVal), *this,
3028 UsedAssumedInformation, AA::Interprocedural);
3029 if (UsedAssumedInformation)
3030 continue;
3031 if (SimplifiedVal && !*SimplifiedVal)
3032 return true;
3033 if (!SimplifiedVal || isa<UndefValue>(**SimplifiedVal)) {
3034 KnownUBInsts.insert(&I);
3035 continue;
3036 }
3037 if (!ArgVal->getType()->isPointerTy() ||
3038 !isa<ConstantPointerNull>(**SimplifiedVal))
3039 continue;
3040 bool IsKnownNonNull;
3041 AA::hasAssumedIRAttr<Attribute::NonNull>(
3042 A, this, CalleeArgumentIRP, DepClassTy::NONE, IsKnownNonNull);
3043 if (IsKnownNonNull)
3044 KnownUBInsts.insert(&I);
3045 }
3046 return true;
3047 };
3048
3049 auto InspectReturnInstForUB = [&](Instruction &I) {
3050 auto &RI = cast<ReturnInst>(I);
3051 // Either we stopped and the appropriate action was taken,
3052 // or we got back a simplified return value to continue.
3053 std::optional<Value *> SimplifiedRetValue =
3054 stopOnUndefOrAssumed(A, RI.getReturnValue(), &I);
3055 if (!SimplifiedRetValue || !*SimplifiedRetValue)
3056 return true;
3057
3058 // Check if a return instruction always cause UB or not
3059 // Note: It is guaranteed that the returned position of the anchor
3060 // scope has noundef attribute when this is called.
3061 // We also ensure the return position is not "assumed dead"
3062 // because the returned value was then potentially simplified to
3063 // `undef` in AAReturnedValues without removing the `noundef`
3064 // attribute yet.
3065
3066 // When the returned position has noundef attriubte, UB occurs in the
3067 // following cases.
3068 // (1) Returned value is known to be undef.
3069 // (2) The value is known to be a null pointer and the returned
3070 // position has nonnull attribute (because the returned value is
3071 // poison).
3072 if (isa<ConstantPointerNull>(*SimplifiedRetValue)) {
3073 bool IsKnownNonNull;
3074 AA::hasAssumedIRAttr<Attribute::NonNull>(
3075 A, this, IRPosition::returned(*getAnchorScope()), DepClassTy::NONE,
3076 IsKnownNonNull);
3077 if (IsKnownNonNull)
3078 KnownUBInsts.insert(&I);
3079 }
3080
3081 return true;
3082 };
3083
3084 bool UsedAssumedInformation = false;
3085 A.checkForAllInstructions(InspectMemAccessInstForUB, *this,
3086 {Instruction::Load, Instruction::Store,
3087 Instruction::AtomicCmpXchg,
3088 Instruction::AtomicRMW},
3089 UsedAssumedInformation,
3090 /* CheckBBLivenessOnly */ true);
3091 A.checkForAllInstructions(InspectBrInstForUB, *this, {Instruction::Br},
3092 UsedAssumedInformation,
3093 /* CheckBBLivenessOnly */ true);
3094 A.checkForAllCallLikeInstructions(InspectCallSiteForUB, *this,
3095 UsedAssumedInformation);
3096
3097 // If the returned position of the anchor scope has noundef attriubte, check
3098 // all returned instructions.
3099 if (!getAnchorScope()->getReturnType()->isVoidTy()) {
3100 const IRPosition &ReturnIRP = IRPosition::returned(*getAnchorScope());
3101 if (!A.isAssumedDead(ReturnIRP, this, nullptr, UsedAssumedInformation)) {
3102 bool IsKnownNoUndef;
3103 AA::hasAssumedIRAttr<Attribute::NoUndef>(
3104 A, this, ReturnIRP, DepClassTy::NONE, IsKnownNoUndef);
3105 if (IsKnownNoUndef)
3106 A.checkForAllInstructions(InspectReturnInstForUB, *this,
3107 {Instruction::Ret}, UsedAssumedInformation,
3108 /* CheckBBLivenessOnly */ true);
3109 }
3110 }
3111
3112 if (NoUBPrevSize != AssumedNoUBInsts.size() ||
3113 UBPrevSize != KnownUBInsts.size())
3114 return ChangeStatus::CHANGED;
3115 return ChangeStatus::UNCHANGED;
3116 }
3117
3118 bool isKnownToCauseUB(Instruction *I) const override {
3119 return KnownUBInsts.count(I);
3120 }
3121
3122 bool isAssumedToCauseUB(Instruction *I) const override {
3123 // In simple words, if an instruction is not in the assumed to _not_
3124 // cause UB, then it is assumed UB (that includes those
3125 // in the KnownUBInsts set). The rest is boilerplate
3126 // is to ensure that it is one of the instructions we test
3127 // for UB.
3128
3129 switch (I->getOpcode()) {
3130 case Instruction::Load:
3131 case Instruction::Store:
3132 case Instruction::AtomicCmpXchg:
3133 case Instruction::AtomicRMW:
3134 return !AssumedNoUBInsts.count(I);
3135 case Instruction::Br: {
3136 auto *BrInst = cast<BranchInst>(I);
3137 if (BrInst->isUnconditional())
3138 return false;
3139 return !AssumedNoUBInsts.count(I);
3140 } break;
3141 default:
3142 return false;
3143 }
3144 return false;
3145 }
3146
3147 ChangeStatus manifest(Attributor &A) override {
3148 if (KnownUBInsts.empty())
3149 return ChangeStatus::UNCHANGED;
3150 for (Instruction *I : KnownUBInsts)
3151 A.changeToUnreachableAfterManifest(I);
3152 return ChangeStatus::CHANGED;
3153 }
3154
3155 /// See AbstractAttribute::getAsStr()
3156 const std::string getAsStr(Attributor *A) const override {
3157 return getAssumed() ? "undefined-behavior" : "no-ub";
3158 }
3159
3160 /// Note: The correctness of this analysis depends on the fact that the
3161 /// following 2 sets will stop changing after some point.
3162 /// "Change" here means that their size changes.
3163 /// The size of each set is monotonically increasing
3164 /// (we only add items to them) and it is upper bounded by the number of
3165 /// instructions in the processed function (we can never save more
3166 /// elements in either set than this number). Hence, at some point,
3167 /// they will stop increasing.
3168 /// Consequently, at some point, both sets will have stopped
3169 /// changing, effectively making the analysis reach a fixpoint.
3170
3171 /// Note: These 2 sets are disjoint and an instruction can be considered
3172 /// one of 3 things:
3173 /// 1) Known to cause UB (AAUndefinedBehavior could prove it) and put it in
3174 /// the KnownUBInsts set.
3175 /// 2) Assumed to cause UB (in every updateImpl, AAUndefinedBehavior
3176 /// has a reason to assume it).
3177 /// 3) Assumed to not cause UB. very other instruction - AAUndefinedBehavior
3178 /// could not find a reason to assume or prove that it can cause UB,
3179 /// hence it assumes it doesn't. We have a set for these instructions
3180 /// so that we don't reprocess them in every update.
3181 /// Note however that instructions in this set may cause UB.
3182
3183protected:
3184 /// A set of all live instructions _known_ to cause UB.
3185 SmallPtrSet<Instruction *, 8> KnownUBInsts;
3186
3187private:
3188 /// A set of all the (live) instructions that are assumed to _not_ cause UB.
3189 SmallPtrSet<Instruction *, 8> AssumedNoUBInsts;
3190
3191 // Should be called on updates in which if we're processing an instruction
3192 // \p I that depends on a value \p V, one of the following has to happen:
3193 // - If the value is assumed, then stop.
3194 // - If the value is known but undef, then consider it UB.
3195 // - Otherwise, do specific processing with the simplified value.
3196 // We return std::nullopt in the first 2 cases to signify that an appropriate
3197 // action was taken and the caller should stop.
3198 // Otherwise, we return the simplified value that the caller should
3199 // use for specific processing.
3200 std::optional<Value *> stopOnUndefOrAssumed(Attributor &A, Value *V,
3201 Instruction *I) {
3202 bool UsedAssumedInformation = false;
3203 std::optional<Value *> SimplifiedV =
3204 A.getAssumedSimplified(IRPosition::value(*V), *this,
3205 UsedAssumedInformation, AA::Interprocedural);
3206 if (!UsedAssumedInformation) {
3207 // Don't depend on assumed values.
3208 if (!SimplifiedV) {
3209 // If it is known (which we tested above) but it doesn't have a value,
3210 // then we can assume `undef` and hence the instruction is UB.
3211 KnownUBInsts.insert(I);
3212 return std::nullopt;
3213 }
3214 if (!*SimplifiedV)
3215 return nullptr;
3216 V = *SimplifiedV;
3217 }
3218 if (isa<UndefValue>(V)) {
3219 KnownUBInsts.insert(I);
3220 return std::nullopt;
3221 }
3222 return V;
3223 }
3224};
3225
3226struct AAUndefinedBehaviorFunction final : AAUndefinedBehaviorImpl {
3227 AAUndefinedBehaviorFunction(const IRPosition &IRP, Attributor &A)
3228 : AAUndefinedBehaviorImpl(IRP, A) {}
3229
3230 /// See AbstractAttribute::trackStatistics()
3231 void trackStatistics() const override {
3232 STATS_DECL(UndefinedBehaviorInstruction, Instruction,
3233 "Number of instructions known to have UB");
3234 BUILD_STAT_NAME(UndefinedBehaviorInstruction, Instruction) +=
3235 KnownUBInsts.size();
3236 }
3237};
3238} // namespace
3239
3240/// ------------------------ Will-Return Attributes ----------------------------
3241
3242namespace {
3243// Helper function that checks whether a function has any cycle which we don't
3244// know if it is bounded or not.
3245// Loops with maximum trip count are considered bounded, any other cycle not.
3246static bool mayContainUnboundedCycle(Function &F, Attributor &A) {
3247 ScalarEvolution *SE =
3248 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(F);
3249 LoopInfo *LI = A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(F);
3250 // If either SCEV or LoopInfo is not available for the function then we assume
3251 // any cycle to be unbounded cycle.
3252 // We use scc_iterator which uses Tarjan algorithm to find all the maximal
3253 // SCCs.To detect if there's a cycle, we only need to find the maximal ones.
3254 if (!SE || !LI) {
3255 for (scc_iterator<Function *> SCCI = scc_begin(&F); !SCCI.isAtEnd(); ++SCCI)
3256 if (SCCI.hasCycle())
3257 return true;
3258 return false;
3259 }
3260
3261 // If there's irreducible control, the function may contain non-loop cycles.
3263 return true;
3264
3265 // Any loop that does not have a max trip count is considered unbounded cycle.
3266 for (auto *L : LI->getLoopsInPreorder()) {
3267 if (!SE->getSmallConstantMaxTripCount(L))
3268 return true;
3269 }
3270 return false;
3271}
3272
3273struct AAWillReturnImpl : public AAWillReturn {
3274 AAWillReturnImpl(const IRPosition &IRP, Attributor &A)
3275 : AAWillReturn(IRP, A) {}
3276
3277 /// See AbstractAttribute::initialize(...).
3278 void initialize(Attributor &A) override {
3279 bool IsKnown;
3280 assert(!AA::hasAssumedIRAttr<Attribute::WillReturn>(
3281 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
3282 (void)IsKnown;
3283 }
3284
3285 /// Check for `mustprogress` and `readonly` as they imply `willreturn`.
3286 bool isImpliedByMustprogressAndReadonly(Attributor &A, bool KnownOnly) {
3287 if (!A.hasAttr(getIRPosition(), {Attribute::MustProgress}))
3288 return false;
3289
3290 bool IsKnown;
3291 if (AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown))
3292 return IsKnown || !KnownOnly;
3293 return false;
3294 }
3295
3296 /// See AbstractAttribute::updateImpl(...).
3297 ChangeStatus updateImpl(Attributor &A) override {
3298 if (isImpliedByMustprogressAndReadonly(A, /* KnownOnly */ false))
3299 return ChangeStatus::UNCHANGED;
3300
3301 auto CheckForWillReturn = [&](Instruction &I) {
3302 IRPosition IPos = IRPosition::callsite_function(cast<CallBase>(I));
3303 bool IsKnown;
3304 if (AA::hasAssumedIRAttr<Attribute::WillReturn>(
3305 A, this, IPos, DepClassTy::REQUIRED, IsKnown)) {
3306 if (IsKnown)
3307 return true;
3308 } else {
3309 return false;
3310 }
3311 bool IsKnownNoRecurse;
3312 return AA::hasAssumedIRAttr<Attribute::NoRecurse>(
3313 A, this, IPos, DepClassTy::REQUIRED, IsKnownNoRecurse);
3314 };
3315
3316 bool UsedAssumedInformation = false;
3317 if (!A.checkForAllCallLikeInstructions(CheckForWillReturn, *this,
3318 UsedAssumedInformation))
3319 return indicatePessimisticFixpoint();
3320
3321 return ChangeStatus::UNCHANGED;
3322 }
3323
3324 /// See AbstractAttribute::getAsStr()
3325 const std::string getAsStr(Attributor *A) const override {
3326 return getAssumed() ? "willreturn" : "may-noreturn";
3327 }
3328};
3329
3330struct AAWillReturnFunction final : AAWillReturnImpl {
3331 AAWillReturnFunction(const IRPosition &IRP, Attributor &A)
3332 : AAWillReturnImpl(IRP, A) {}
3333
3334 /// See AbstractAttribute::initialize(...).
3335 void initialize(Attributor &A) override {
3336 AAWillReturnImpl::initialize(A);
3337
3338 Function *F = getAnchorScope();
3339 assert(F && "Did expect an anchor function");
3340 if (F->isDeclaration() || mayContainUnboundedCycle(*F, A))
3341 indicatePessimisticFixpoint();
3342 }
3343
3344 /// See AbstractAttribute::trackStatistics()
3345 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(willreturn) }
3346};
3347
3348/// WillReturn attribute deduction for a call sites.
3349struct AAWillReturnCallSite final
3350 : AACalleeToCallSite<AAWillReturn, AAWillReturnImpl> {
3351 AAWillReturnCallSite(const IRPosition &IRP, Attributor &A)
3352 : AACalleeToCallSite<AAWillReturn, AAWillReturnImpl>(IRP, A) {}
3353
3354 /// See AbstractAttribute::updateImpl(...).
3355 ChangeStatus updateImpl(Attributor &A) override {
3356 if (isImpliedByMustprogressAndReadonly(A, /* KnownOnly */ false))
3357 return ChangeStatus::UNCHANGED;
3358
3359 return AACalleeToCallSite::updateImpl(A);
3360 }
3361
3362 /// See AbstractAttribute::trackStatistics()
3363 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(willreturn); }
3364};
3365} // namespace
3366
3367/// -------------------AAIntraFnReachability Attribute--------------------------
3368
3369/// All information associated with a reachability query. This boilerplate code
3370/// is used by both AAIntraFnReachability and AAInterFnReachability, with
3371/// different \p ToTy values.
3372template <typename ToTy> struct ReachabilityQueryInfo {
3373 enum class Reachable {
3374 No,
3375 Yes,
3376 };
3377
3378 /// Start here,
3379 const Instruction *From = nullptr;
3380 /// reach this place,
3381 const ToTy *To = nullptr;
3382 /// without going through any of these instructions,
3383 const AA::InstExclusionSetTy *ExclusionSet = nullptr;
3384 /// and remember if it worked:
3385 Reachable Result = Reachable::No;
3386
3387 /// Precomputed hash for this RQI.
3388 unsigned Hash = 0;
3389
3390 unsigned computeHashValue() const {
3391 assert(Hash == 0 && "Computed hash twice!");
3394 return const_cast<ReachabilityQueryInfo<ToTy> *>(this)->Hash =
3395 detail::combineHashValue(PairDMI ::getHashValue({From, To}),
3396 InstSetDMI::getHashValue(ExclusionSet));
3397 }
3398
3400 : From(From), To(To) {}
3401
3402 /// Constructor replacement to ensure unique and stable sets are used for the
3403 /// cache.
3405 const AA::InstExclusionSetTy *ES, bool MakeUnique)
3406 : From(&From), To(&To), ExclusionSet(ES) {
3407
3408 if (!ES || ES->empty()) {
3409 ExclusionSet = nullptr;
3410 } else if (MakeUnique) {
3411 ExclusionSet = A.getInfoCache().getOrCreateUniqueBlockExecutionSet(ES);
3412 }
3413 }
3414
3416 : From(RQI.From), To(RQI.To), ExclusionSet(RQI.ExclusionSet) {}
3417};
3418
3419namespace llvm {
3420template <typename ToTy> struct DenseMapInfo<ReachabilityQueryInfo<ToTy> *> {
3423
3426
3427 static inline ReachabilityQueryInfo<ToTy> *getEmptyKey() { return &EmptyKey; }
3429 return &TombstoneKey;
3430 }
3431 static unsigned getHashValue(const ReachabilityQueryInfo<ToTy> *RQI) {
3432 return RQI->Hash ? RQI->Hash : RQI->computeHashValue();
3433 }
3436 if (!PairDMI::isEqual({LHS->From, LHS->To}, {RHS->From, RHS->To}))
3437 return false;
3438 return InstSetDMI::isEqual(LHS->ExclusionSet, RHS->ExclusionSet);
3439 }
3440};
3441
3442#define DefineKeys(ToTy) \
3443 template <> \
3444 ReachabilityQueryInfo<ToTy> \
3445 DenseMapInfo<ReachabilityQueryInfo<ToTy> *>::EmptyKey = \
3446 ReachabilityQueryInfo<ToTy>( \
3447 DenseMapInfo<const Instruction *>::getEmptyKey(), \
3448 DenseMapInfo<const ToTy *>::getEmptyKey()); \
3449 template <> \
3450 ReachabilityQueryInfo<ToTy> \
3451 DenseMapInfo<ReachabilityQueryInfo<ToTy> *>::TombstoneKey = \
3452 ReachabilityQueryInfo<ToTy>( \
3453 DenseMapInfo<const Instruction *>::getTombstoneKey(), \
3454 DenseMapInfo<const ToTy *>::getTombstoneKey());
3455
3457#undef DefineKeys
3458
3459} // namespace llvm
3460
3461namespace {
3462
3463template <typename BaseTy, typename ToTy>
3464struct CachedReachabilityAA : public BaseTy {
3465 using RQITy = ReachabilityQueryInfo<ToTy>;
3466
3467 CachedReachabilityAA(const IRPosition &IRP, Attributor &A) : BaseTy(IRP, A) {}
3468
3469 /// See AbstractAttribute::isQueryAA.
3470 bool isQueryAA() const override { return true; }
3471
3472 /// See AbstractAttribute::updateImpl(...).
3473 ChangeStatus updateImpl(Attributor &A) override {
3474 ChangeStatus Changed = ChangeStatus::UNCHANGED;
3475 for (unsigned u = 0, e = QueryVector.size(); u < e; ++u) {
3476 RQITy *RQI = QueryVector[u];
3477 if (RQI->Result == RQITy::Reachable::No &&
3478 isReachableImpl(A, *RQI, /*IsTemporaryRQI=*/false))
3479 Changed = ChangeStatus::CHANGED;
3480 }
3481 return Changed;
3482 }
3483
3484 virtual bool isReachableImpl(Attributor &A, RQITy &RQI,
3485 bool IsTemporaryRQI) = 0;
3486
3487 bool rememberResult(Attributor &A, typename RQITy::Reachable Result,
3488 RQITy &RQI, bool UsedExclusionSet, bool IsTemporaryRQI) {
3489 RQI.Result = Result;
3490
3491 // Remove the temporary RQI from the cache.
3492 if (IsTemporaryRQI)
3493 QueryCache.erase(&RQI);
3494
3495 // Insert a plain RQI (w/o exclusion set) if that makes sense. Two options:
3496 // 1) If it is reachable, it doesn't matter if we have an exclusion set for
3497 // this query. 2) We did not use the exclusion set, potentially because
3498 // there is none.
3499 if (Result == RQITy::Reachable::Yes || !UsedExclusionSet) {
3500 RQITy PlainRQI(RQI.From, RQI.To);
3501 if (!QueryCache.count(&PlainRQI)) {
3502 RQITy *RQIPtr = new (A.Allocator) RQITy(RQI.From, RQI.To);
3503 RQIPtr->Result = Result;
3504 QueryVector.push_back(RQIPtr);
3505 QueryCache.insert(RQIPtr);
3506 }
3507 }
3508
3509 // Check if we need to insert a new permanent RQI with the exclusion set.
3510 if (IsTemporaryRQI && Result != RQITy::Reachable::Yes && UsedExclusionSet) {
3511 assert((!RQI.ExclusionSet || !RQI.ExclusionSet->empty()) &&
3512 "Did not expect empty set!");
3513 RQITy *RQIPtr = new (A.Allocator)
3514 RQITy(A, *RQI.From, *RQI.To, RQI.ExclusionSet, true);
3515 assert(RQIPtr->Result == RQITy::Reachable::No && "Already reachable?");
3516 RQIPtr->Result = Result;
3517 assert(!QueryCache.count(RQIPtr));
3518 QueryVector.push_back(RQIPtr);
3519 QueryCache.insert(RQIPtr);
3520 }
3521
3522 if (Result == RQITy::Reachable::No && IsTemporaryRQI)
3523 A.registerForUpdate(*this);
3524 return Result == RQITy::Reachable::Yes;
3525 }
3526
3527 const std::string getAsStr(Attributor *A) const override {
3528 // TODO: Return the number of reachable queries.
3529 return "#queries(" + std::to_string(QueryVector.size()) + ")";
3530 }
3531
3532 bool checkQueryCache(Attributor &A, RQITy &StackRQI,
3533 typename RQITy::Reachable &Result) {
3534 if (!this->getState().isValidState()) {
3535 Result = RQITy::Reachable::Yes;
3536 return true;
3537 }
3538
3539 // If we have an exclusion set we might be able to find our answer by
3540 // ignoring it first.
3541 if (StackRQI.ExclusionSet) {
3542 RQITy PlainRQI(StackRQI.From, StackRQI.To);
3543 auto It = QueryCache.find(&PlainRQI);
3544 if (It != QueryCache.end() && (*It)->Result == RQITy::Reachable::No) {
3545 Result = RQITy::Reachable::No;
3546 return true;
3547 }
3548 }
3549
3550 auto It = QueryCache.find(&StackRQI);
3551 if (It != QueryCache.end()) {
3552 Result = (*It)->Result;
3553 return true;
3554 }
3555
3556 // Insert a temporary for recursive queries. We will replace it with a
3557 // permanent entry later.
3558 QueryCache.insert(&StackRQI);
3559 return false;
3560 }
3561
3562private:
3563 SmallVector<RQITy *> QueryVector;
3564 DenseSet<RQITy *> QueryCache;
3565};
3566
3567struct AAIntraFnReachabilityFunction final
3568 : public CachedReachabilityAA<AAIntraFnReachability, Instruction> {
3569 using Base = CachedReachabilityAA<AAIntraFnReachability, Instruction>;
3570 AAIntraFnReachabilityFunction(const IRPosition &IRP, Attributor &A)
3571 : Base(IRP, A) {
3572 DT = A.getInfoCache().getAnalysisResultForFunction<DominatorTreeAnalysis>(
3573 *IRP.getAssociatedFunction());
3574 }
3575
3576 bool isAssumedReachable(
3577 Attributor &A, const Instruction &From, const Instruction &To,
3578 const AA::InstExclusionSetTy *ExclusionSet) const override {
3579 auto *NonConstThis = const_cast<AAIntraFnReachabilityFunction *>(this);
3580 if (&From == &To)
3581 return true;
3582
3583 RQITy StackRQI(A, From, To, ExclusionSet, false);
3584 typename RQITy::Reachable Result;
3585 if (!NonConstThis->checkQueryCache(A, StackRQI, Result))
3586 return NonConstThis->isReachableImpl(A, StackRQI,
3587 /*IsTemporaryRQI=*/true);
3588 return Result == RQITy::Reachable::Yes;
3589 }
3590
3591 ChangeStatus updateImpl(Attributor &A) override {
3592 // We only depend on liveness. DeadEdges is all we care about, check if any
3593 // of them changed.
3594 auto *LivenessAA =
3595 A.getAAFor<AAIsDead>(*this, getIRPosition(), DepClassTy::OPTIONAL);
3596 if (LivenessAA &&
3597 llvm::all_of(DeadEdges,
3598 [&](const auto &DeadEdge) {
3599 return LivenessAA->isEdgeDead(DeadEdge.first,
3600 DeadEdge.second);
3601 }) &&
3602 llvm::all_of(DeadBlocks, [&](const BasicBlock *BB) {
3603 return LivenessAA->isAssumedDead(BB);
3604 })) {
3605 return ChangeStatus::UNCHANGED;
3606 }
3607 DeadEdges.clear();
3608 DeadBlocks.clear();
3609 return Base::updateImpl(A);
3610 }
3611
3612 bool isReachableImpl(Attributor &A, RQITy &RQI,
3613 bool IsTemporaryRQI) override {
3614 const Instruction *Origin = RQI.From;
3615 bool UsedExclusionSet = false;
3616
3617 auto WillReachInBlock = [&](const Instruction &From, const Instruction &To,
3618 const AA::InstExclusionSetTy *ExclusionSet) {
3619 const Instruction *IP = &From;
3620 while (IP && IP != &To) {
3621 if (ExclusionSet && IP != Origin && ExclusionSet->count(IP)) {
3622 UsedExclusionSet = true;
3623 break;
3624 }
3625 IP = IP->getNextNode();
3626 }
3627 return IP == &To;
3628 };
3629
3630 const BasicBlock *FromBB = RQI.From->getParent();
3631 const BasicBlock *ToBB = RQI.To->getParent();
3632 assert(FromBB->getParent() == ToBB->getParent() &&
3633 "Not an intra-procedural query!");
3634
3635 // Check intra-block reachability, however, other reaching paths are still
3636 // possible.
3637 if (FromBB == ToBB &&
3638 WillReachInBlock(*RQI.From, *RQI.To, RQI.ExclusionSet))
3639 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
3640 IsTemporaryRQI);
3641
3642 // Check if reaching the ToBB block is sufficient or if even that would not
3643 // ensure reaching the target. In the latter case we are done.
3644 if (!WillReachInBlock(ToBB->front(), *RQI.To, RQI.ExclusionSet))
3645 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
3646 IsTemporaryRQI);
3647
3648 const Function *Fn = FromBB->getParent();
3650 if (RQI.ExclusionSet)
3651 for (auto *I : *RQI.ExclusionSet)
3652 if (I->getFunction() == Fn)
3653 ExclusionBlocks.insert(I->getParent());
3654
3655 // Check if we make it out of the FromBB block at all.
3656 if (ExclusionBlocks.count(FromBB) &&
3657 !WillReachInBlock(*RQI.From, *FromBB->getTerminator(),
3658 RQI.ExclusionSet))
3659 return rememberResult(A, RQITy::Reachable::No, RQI, true, IsTemporaryRQI);
3660
3661 auto *LivenessAA =
3662 A.getAAFor<AAIsDead>(*this, getIRPosition(), DepClassTy::OPTIONAL);
3663 if (LivenessAA && LivenessAA->isAssumedDead(ToBB)) {
3664 DeadBlocks.insert(ToBB);
3665 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
3666 IsTemporaryRQI);
3667 }
3668
3671 Worklist.push_back(FromBB);
3672
3674 while (!Worklist.empty()) {
3675 const BasicBlock *BB = Worklist.pop_back_val();
3676 if (!Visited.insert(BB).second)
3677 continue;
3678 for (const BasicBlock *SuccBB : successors(BB)) {
3679 if (LivenessAA && LivenessAA->isEdgeDead(BB, SuccBB)) {
3680 LocalDeadEdges.insert({BB, SuccBB});
3681 continue;
3682 }
3683 // We checked before if we just need to reach the ToBB block.
3684 if (SuccBB == ToBB)
3685 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
3686 IsTemporaryRQI);
3687 if (DT && ExclusionBlocks.empty() && DT->dominates(BB, ToBB))
3688 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
3689 IsTemporaryRQI);
3690
3691 if (ExclusionBlocks.count(SuccBB)) {
3692 UsedExclusionSet = true;
3693 continue;
3694 }
3695 Worklist.push_back(SuccBB);
3696 }
3697 }
3698
3699 DeadEdges.insert(LocalDeadEdges.begin(), LocalDeadEdges.end());
3700 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
3701 IsTemporaryRQI);
3702 }
3703
3704 /// See AbstractAttribute::trackStatistics()
3705 void trackStatistics() const override {}
3706
3707private:
3708 // Set of assumed dead blocks we used in the last query. If any changes we
3709 // update the state.
3711
3712 // Set of assumed dead edges we used in the last query. If any changes we
3713 // update the state.
3715
3716 /// The dominator tree of the function to short-circuit reasoning.
3717 const DominatorTree *DT = nullptr;
3718};
3719} // namespace
3720
3721/// ------------------------ NoAlias Argument Attribute ------------------------
3722
3724 Attribute::AttrKind ImpliedAttributeKind,
3725 bool IgnoreSubsumingPositions) {
3726 assert(ImpliedAttributeKind == Attribute::NoAlias &&
3727 "Unexpected attribute kind");
3728 Value *Val = &IRP.getAssociatedValue();
3729 if (IRP.getPositionKind() != IRP_CALL_SITE_ARGUMENT) {
3730 if (isa<AllocaInst>(Val))
3731 return true;
3732 } else {
3733 IgnoreSubsumingPositions = true;
3734 }
3735
3736 if (isa<UndefValue>(Val))
3737 return true;
3738
3739 if (isa<ConstantPointerNull>(Val) &&
3742 return true;
3743
3744 if (A.hasAttr(IRP, {Attribute::ByVal, Attribute::NoAlias},
3745 IgnoreSubsumingPositions, Attribute::NoAlias))
3746 return true;
3747
3748 return false;
3749}
3750
3751namespace {
3752struct AANoAliasImpl : AANoAlias {
3753 AANoAliasImpl(const IRPosition &IRP, Attributor &A) : AANoAlias(IRP, A) {
3754 assert(getAssociatedType()->isPointerTy() &&
3755 "Noalias is a pointer attribute");
3756 }
3757
3758 const std::string getAsStr(Attributor *A) const override {
3759 return getAssumed() ? "noalias" : "may-alias";
3760 }
3761};
3762
3763/// NoAlias attribute for a floating value.
3764struct AANoAliasFloating final : AANoAliasImpl {
3765 AANoAliasFloating(const IRPosition &IRP, Attributor &A)
3766 : AANoAliasImpl(IRP, A) {}
3767
3768 /// See AbstractAttribute::updateImpl(...).
3769 ChangeStatus updateImpl(Attributor &A) override {
3770 // TODO: Implement this.
3771 return indicatePessimisticFixpoint();
3772 }
3773
3774 /// See AbstractAttribute::trackStatistics()
3775 void trackStatistics() const override {
3777 }
3778};
3779
3780/// NoAlias attribute for an argument.
3781struct AANoAliasArgument final
3782 : AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl> {
3783 using Base = AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl>;
3784 AANoAliasArgument(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {}
3785
3786 /// See AbstractAttribute::update(...).
3787 ChangeStatus updateImpl(Attributor &A) override {
3788 // We have to make sure no-alias on the argument does not break
3789 // synchronization when this is a callback argument, see also [1] below.
3790 // If synchronization cannot be affected, we delegate to the base updateImpl
3791 // function, otherwise we give up for now.
3792
3793 // If the function is no-sync, no-alias cannot break synchronization.
3794 bool IsKnownNoSycn;
3795 if (AA::hasAssumedIRAttr<Attribute::NoSync>(
3796 A, this, IRPosition::function_scope(getIRPosition()),
3797 DepClassTy::OPTIONAL, IsKnownNoSycn))
3798 return Base::updateImpl(A);
3799
3800 // If the argument is read-only, no-alias cannot break synchronization.
3801 bool IsKnown;
3802 if (AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown))
3803 return Base::updateImpl(A);
3804
3805 // If the argument is never passed through callbacks, no-alias cannot break
3806 // synchronization.
3807 bool UsedAssumedInformation = false;
3808 if (A.checkForAllCallSites(
3809 [](AbstractCallSite ACS) { return !ACS.isCallbackCall(); }, *this,
3810 true, UsedAssumedInformation))
3811 return Base::updateImpl(A);
3812
3813 // TODO: add no-alias but make sure it doesn't break synchronization by
3814 // introducing fake uses. See:
3815 // [1] Compiler Optimizations for OpenMP, J. Doerfert and H. Finkel,
3816 // International Workshop on OpenMP 2018,
3817 // http://compilers.cs.uni-saarland.de/people/doerfert/par_opt18.pdf
3818
3819 return indicatePessimisticFixpoint();
3820 }
3821
3822 /// See AbstractAttribute::trackStatistics()
3823 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noalias) }
3824};
3825
3826struct AANoAliasCallSiteArgument final : AANoAliasImpl {
3827 AANoAliasCallSiteArgument(const IRPosition &IRP, Attributor &A)
3828 : AANoAliasImpl(IRP, A) {}
3829
3830 /// Determine if the underlying value may alias with the call site argument
3831 /// \p OtherArgNo of \p ICS (= the underlying call site).
3832 bool mayAliasWithArgument(Attributor &A, AAResults *&AAR,
3833 const AAMemoryBehavior &MemBehaviorAA,
3834 const CallBase &CB, unsigned OtherArgNo) {
3835 // We do not need to worry about aliasing with the underlying IRP.
3836 if (this->getCalleeArgNo() == (int)OtherArgNo)
3837 return false;
3838
3839 // If it is not a pointer or pointer vector we do not alias.
3840 const Value *ArgOp = CB.getArgOperand(OtherArgNo);
3841 if (!ArgOp->getType()->isPtrOrPtrVectorTy())
3842 return false;
3843
3844 auto *CBArgMemBehaviorAA = A.getAAFor<AAMemoryBehavior>(
3845 *this, IRPosition::callsite_argument(CB, OtherArgNo), DepClassTy::NONE);
3846
3847 // If the argument is readnone, there is no read-write aliasing.
3848 if (CBArgMemBehaviorAA && CBArgMemBehaviorAA->isAssumedReadNone()) {
3849 A.recordDependence(*CBArgMemBehaviorAA, *this, DepClassTy::OPTIONAL);
3850 return false;
3851 }
3852
3853 // If the argument is readonly and the underlying value is readonly, there
3854 // is no read-write aliasing.
3855 bool IsReadOnly = MemBehaviorAA.isAssumedReadOnly();
3856 if (CBArgMemBehaviorAA && CBArgMemBehaviorAA->isAssumedReadOnly() &&
3857 IsReadOnly) {
3858 A.recordDependence(MemBehaviorAA, *this, DepClassTy::OPTIONAL);
3859 A.recordDependence(*CBArgMemBehaviorAA, *this, DepClassTy::OPTIONAL);
3860 return false;
3861 }
3862
3863 // We have to utilize actual alias analysis queries so we need the object.
3864 if (!AAR)
3865 AAR = A.getInfoCache().getAnalysisResultForFunction<AAManager>(
3866 *getAnchorScope());
3867
3868 // Try to rule it out at the call site.
3869 bool IsAliasing = !AAR || !AAR->isNoAlias(&getAssociatedValue(), ArgOp);
3870 LLVM_DEBUG(dbgs() << "[NoAliasCSArg] Check alias between "
3871 "callsite arguments: "
3872 << getAssociatedValue() << " " << *ArgOp << " => "
3873 << (IsAliasing ? "" : "no-") << "alias \n");
3874
3875 return IsAliasing;
3876 }
3877
3878 bool isKnownNoAliasDueToNoAliasPreservation(
3879 Attributor &A, AAResults *&AAR, const AAMemoryBehavior &MemBehaviorAA) {
3880 // We can deduce "noalias" if the following conditions hold.
3881 // (i) Associated value is assumed to be noalias in the definition.
3882 // (ii) Associated value is assumed to be no-capture in all the uses
3883 // possibly executed before this callsite.
3884 // (iii) There is no other pointer argument which could alias with the
3885 // value.
3886
3887 auto IsDereferenceableOrNull = [&](Value *O, const DataLayout &DL) {
3888 const auto *DerefAA = A.getAAFor<AADereferenceable>(
3889 *this, IRPosition::value(*O), DepClassTy::OPTIONAL);
3890 return DerefAA ? DerefAA->getAssumedDereferenceableBytes() : 0;
3891 };
3892
3893 const IRPosition &VIRP = IRPosition::value(getAssociatedValue());
3894 const Function *ScopeFn = VIRP.getAnchorScope();
3895 // Check whether the value is captured in the scope using AANoCapture.
3896 // Look at CFG and check only uses possibly executed before this
3897 // callsite.
3898 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
3899 Instruction *UserI = cast<Instruction>(U.getUser());
3900
3901 // If UserI is the curr instruction and there is a single potential use of
3902 // the value in UserI we allow the use.
3903 // TODO: We should inspect the operands and allow those that cannot alias
3904 // with the value.
3905 if (UserI == getCtxI() && UserI->getNumOperands() == 1)
3906 return true;
3907
3908 if (ScopeFn) {
3909 if (auto *CB = dyn_cast<CallBase>(UserI)) {
3910 if (CB->isArgOperand(&U)) {
3911
3912 unsigned ArgNo = CB->getArgOperandNo(&U);
3913
3914 bool IsKnownNoCapture;
3915 if (AA::hasAssumedIRAttr<Attribute::NoCapture>(
3916 A, this, IRPosition::callsite_argument(*CB, ArgNo),
3917 DepClassTy::OPTIONAL, IsKnownNoCapture))
3918 return true;
3919 }
3920 }
3921
3923 A, *UserI, *getCtxI(), *this, /* ExclusionSet */ nullptr,
3924 [ScopeFn](const Function &Fn) { return &Fn != ScopeFn; }))
3925 return true;
3926 }
3927
3928 // TODO: We should track the capturing uses in AANoCapture but the problem
3929 // is CGSCC runs. For those we would need to "allow" AANoCapture for
3930 // a value in the module slice.
3931 switch (DetermineUseCaptureKind(U, IsDereferenceableOrNull)) {
3932 case UseCaptureKind::NO_CAPTURE:
3933 return true;
3934 case UseCaptureKind::MAY_CAPTURE:
3935 LLVM_DEBUG(dbgs() << "[AANoAliasCSArg] Unknown user: " << *UserI
3936 << "\n");
3937 return false;
3938 case UseCaptureKind::PASSTHROUGH:
3939 Follow = true;
3940 return true;
3941 }
3942 llvm_unreachable("unknown UseCaptureKind");
3943 };
3944
3945 bool IsKnownNoCapture;
3946 const AANoCapture *NoCaptureAA = nullptr;
3947 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::NoCapture>(
3948 A, this, VIRP, DepClassTy::NONE, IsKnownNoCapture, false, &NoCaptureAA);
3949 if (!IsAssumedNoCapture &&
3950 (!NoCaptureAA || !NoCaptureAA->isAssumedNoCaptureMaybeReturned())) {
3951 if (!A.checkForAllUses(UsePred, *this, getAssociatedValue())) {
3952 LLVM_DEBUG(
3953 dbgs() << "[AANoAliasCSArg] " << getAssociatedValue()
3954 << " cannot be noalias as it is potentially captured\n");
3955 return false;
3956 }
3957 }
3958 if (NoCaptureAA)
3959 A.recordDependence(*NoCaptureAA, *this, DepClassTy::OPTIONAL);
3960
3961 // Check there is no other pointer argument which could alias with the
3962 // value passed at this call site.
3963 // TODO: AbstractCallSite
3964 const auto &CB = cast<CallBase>(getAnchorValue());
3965 for (unsigned OtherArgNo = 0; OtherArgNo < CB.arg_size(); OtherArgNo++)
3966 if (mayAliasWithArgument(A, AAR, MemBehaviorAA, CB, OtherArgNo))
3967 return false;
3968
3969 return true;
3970 }
3971
3972 /// See AbstractAttribute::updateImpl(...).
3973 ChangeStatus updateImpl(Attributor &A) override {
3974 // If the argument is readnone we are done as there are no accesses via the
3975 // argument.
3976 auto *MemBehaviorAA =
3977 A.getAAFor<AAMemoryBehavior>(*this, getIRPosition(), DepClassTy::NONE);
3978 if (MemBehaviorAA && MemBehaviorAA->isAssumedReadNone()) {
3979 A.recordDependence(*MemBehaviorAA, *this, DepClassTy::OPTIONAL);
3980 return ChangeStatus::UNCHANGED;
3981 }
3982
3983 bool IsKnownNoAlias;
3984 const IRPosition &VIRP = IRPosition::value(getAssociatedValue());
3985 if (!AA::hasAssumedIRAttr<Attribute::NoAlias>(
3986 A, this, VIRP, DepClassTy::REQUIRED, IsKnownNoAlias)) {
3987 LLVM_DEBUG(dbgs() << "[AANoAlias] " << getAssociatedValue()
3988 << " is not no-alias at the definition\n");
3989 return indicatePessimisticFixpoint();
3990 }
3991
3992 AAResults *AAR = nullptr;
3993 if (MemBehaviorAA &&
3994 isKnownNoAliasDueToNoAliasPreservation(A, AAR, *MemBehaviorAA)) {
3995 LLVM_DEBUG(
3996 dbgs() << "[AANoAlias] No-Alias deduced via no-alias preservation\n");
3997 return ChangeStatus::UNCHANGED;
3998 }
3999
4000 return indicatePessimisticFixpoint();
4001 }
4002
4003 /// See AbstractAttribute::trackStatistics()
4004 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(noalias) }
4005};
4006
4007/// NoAlias attribute for function return value.
4008struct AANoAliasReturned final : AANoAliasImpl {
4009 AANoAliasReturned(const IRPosition &IRP, Attributor &A)
4010 : AANoAliasImpl(IRP, A) {}
4011
4012 /// See AbstractAttribute::updateImpl(...).
4013 ChangeStatus updateImpl(Attributor &A) override {
4014
4015 auto CheckReturnValue = [&](Value &RV) -> bool {
4016 if (Constant *C = dyn_cast<Constant>(&RV))
4017 if (C->isNullValue() || isa<UndefValue>(C))
4018 return true;
4019
4020 /// For now, we can only deduce noalias if we have call sites.
4021 /// FIXME: add more support.
4022 if (!isa<CallBase>(&RV))
4023 return false;
4024
4025 const IRPosition &RVPos = IRPosition::value(RV);
4026 bool IsKnownNoAlias;
4027 if (!AA::hasAssumedIRAttr<Attribute::NoAlias>(
4028 A, this, RVPos, DepClassTy::REQUIRED, IsKnownNoAlias))
4029 return false;
4030
4031 bool IsKnownNoCapture;
4032 const AANoCapture *NoCaptureAA = nullptr;
4033 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::NoCapture>(
4034 A, this, RVPos, DepClassTy::REQUIRED, IsKnownNoCapture, false,
4035 &NoCaptureAA);
4036 return IsAssumedNoCapture ||
4037 (NoCaptureAA && NoCaptureAA->isAssumedNoCaptureMaybeReturned());
4038 };
4039
4040 if (!A.checkForAllReturnedValues(CheckReturnValue, *this))
4041 return indicatePessimisticFixpoint();
4042
4043 return ChangeStatus::UNCHANGED;
4044 }
4045
4046 /// See AbstractAttribute::trackStatistics()
4047 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noalias) }
4048};
4049
4050/// NoAlias attribute deduction for a call site return value.
4051struct AANoAliasCallSiteReturned final
4052 : AACalleeToCallSite<AANoAlias, AANoAliasImpl> {
4053 AANoAliasCallSiteReturned(const IRPosition &IRP, Attributor &A)
4054 : AACalleeToCallSite<AANoAlias, AANoAliasImpl>(IRP, A) {}
4055
4056 /// See AbstractAttribute::trackStatistics()
4057 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(noalias); }
4058};
4059} // namespace
4060
4061/// -------------------AAIsDead Function Attribute-----------------------
4062
4063namespace {
4064struct AAIsDeadValueImpl : public AAIsDead {
4065 AAIsDeadValueImpl(const IRPosition &IRP, Attributor &A) : AAIsDead(IRP, A) {}
4066
4067 /// See AAIsDead::isAssumedDead().
4068 bool isAssumedDead() const override { return isAssumed(IS_DEAD); }
4069
4070 /// See AAIsDead::isKnownDead().
4071 bool isKnownDead() const override { return isKnown(IS_DEAD); }
4072
4073 /// See AAIsDead::isAssumedDead(BasicBlock *).
4074 bool isAssumedDead(const BasicBlock *BB) const override { return false; }
4075
4076 /// See AAIsDead::isKnownDead(BasicBlock *).
4077 bool isKnownDead(const BasicBlock *BB) const override { return false; }
4078
4079 /// See AAIsDead::isAssumedDead(Instruction *I).
4080 bool isAssumedDead(const Instruction *I) const override {
4081 return I == getCtxI() && isAssumedDead();
4082 }
4083
4084 /// See AAIsDead::isKnownDead(Instruction *I).
4085 bool isKnownDead(const Instruction *I) const override {
4086 return isAssumedDead(I) && isKnownDead();
4087 }
4088
4089 /// See AbstractAttribute::getAsStr().
4090 const std::string getAsStr(Attributor *A) const override {
4091 return isAssumedDead() ? "assumed-dead" : "assumed-live";
4092 }
4093
4094 /// Check if all uses are assumed dead.
4095 bool areAllUsesAssumedDead(Attributor &A, Value &V) {
4096 // Callers might not check the type, void has no uses.
4097 if (V.getType()->isVoidTy() || V.use_empty())
4098 return true;
4099
4100 // If we replace a value with a constant there are no uses left afterwards.
4101 if (!isa<Constant>(V)) {
4102 if (auto *I = dyn_cast<Instruction>(&V))
4103 if (!A.isRunOn(*I->getFunction()))
4104 return false;
4105 bool UsedAssumedInformation = false;
4106 std::optional<Constant *> C =
4107 A.getAssumedConstant(V, *this, UsedAssumedInformation);
4108 if (!C || *C)
4109 return true;
4110 }
4111
4112 auto UsePred = [&](const Use &U, bool &Follow) { return false; };
4113 // Explicitly set the dependence class to required because we want a long
4114 // chain of N dependent instructions to be considered live as soon as one is
4115 // without going through N update cycles. This is not required for
4116 // correctness.
4117 return A.checkForAllUses(UsePred, *this, V, /* CheckBBLivenessOnly */ false,
4118 DepClassTy::REQUIRED,
4119 /* IgnoreDroppableUses */ false);
4120 }
4121
4122 /// Determine if \p I is assumed to be side-effect free.
4123 bool isAssumedSideEffectFree(Attributor &A, Instruction *I) {
4125 return true;
4126
4127 auto *CB = dyn_cast<CallBase>(I);
4128 if (!CB || isa<IntrinsicInst>(CB))
4129 return false;
4130
4131 const IRPosition &CallIRP = IRPosition::callsite_function(*CB);
4132
4133 bool IsKnownNoUnwind;
4134 if (!AA::hasAssumedIRAttr<Attribute::NoUnwind>(
4135 A, this, CallIRP, DepClassTy::OPTIONAL, IsKnownNoUnwind))
4136 return false;
4137
4138 bool IsKnown;
4139 return AA::isAssumedReadOnly(A, CallIRP, *this, IsKnown);
4140 }
4141};
4142
4143struct AAIsDeadFloating : public AAIsDeadValueImpl {
4144 AAIsDeadFloating(const IRPosition &IRP, Attributor &A)
4145 : AAIsDeadValueImpl(IRP, A) {}
4146
4147 /// See AbstractAttribute::initialize(...).
4148 void initialize(Attributor &A) override {
4149 AAIsDeadValueImpl::initialize(A);
4150
4151 if (isa<UndefValue>(getAssociatedValue())) {
4152 indicatePessimisticFixpoint();
4153 return;
4154 }
4155
4156 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
4157 if (!isAssumedSideEffectFree(A, I)) {
4158 if (!isa_and_nonnull<StoreInst>(I) && !isa_and_nonnull<FenceInst>(I))
4159 indicatePessimisticFixpoint();
4160 else
4161 removeAssumedBits(HAS_NO_EFFECT);
4162 }
4163 }
4164
4165 bool isDeadFence(Attributor &A, FenceInst &FI) {
4166 const auto *ExecDomainAA = A.lookupAAFor<AAExecutionDomain>(
4167 IRPosition::function(*FI.getFunction()), *this, DepClassTy::NONE);
4168 if (!ExecDomainAA || !ExecDomainAA->isNoOpFence(FI))
4169 return false;
4170 A.recordDependence(*ExecDomainAA, *this, DepClassTy::OPTIONAL);
4171 return true;
4172 }
4173
4174 bool isDeadStore(Attributor &A, StoreInst &SI,
4175 SmallSetVector<Instruction *, 8> *AssumeOnlyInst = nullptr) {
4176 // Lang ref now states volatile store is not UB/dead, let's skip them.
4177 if (SI.isVolatile())
4178 return false;
4179
4180 // If we are collecting assumes to be deleted we are in the manifest stage.
4181 // It's problematic to collect the potential copies again now so we use the
4182 // cached ones.
4183 bool UsedAssumedInformation = false;
4184 if (!AssumeOnlyInst) {
4185 PotentialCopies.clear();
4186 if (!AA::getPotentialCopiesOfStoredValue(A, SI, PotentialCopies, *this,
4187 UsedAssumedInformation)) {
4188 LLVM_DEBUG(
4189 dbgs()
4190 << "[AAIsDead] Could not determine potential copies of store!\n");
4191 return false;
4192 }
4193 }
4194 LLVM_DEBUG(dbgs() << "[AAIsDead] Store has " << PotentialCopies.size()
4195 << " potential copies.\n");
4196
4197 InformationCache &InfoCache = A.getInfoCache();
4198 return llvm::all_of(PotentialCopies, [&](Value *V) {
4199 if (A.isAssumedDead(IRPosition::value(*V), this, nullptr,
4200 UsedAssumedInformation))
4201 return true;
4202 if (auto *LI = dyn_cast<LoadInst>(V)) {
4203 if (llvm::all_of(LI->uses(), [&](const Use &U) {
4204 auto &UserI = cast<Instruction>(*U.getUser());
4205 if (InfoCache.isOnlyUsedByAssume(UserI)) {
4206 if (AssumeOnlyInst)
4207 AssumeOnlyInst->insert(&UserI);
4208 return true;
4209 }
4210 return A.isAssumedDead(U, this, nullptr, UsedAssumedInformation);
4211 })) {
4212 return true;
4213 }
4214 }
4215 LLVM_DEBUG(dbgs() << "[AAIsDead] Potential copy " << *V
4216 << " is assumed live!\n");
4217 return false;
4218 });
4219 }
4220
4221 /// See AbstractAttribute::getAsStr().
4222 const std::string getAsStr(Attributor *A) const override {
4223 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
4224 if (isa_and_nonnull<StoreInst>(I))
4225 if (isValidState())
4226 return "assumed-dead-store";
4227 if (isa_and_nonnull<FenceInst>(I))
4228 if (isValidState())
4229 return "assumed-dead-fence";
4230 return AAIsDeadValueImpl::getAsStr(A);
4231 }
4232
4233 /// See AbstractAttribute::updateImpl(...).
4234 ChangeStatus updateImpl(Attributor &A) override {
4235 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
4236 if (auto *SI = dyn_cast_or_null<StoreInst>(I)) {
4237 if (!isDeadStore(A, *SI))
4238 return indicatePessimisticFixpoint();
4239 } else if (auto *FI = dyn_cast_or_null<FenceInst>(I)) {
4240 if (!isDeadFence(A, *FI))
4241 return indicatePessimisticFixpoint();
4242 } else {
4243 if (!isAssumedSideEffectFree(A, I))
4244 return indicatePessimisticFixpoint();
4245 if (!areAllUsesAssumedDead(A, getAssociatedValue()))
4246 return indicatePessimisticFixpoint();
4247 }
4249 }
4250
4251 bool isRemovableStore() const override {
4252 return isAssumed(IS_REMOVABLE) && isa<StoreInst>(&getAssociatedValue());
4253 }
4254
4255 /// See AbstractAttribute::manifest(...).
4256 ChangeStatus manifest(Attributor &A) override {
4257 Value &V = getAssociatedValue();
4258 if (auto *I = dyn_cast<Instruction>(&V)) {
4259 // If we get here we basically know the users are all dead. We check if
4260 // isAssumedSideEffectFree returns true here again because it might not be
4261 // the case and only the users are dead but the instruction (=call) is
4262 // still needed.
4263 if (auto *SI = dyn_cast<StoreInst>(I)) {
4264 SmallSetVector<Instruction *, 8> AssumeOnlyInst;
4265 bool IsDead = isDeadStore(A, *SI, &AssumeOnlyInst);
4266 (void)IsDead;
4267 assert(IsDead && "Store was assumed to be dead!");
4268 A.deleteAfterManifest(*I);
4269 for (size_t i = 0; i < AssumeOnlyInst.size(); ++i) {
4270 Instruction *AOI = AssumeOnlyInst[i];
4271 for (auto *Usr : AOI->users())
4272 AssumeOnlyInst.insert(cast<Instruction>(Usr));
4273 A.deleteAfterManifest(*AOI);
4274 }
4275 return ChangeStatus::CHANGED;
4276 }
4277 if (auto *FI = dyn_cast<FenceInst>(I)) {
4278 assert(isDeadFence(A, *FI));
4279 A.deleteAfterManifest(*FI);
4280 return ChangeStatus::CHANGED;
4281 }
4282 if (isAssumedSideEffectFree(A, I) && !isa<InvokeInst>(I)) {
4283 A.deleteAfterManifest(*I);
4284 return ChangeStatus::CHANGED;
4285 }
4286 }
4288 }
4289
4290 /// See AbstractAttribute::trackStatistics()
4291 void trackStatistics() const override {
4293 }
4294
4295private:
4296 // The potential copies of a dead store, used for deletion during manifest.
4297 SmallSetVector<Value *, 4> PotentialCopies;
4298};
4299
4300struct AAIsDeadArgument : public AAIsDeadFloating {
4301 AAIsDeadArgument(const IRPosition &IRP, Attributor &A)
4302 : AAIsDeadFloating(IRP, A) {}
4303
4304 /// See AbstractAttribute::manifest(...).
4305 ChangeStatus manifest(Attributor &A) override {
4306 Argument &Arg = *getAssociatedArgument();
4307 if (A.isValidFunctionSignatureRewrite(Arg, /* ReplacementTypes */ {}))
4308 if (A.registerFunctionSignatureRewrite(
4309 Arg, /* ReplacementTypes */ {},
4312 return ChangeStatus::CHANGED;
4313 }
4314 return ChangeStatus::UNCHANGED;
4315 }
4316
4317 /// See AbstractAttribute::trackStatistics()
4318 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(IsDead) }
4319};
4320
4321struct AAIsDeadCallSiteArgument : public AAIsDeadValueImpl {
4322 AAIsDeadCallSiteArgument(const IRPosition &IRP, Attributor &A)
4323 : AAIsDeadValueImpl(IRP, A) {}
4324
4325 /// See AbstractAttribute::initialize(...).
4326 void initialize(Attributor &A) override {
4327 AAIsDeadValueImpl::initialize(A);
4328 if (isa<UndefValue>(getAssociatedValue()))
4329 indicatePessimisticFixpoint();
4330 }
4331
4332 /// See AbstractAttribute::updateImpl(...).
4333 ChangeStatus updateImpl(Attributor &A) override {
4334 // TODO: Once we have call site specific value information we can provide
4335 // call site specific liveness information and then it makes
4336 // sense to specialize attributes for call sites arguments instead of
4337 // redirecting requests to the callee argument.
4338 Argument *Arg = getAssociatedArgument();
4339 if (!Arg)
4340 return indicatePessimisticFixpoint();
4341 const IRPosition &ArgPos = IRPosition::argument(*Arg);
4342 auto *ArgAA = A.getAAFor<AAIsDead>(*this, ArgPos, DepClassTy::REQUIRED);
4343 if (!ArgAA)
4344 return indicatePessimisticFixpoint();
4345 return clampStateAndIndicateChange(getState(), ArgAA->getState());
4346 }
4347
4348 /// See AbstractAttribute::manifest(...).
4349 ChangeStatus manifest(Attributor &A) override {
4350 CallBase &CB = cast<CallBase>(getAnchorValue());
4351 Use &U = CB.getArgOperandUse(getCallSiteArgNo());
4352 assert(!isa<UndefValue>(U.get()) &&
4353 "Expected undef values to be filtered out!");
4354 UndefValue &UV = *UndefValue::get(U->getType());
4355 if (A.changeUseAfterManifest(U, UV))
4356 return ChangeStatus::CHANGED;
4357 return ChangeStatus::UNCHANGED;
4358 }
4359
4360 /// See AbstractAttribute::trackStatistics()
4361 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(IsDead) }
4362};
4363
4364struct AAIsDeadCallSiteReturned : public AAIsDeadFloating {
4365 AAIsDeadCallSiteReturned(const IRPosition &IRP, Attributor &A)
4366 : AAIsDeadFloating(IRP, A) {}
4367
4368 /// See AAIsDead::isAssumedDead().
4369 bool isAssumedDead() const override {
4370 return AAIsDeadFloating::isAssumedDead() && IsAssumedSideEffectFree;
4371 }
4372
4373 /// See AbstractAttribute::initialize(...).
4374 void initialize(Attributor &A) override {
4375 AAIsDeadFloating::initialize(A);
4376 if (isa<UndefValue>(getAssociatedValue())) {
4377 indicatePessimisticFixpoint();
4378 return;
4379 }
4380
4381 // We track this separately as a secondary state.
4382 IsAssumedSideEffectFree = isAssumedSideEffectFree(A, getCtxI());
4383 }
4384
4385 /// See AbstractAttribute::updateImpl(...).
4386 ChangeStatus updateImpl(Attributor &A) override {
4387 ChangeStatus Changed = ChangeStatus::UNCHANGED;
4388 if (IsAssumedSideEffectFree && !isAssumedSideEffectFree(A, getCtxI())) {
4389 IsAssumedSideEffectFree = false;
4390 Changed = ChangeStatus::CHANGED;
4391 }
4392 if (!areAllUsesAssumedDead(A, getAssociatedValue()))
4393 return indicatePessimisticFixpoint();
4394 return Changed;
4395 }
4396
4397 /// See AbstractAttribute::trackStatistics()
4398 void trackStatistics() const override {
4399 if (IsAssumedSideEffectFree)
4401 else
4402 STATS_DECLTRACK_CSRET_ATTR(UnusedResult)
4403 }
4404
4405 /// See AbstractAttribute::getAsStr().
4406 const std::string getAsStr(Attributor *A) const override {
4407 return isAssumedDead()
4408 ? "assumed-dead"
4409 : (getAssumed() ? "assumed-dead-users" : "assumed-live");
4410 }
4411
4412private:
4413 bool IsAssumedSideEffectFree = true;
4414};
4415
4416struct AAIsDeadReturned : public AAIsDeadValueImpl {
4417 AAIsDeadReturned(const IRPosition &IRP, Attributor &A)
4418 : AAIsDeadValueImpl(IRP, A) {}
4419
4420 /// See AbstractAttribute::updateImpl(...).
4421 ChangeStatus updateImpl(Attributor &A) override {
4422
4423 bool UsedAssumedInformation = false;
4424 A.checkForAllInstructions([](Instruction &) { return true; }, *this,
4425 {Instruction::Ret}, UsedAssumedInformation);
4426
4427 auto PredForCallSite = [&](AbstractCallSite ACS) {
4428 if (ACS.isCallbackCall() || !ACS.getInstruction())
4429 return false;
4430 return areAllUsesAssumedDead(A, *ACS.getInstruction());
4431 };
4432
4433 if (!A.checkForAllCallSites(PredForCallSite, *this, true,
4434 UsedAssumedInformation))
4435 return indicatePessimisticFixpoint();
4436
4437 return ChangeStatus::UNCHANGED;
4438 }
4439
4440 /// See AbstractAttribute::manifest(...).
4441 ChangeStatus manifest(Attributor &A) override {
4442 // TODO: Rewrite the signature to return void?
4443 bool AnyChange = false;
4444 UndefValue &UV = *UndefValue::get(getAssociatedFunction()->getReturnType());
4445 auto RetInstPred = [&](Instruction &I) {
4446 ReturnInst &RI = cast<ReturnInst>(I);
4447 if (!isa<UndefValue>(RI.getReturnValue()))
4448 AnyChange |= A.changeUseAfterManifest(RI.getOperandUse(0), UV);
4449 return true;
4450 };
4451 bool UsedAssumedInformation = false;
4452 A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret},
4453 UsedAssumedInformation);
4454 return AnyChange ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
4455 }
4456
4457 /// See AbstractAttribute::trackStatistics()
4458 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(IsDead) }
4459};
4460
4461struct AAIsDeadFunction : public AAIsDead {
4462 AAIsDeadFunction(const IRPosition &IRP, Attributor &A) : AAIsDead(IRP, A) {}
4463
4464 /// See AbstractAttribute::initialize(...).
4465 void initialize(Attributor &A) override {
4466 Function *F = getAnchorScope();
4467 assert(F && "Did expect an anchor function");
4468 if (!isAssumedDeadInternalFunction(A)) {
4469 ToBeExploredFrom.insert(&F->getEntryBlock().front());
4470 assumeLive(A, F->getEntryBlock());
4471 }
4472 }
4473
4474 bool isAssumedDeadInternalFunction(Attributor &A) {
4475 if (!getAnchorScope()->hasLocalLinkage())
4476 return false;
4477 bool UsedAssumedInformation = false;
4478 return A.checkForAllCallSites([](AbstractCallSite) { return false; }, *this,
4479 true, UsedAssumedInformation);
4480 }
4481
4482 /// See AbstractAttribute::getAsStr().
4483 const std::string getAsStr(Attributor *A) const override {
4484 return "Live[#BB " + std::to_string(AssumedLiveBlocks.size()) + "/" +
4485 std::to_string(getAnchorScope()->size()) + "][#TBEP " +
4486 std::to_string(ToBeExploredFrom.size()) + "][#KDE " +
4487 std::to_string(KnownDeadEnds.size()) + "]";
4488 }
4489
4490 /// See AbstractAttribute::manifest(...).
4491 ChangeStatus manifest(Attributor &A) override {
4492 assert(getState().isValidState() &&
4493 "Attempted to manifest an invalid state!");
4494
4495 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
4496 Function &F = *getAnchorScope();
4497
4498 if (AssumedLiveBlocks.empty()) {
4499 A.deleteAfterManifest(F);
4500 return ChangeStatus::CHANGED;
4501 }
4502
4503 // Flag to determine if we can change an invoke to a call assuming the
4504 // callee is nounwind. This is not possible if the personality of the
4505 // function allows to catch asynchronous exceptions.
4506 bool Invoke2CallAllowed = !mayCatchAsynchronousExceptions(F);
4507
4508 KnownDeadEnds.set_union(ToBeExploredFrom);
4509 for (const Instruction *DeadEndI : KnownDeadEnds) {
4510 auto *CB = dyn_cast<CallBase>(DeadEndI);
4511 if (!CB)
4512 continue;
4513 bool IsKnownNoReturn;
4514 bool MayReturn = !AA::hasAssumedIRAttr<Attribute::NoReturn>(
4515 A, this, IRPosition::callsite_function(*CB), DepClassTy::OPTIONAL,
4516 IsKnownNoReturn);
4517 if (MayReturn && (!Invoke2CallAllowed || !isa<InvokeInst>(CB)))
4518 continue;
4519
4520 if (auto *II = dyn_cast<InvokeInst>(DeadEndI))
4521 A.registerInvokeWithDeadSuccessor(const_cast<InvokeInst &>(*II));
4522 else
4523 A.changeToUnreachableAfterManifest(
4524 const_cast<Instruction *>(DeadEndI->getNextNode()));
4525 HasChanged = ChangeStatus::CHANGED;
4526 }
4527
4528 STATS_DECL(AAIsDead, BasicBlock, "Number of dead basic blocks deleted.");
4529 for (BasicBlock &BB : F)
4530 if (!AssumedLiveBlocks.count(&BB)) {
4531 A.deleteAfterManifest(BB);
4533 HasChanged = ChangeStatus::CHANGED;
4534 }
4535
4536 return HasChanged;
4537 }
4538
4539 /// See AbstractAttribute::updateImpl(...).
4540 ChangeStatus updateImpl(Attributor &A) override;
4541
4542 bool isEdgeDead(const BasicBlock *From, const BasicBlock *To) const override {
4543 assert(From->getParent() == getAnchorScope() &&
4544 To->getParent() == getAnchorScope() &&
4545 "Used AAIsDead of the wrong function");
4546 return isValidState() && !AssumedLiveEdges.count(std::make_pair(From, To));
4547 }
4548
4549 /// See AbstractAttribute::trackStatistics()
4550 void trackStatistics() const override {}
4551
4552 /// Returns true if the function is assumed dead.
4553 bool isAssumedDead() const override { return false; }
4554
4555 /// See AAIsDead::isKnownDead().
4556 bool isKnownDead() const override { return false; }
4557
4558 /// See AAIsDead::isAssumedDead(BasicBlock *).
4559 bool isAssumedDead(const BasicBlock *BB) const override {
4560 assert(BB->getParent() == getAnchorScope() &&
4561 "BB must be in the same anchor scope function.");
4562
4563 if (!getAssumed())
4564 return false;
4565 return !AssumedLiveBlocks.count(BB);
4566 }
4567
4568 /// See AAIsDead::isKnownDead(BasicBlock *).
4569 bool isKnownDead(const BasicBlock *BB) const override {
4570 return getKnown() && isAssumedDead(BB);
4571 }
4572
4573 /// See AAIsDead::isAssumed(Instruction *I).
4574 bool isAssumedDead(const Instruction *I) const override {
4575 assert(I->getParent()->getParent() == getAnchorScope() &&
4576 "Instruction must be in the same anchor scope function.");
4577
4578 if (!getAssumed())
4579 return false;
4580
4581 // If it is not in AssumedLiveBlocks then it for sure dead.
4582 // Otherwise, it can still be after noreturn call in a live block.
4583 if (!AssumedLiveBlocks.count(I->getParent()))
4584 return true;
4585
4586 // If it is not after a liveness barrier it is live.
4587 const Instruction *PrevI = I->getPrevNode();
4588 while (PrevI) {
4589 if (KnownDeadEnds.count(PrevI) || ToBeExploredFrom.count(PrevI))
4590 return true;
4591 PrevI = PrevI->getPrevNode();
4592 }
4593 return false;
4594 }
4595
4596 /// See AAIsDead::isKnownDead(Instruction *I).
4597 bool isKnownDead(const Instruction *I) const override {
4598 return getKnown() && isAssumedDead(I);
4599 }
4600
4601 /// Assume \p BB is (partially) live now and indicate to the Attributor \p A
4602 /// that internal function called from \p BB should now be looked at.
4603 bool assumeLive(Attributor &A, const BasicBlock &BB) {
4604 if (!AssumedLiveBlocks.insert(&BB).second)
4605 return false;
4606
4607 // We assume that all of BB is (probably) live now and if there are calls to
4608 // internal functions we will assume that those are now live as well. This
4609 // is a performance optimization for blocks with calls to a lot of internal
4610 // functions. It can however cause dead functions to be treated as live.
4611 for (const Instruction &I : BB)
4612 if (const auto *CB = dyn_cast<CallBase>(&I))
4613 if (auto *F = dyn_cast_if_present<Function>(CB->getCalledOperand()))
4614 if (F->hasLocalLinkage())
4615 A.markLiveInternalFunction(*F);
4616 return true;
4617 }
4618
4619 /// Collection of instructions that need to be explored again, e.g., we
4620 /// did assume they do not transfer control to (one of their) successors.
4622
4623 /// Collection of instructions that are known to not transfer control.
4625
4626 /// Collection of all assumed live edges
4628
4629 /// Collection of all assumed live BasicBlocks.
4630 DenseSet<const BasicBlock *> AssumedLiveBlocks;
4631};
4632
4633static bool
4634identifyAliveSuccessors(Attributor &A, const CallBase &CB,
4636 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4637 const IRPosition &IPos = IRPosition::callsite_function(CB);
4638
4639 bool IsKnownNoReturn;
4640 if (AA::hasAssumedIRAttr<Attribute::NoReturn>(
4641 A, &AA, IPos, DepClassTy::OPTIONAL, IsKnownNoReturn))
4642 return !IsKnownNoReturn;
4643 if (CB.isTerminator())
4644 AliveSuccessors.push_back(&CB.getSuccessor(0)->front());
4645 else
4646 AliveSuccessors.push_back(CB.getNextNode());
4647 return false;
4648}
4649
4650static bool
4651identifyAliveSuccessors(Attributor &A, const InvokeInst &II,
4653 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4654 bool UsedAssumedInformation =
4655 identifyAliveSuccessors(A, cast<CallBase>(II), AA, AliveSuccessors);
4656
4657 // First, determine if we can change an invoke to a call assuming the
4658 // callee is nounwind. This is not possible if the personality of the
4659 // function allows to catch asynchronous exceptions.
4660 if (AAIsDeadFunction::mayCatchAsynchronousExceptions(*II.getFunction())) {
4661 AliveSuccessors.push_back(&II.getUnwindDest()->front());
4662 } else {
4664
4665 bool IsKnownNoUnwind;
4666 if (AA::hasAssumedIRAttr<Attribute::NoUnwind>(
4667 A, &AA, IPos, DepClassTy::OPTIONAL, IsKnownNoUnwind)) {
4668 UsedAssumedInformation |= !IsKnownNoUnwind;
4669 } else {
4670 AliveSuccessors.push_back(&II.getUnwindDest()->front());
4671 }
4672 }
4673 return UsedAssumedInformation;
4674}
4675
4676static bool
4677identifyAliveSuccessors(Attributor &A, const BranchInst &BI,
4679 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4680 bool UsedAssumedInformation = false;
4681 if (BI.getNumSuccessors() == 1) {
4682 AliveSuccessors.push_back(&BI.getSuccessor(0)->front());
4683 } else {
4684 std::optional<Constant *> C =
4685 A.getAssumedConstant(*BI.getCondition(), AA, UsedAssumedInformation);
4686 if (!C || isa_and_nonnull<UndefValue>(*C)) {
4687 // No value yet, assume both edges are dead.
4688 } else if (isa_and_nonnull<ConstantInt>(*C)) {
4689 const BasicBlock *SuccBB =
4690 BI.getSuccessor(1 - cast<ConstantInt>(*C)->getValue().getZExtValue());
4691 AliveSuccessors.push_back(&SuccBB->front());
4692 } else {
4693 AliveSuccessors.push_back(&BI.getSuccessor(0)->front());
4694 AliveSuccessors.push_back(&BI.getSuccessor(1)->front());
4695 UsedAssumedInformation = false;
4696 }
4697 }
4698 return UsedAssumedInformation;
4699}
4700
4701static bool
4702identifyAliveSuccessors(Attributor &A, const SwitchInst &SI,
4704 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4705 bool UsedAssumedInformation = false;
4707 if (!A.getAssumedSimplifiedValues(IRPosition::value(*SI.getCondition()), &AA,
4708 Values, AA::AnyScope,
4709 UsedAssumedInformation)) {
4710 // Something went wrong, assume all successors are live.
4711 for (const BasicBlock *SuccBB : successors(SI.getParent()))
4712 AliveSuccessors.push_back(&SuccBB->front());
4713 return false;
4714 }
4715
4716 if (Values.empty() ||
4717 (Values.size() == 1 &&
4718 isa_and_nonnull<UndefValue>(Values.front().getValue()))) {
4719 // No valid value yet, assume all edges are dead.
4720 return UsedAssumedInformation;
4721 }
4722
4723 Type &Ty = *SI.getCondition()->getType();
4725 auto CheckForConstantInt = [&](Value *V) {
4726 if (auto *CI = dyn_cast_if_present<ConstantInt>(AA::getWithType(*V, Ty))) {
4727 Constants.insert(CI);
4728 return true;
4729 }
4730 return false;
4731 };
4732
4733 if (!all_of(Values, [&](AA::ValueAndContext &VAC) {
4734 return CheckForConstantInt(VAC.getValue());
4735 })) {
4736 for (const BasicBlock *SuccBB : successors(SI.getParent()))
4737 AliveSuccessors.push_back(&SuccBB->front());
4738 return UsedAssumedInformation;
4739 }
4740
4741 unsigned MatchedCases = 0;
4742 for (const auto &CaseIt : SI.cases()) {
4743 if (Constants.count(CaseIt.getCaseValue())) {
4744 ++MatchedCases;
4745 AliveSuccessors.push_back(&CaseIt.getCaseSuccessor()->front());
4746 }
4747 }
4748
4749 // If all potential values have been matched, we will not visit the default
4750 // case.
4751 if (MatchedCases < Constants.size())
4752 AliveSuccessors.push_back(&SI.getDefaultDest()->front());
4753 return UsedAssumedInformation;
4754}
4755
4756ChangeStatus AAIsDeadFunction::updateImpl(Attributor &A) {
4758
4759 if (AssumedLiveBlocks.empty()) {
4760 if (isAssumedDeadInternalFunction(A))
4762
4763 Function *F = getAnchorScope();
4764 ToBeExploredFrom.insert(&F->getEntryBlock().front());
4765 assumeLive(A, F->getEntryBlock());
4766 Change = ChangeStatus::CHANGED;
4767 }
4768
4769 LLVM_DEBUG(dbgs() << "[AAIsDead] Live [" << AssumedLiveBlocks.size() << "/"
4770 << getAnchorScope()->size() << "] BBs and "
4771 << ToBeExploredFrom.size() << " exploration points and "
4772 << KnownDeadEnds.size() << " known dead ends\n");
4773
4774 // Copy and clear the list of instructions we need to explore from. It is
4775 // refilled with instructions the next update has to look at.
4776 SmallVector<const Instruction *, 8> Worklist(ToBeExploredFrom.begin(),
4777 ToBeExploredFrom.end());
4778 decltype(ToBeExploredFrom) NewToBeExploredFrom;
4779
4781 while (!Worklist.empty()) {
4782 const Instruction *I = Worklist.pop_back_val();
4783 LLVM_DEBUG(dbgs() << "[AAIsDead] Exploration inst: " << *I << "\n");
4784
4785 // Fast forward for uninteresting instructions. We could look for UB here
4786 // though.
4787 while (!I->isTerminator() && !isa<CallBase>(I))
4788 I = I->getNextNode();
4789
4790 AliveSuccessors.clear();
4791
4792 bool UsedAssumedInformation = false;
4793 switch (I->getOpcode()) {
4794 // TODO: look for (assumed) UB to backwards propagate "deadness".
4795 default:
4796 assert(I->isTerminator() &&
4797 "Expected non-terminators to be handled already!");
4798 for (const BasicBlock *SuccBB : successors(I->getParent()))
4799 AliveSuccessors.push_back(&SuccBB->front());
4800 break;
4801 case Instruction::Call:
4802 UsedAssumedInformation = identifyAliveSuccessors(A, cast<CallInst>(*I),
4803 *this, AliveSuccessors);
4804 break;
4805 case Instruction::Invoke:
4806 UsedAssumedInformation = identifyAliveSuccessors(A, cast<InvokeInst>(*I),
4807 *this, AliveSuccessors);
4808 break;
4809 case Instruction::Br:
4810 UsedAssumedInformation = identifyAliveSuccessors(A, cast<BranchInst>(*I),
4811 *this, AliveSuccessors);
4812 break;
4813 case Instruction::Switch:
4814 UsedAssumedInformation = identifyAliveSuccessors(A, cast<SwitchInst>(*I),
4815 *this, AliveSuccessors);
4816 break;
4817 }
4818
4819 if (UsedAssumedInformation) {
4820 NewToBeExploredFrom.insert(I);
4821 } else if (AliveSuccessors.empty() ||
4822 (I->isTerminator() &&
4823 AliveSuccessors.size() < I->getNumSuccessors())) {
4824 if (KnownDeadEnds.insert(I))
4825 Change = ChangeStatus::CHANGED;
4826 }
4827
4828 LLVM_DEBUG(dbgs() << "[AAIsDead] #AliveSuccessors: "
4829 << AliveSuccessors.size() << " UsedAssumedInformation: "
4830 << UsedAssumedInformation << "\n");
4831
4832 for (const Instruction *AliveSuccessor : AliveSuccessors) {
4833 if (!I->isTerminator()) {
4834 assert(AliveSuccessors.size() == 1 &&
4835 "Non-terminator expected to have a single successor!");
4836 Worklist.push_back(AliveSuccessor);
4837 } else {
4838 // record the assumed live edge
4839 auto Edge = std::make_pair(I->getParent(), AliveSuccessor->getParent());
4840 if (AssumedLiveEdges.insert(Edge).second)
4841 Change = ChangeStatus::CHANGED;
4842 if (assumeLive(A, *AliveSuccessor->getParent()))
4843 Worklist.push_back(AliveSuccessor);
4844 }
4845 }
4846 }
4847
4848 // Check if the content of ToBeExploredFrom changed, ignore the order.
4849 if (NewToBeExploredFrom.size() != ToBeExploredFrom.size() ||
4850 llvm::any_of(NewToBeExploredFrom, [&](const Instruction *I) {
4851 return !ToBeExploredFrom.count(I);
4852 })) {
4853 Change = ChangeStatus::CHANGED;
4854 ToBeExploredFrom = std::move(NewToBeExploredFrom);
4855 }
4856
4857 // If we know everything is live there is no need to query for liveness.
4858 // Instead, indicating a pessimistic fixpoint will cause the state to be
4859 // "invalid" and all queries to be answered conservatively without lookups.
4860 // To be in this state we have to (1) finished the exploration and (3) not
4861 // discovered any non-trivial dead end and (2) not ruled unreachable code
4862 // dead.
4863 if (ToBeExploredFrom.empty() &&
4864 getAnchorScope()->size() == AssumedLiveBlocks.size() &&
4865 llvm::all_of(KnownDeadEnds, [](const Instruction *DeadEndI) {
4866 return DeadEndI->isTerminator() && DeadEndI->getNumSuccessors() == 0;
4867 }))
4868 return indicatePessimisticFixpoint();
4869 return Change;
4870}
4871
4872/// Liveness information for a call sites.
4873struct AAIsDeadCallSite final : AAIsDeadFunction {
4874 AAIsDeadCallSite(const IRPosition &IRP, Attributor &A)
4875 : AAIsDeadFunction(IRP, A) {}
4876
4877 /// See AbstractAttribute::initialize(...).
4878 void initialize(Attributor &A) override {
4879 // TODO: Once we have call site specific value information we can provide
4880 // call site specific liveness information and then it makes
4881 // sense to specialize attributes for call sites instead of
4882 // redirecting requests to the callee.
4883 llvm_unreachable("Abstract attributes for liveness are not "
4884 "supported for call sites yet!");
4885 }
4886
4887 /// See AbstractAttribute::updateImpl(...).
4888 ChangeStatus updateImpl(Attributor &A) override {
4889 return indicatePessimisticFixpoint();
4890 }
4891
4892 /// See AbstractAttribute::trackStatistics()
4893 void trackStatistics() const override {}
4894};
4895} // namespace
4896
4897/// -------------------- Dereferenceable Argument Attribute --------------------
4898
4899namespace {
4900struct AADereferenceableImpl : AADereferenceable {
4901 AADereferenceableImpl(const IRPosition &IRP, Attributor &A)
4902 : AADereferenceable(IRP, A) {}
4903 using StateType = DerefState;
4904
4905 /// See AbstractAttribute::initialize(...).
4906 void initialize(Attributor &A) override {
4907 Value &V = *getAssociatedValue().stripPointerCasts();
4909 A.getAttrs(getIRPosition(),
4910 {Attribute::Dereferenceable, Attribute::DereferenceableOrNull},
4911 Attrs, /* IgnoreSubsumingPositions */ false);
4912 for (const Attribute &Attr : Attrs)
4913 takeKnownDerefBytesMaximum(Attr.getValueAsInt());
4914
4915 // Ensure we initialize the non-null AA (if necessary).
4916 bool IsKnownNonNull;
4917 AA::hasAssumedIRAttr<Attribute::NonNull>(
4918 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNonNull);
4919
4920 bool CanBeNull, CanBeFreed;
4921 takeKnownDerefBytesMaximum(V.getPointerDereferenceableBytes(
4922 A.getDataLayout(), CanBeNull, CanBeFreed));
4923
4924 if (Instruction *CtxI = getCtxI())
4925 followUsesInMBEC(*this, A, getState(), *CtxI);
4926 }
4927
4928 /// See AbstractAttribute::getState()
4929 /// {
4930 StateType &getState() override { return *this; }
4931 const StateType &getState() const override { return *this; }
4932 /// }
4933
4934 /// Helper function for collecting accessed bytes in must-be-executed-context
4935 void addAccessedBytesForUse(Attributor &A, const Use *U, const Instruction *I,
4936 DerefState &State) {
4937 const Value *UseV = U->get();
4938 if (!UseV->getType()->isPointerTy())
4939 return;
4940
4941 std::optional<MemoryLocation> Loc = MemoryLocation::getOrNone(I);
4942 if (!Loc || Loc->Ptr != UseV || !Loc->Size.isPrecise() || I->isVolatile())
4943 return;
4944
4945 int64_t Offset;
4947 Loc->Ptr, Offset, A.getDataLayout(), /*AllowNonInbounds*/ true);
4948 if (Base && Base == &getAssociatedValue())
4949 State.addAccessedBytes(Offset, Loc->Size.getValue());
4950 }
4951
4952 /// See followUsesInMBEC
4953 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
4955 bool IsNonNull = false;
4956 bool TrackUse = false;
4957 int64_t DerefBytes = getKnownNonNullAndDerefBytesForUse(
4958 A, *this, getAssociatedValue(), U, I, IsNonNull, TrackUse);
4959 LLVM_DEBUG(dbgs() << "[AADereferenceable] Deref bytes: " << DerefBytes
4960 << " for instruction " << *I << "\n");
4961
4962 addAccessedBytesForUse(A, U, I, State);
4963 State.takeKnownDerefBytesMaximum(DerefBytes);
4964 return TrackUse;
4965 }
4966
4967 /// See AbstractAttribute::manifest(...).
4968 ChangeStatus manifest(Attributor &A) override {
4969 ChangeStatus Change = AADereferenceable::manifest(A);
4970 bool IsKnownNonNull;
4971 bool IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>(
4972 A, this, getIRPosition(), DepClassTy::NONE, IsKnownNonNull);
4973 if (IsAssumedNonNull &&
4974 A.hasAttr(getIRPosition(), Attribute::DereferenceableOrNull)) {
4975 A.removeAttrs(getIRPosition(), {Attribute::DereferenceableOrNull});
4976 return ChangeStatus::CHANGED;
4977 }
4978 return Change;
4979 }
4980
4981 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
4982 SmallVectorImpl<Attribute> &Attrs) const override {
4983 // TODO: Add *_globally support
4984 bool IsKnownNonNull;
4985 bool IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>(
4986 A, this, getIRPosition(), DepClassTy::NONE, IsKnownNonNull);
4987 if (IsAssumedNonNull)
4989 Ctx, getAssumedDereferenceableBytes()));
4990 else
4992 Ctx, getAssumedDereferenceableBytes()));
4993 }
4994
4995 /// See AbstractAttribute::getAsStr().
4996 const std::string getAsStr(Attributor *A) const override {
4997 if (!getAssumedDereferenceableBytes())
4998 return "unknown-dereferenceable";
4999 bool IsKnownNonNull;
5000 bool IsAssumedNonNull = false;
5001 if (A)
5002 IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>(
5003 *A, this, getIRPosition(), DepClassTy::NONE, IsKnownNonNull);
5004 return std::string("dereferenceable") +
5005 (IsAssumedNonNull ? "" : "_or_null") +
5006 (isAssumedGlobal() ? "_globally" : "") + "<" +
5007 std::to_string(getKnownDereferenceableBytes()) + "-" +
5008 std::to_string(getAssumedDereferenceableBytes()) + ">" +
5009 (!A ? " [non-null is unknown]" : "");
5010 }
5011};
5012
5013/// Dereferenceable attribute for a floating value.
5014struct AADereferenceableFloating : AADereferenceableImpl {
5015 AADereferenceableFloating(const IRPosition &IRP, Attributor &A)
5016 : AADereferenceableImpl(IRP, A) {}
5017
5018 /// See AbstractAttribute::updateImpl(...).
5019 ChangeStatus updateImpl(Attributor &A) override {
5020 bool Stripped;
5021 bool UsedAssumedInformation = false;
5023 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
5024 AA::AnyScope, UsedAssumedInformation)) {
5025 Values.push_back({getAssociatedValue(), getCtxI()});
5026 Stripped = false;
5027 } else {
5028 Stripped = Values.size() != 1 ||
5029 Values.front().getValue() != &getAssociatedValue();
5030 }
5031
5032 const DataLayout &DL = A.getDataLayout();
5033 DerefState T;
5034
5035 auto VisitValueCB = [&](const Value &V) -> bool {
5036 unsigned IdxWidth =
5037 DL.getIndexSizeInBits(V.getType()->getPointerAddressSpace());
5038 APInt Offset(IdxWidth, 0);
5040 A, *this, &V, DL, Offset, /* GetMinOffset */ false,
5041 /* AllowNonInbounds */ true);
5042
5043 const auto *AA = A.getAAFor<AADereferenceable>(
5044 *this, IRPosition::value(*Base), DepClassTy::REQUIRED);
5045 int64_t DerefBytes = 0;
5046 if (!AA || (!Stripped && this == AA)) {
5047 // Use IR information if we did not strip anything.
5048 // TODO: track globally.
5049 bool CanBeNull, CanBeFreed;
5050 DerefBytes =
5051 Base->getPointerDereferenceableBytes(DL, CanBeNull, CanBeFreed);
5052 T.GlobalState.indicatePessimisticFixpoint();
5053 } else {
5054 const DerefState &DS = AA->getState();
5055 DerefBytes = DS.DerefBytesState.getAssumed();
5056 T.GlobalState &= DS.GlobalState;
5057 }
5058
5059 // For now we do not try to "increase" dereferenceability due to negative
5060 // indices as we first have to come up with code to deal with loops and
5061 // for overflows of the dereferenceable bytes.
5062 int64_t OffsetSExt = Offset.getSExtValue();
5063 if (OffsetSExt < 0)
5064 OffsetSExt = 0;
5065
5066 T.takeAssumedDerefBytesMinimum(
5067 std::max(int64_t(0), DerefBytes - OffsetSExt));
5068
5069 if (this == AA) {
5070 if (!Stripped) {
5071 // If nothing was stripped IR information is all we got.
5072 T.takeKnownDerefBytesMaximum(
5073 std::max(int64_t(0), DerefBytes - OffsetSExt));
5074 T.indicatePessimisticFixpoint();
5075 } else if (OffsetSExt > 0) {
5076 // If something was stripped but there is circular reasoning we look
5077 // for the offset. If it is positive we basically decrease the
5078 // dereferenceable bytes in a circular loop now, which will simply
5079 // drive them down to the known value in a very slow way which we
5080 // can accelerate.
5081 T.indicatePessimisticFixpoint();
5082 }
5083 }
5084
5085 return T.isValidState();
5086 };
5087
5088 for (const auto &VAC : Values)
5089 if (!VisitValueCB(*VAC.getValue()))
5090 return indicatePessimisticFixpoint();
5091
5092 return clampStateAndIndicateChange(getState(), T);
5093 }
5094
5095 /// See AbstractAttribute::trackStatistics()
5096 void trackStatistics() const override {
5097 STATS_DECLTRACK_FLOATING_ATTR(dereferenceable)
5098 }
5099};
5100
5101/// Dereferenceable attribute for a return value.
5102struct AADereferenceableReturned final
5103 : AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl> {
5104 using Base =
5105 AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl>;
5106 AADereferenceableReturned(const IRPosition &IRP, Attributor &A)
5107 : Base(IRP, A) {}
5108
5109 /// See AbstractAttribute::trackStatistics()
5110 void trackStatistics() const override {
5111 STATS_DECLTRACK_FNRET_ATTR(dereferenceable)
5112 }
5113};
5114
5115/// Dereferenceable attribute for an argument
5116struct AADereferenceableArgument final
5117 : AAArgumentFromCallSiteArguments<AADereferenceable,
5118 AADereferenceableImpl> {
5119 using Base =
5120 AAArgumentFromCallSiteArguments<AADereferenceable, AADereferenceableImpl>;
5121 AADereferenceableArgument(const IRPosition &IRP, Attributor &A)
5122 : Base(IRP, A) {}
5123
5124 /// See AbstractAttribute::trackStatistics()
5125 void trackStatistics() const override {
5126 STATS_DECLTRACK_ARG_ATTR(dereferenceable)
5127 }
5128};
5129
5130/// Dereferenceable attribute for a call site argument.
5131struct AADereferenceableCallSiteArgument final : AADereferenceableFloating {
5132 AADereferenceableCallSiteArgument(const IRPosition &IRP, Attributor &A)
5133 : AADereferenceableFloating(IRP, A) {}
5134
5135 /// See AbstractAttribute::trackStatistics()
5136 void trackStatistics() const override {
5137 STATS_DECLTRACK_CSARG_ATTR(dereferenceable)
5138 }
5139};
5140
5141/// Dereferenceable attribute deduction for a call site return value.
5142struct AADereferenceableCallSiteReturned final
5143 : AACalleeToCallSite<AADereferenceable, AADereferenceableImpl> {
5144 using Base = AACalleeToCallSite<AADereferenceable, AADereferenceableImpl>;
5145 AADereferenceableCallSiteReturned(const IRPosition &IRP, Attributor &A)
5146 : Base(IRP, A) {}
5147
5148 /// See AbstractAttribute::trackStatistics()
5149 void trackStatistics() const override {
5150 STATS_DECLTRACK_CS_ATTR(dereferenceable);
5151 }
5152};
5153} // namespace
5154
5155// ------------------------ Align Argument Attribute ------------------------
5156
5157namespace {
5158static unsigned getKnownAlignForUse(Attributor &A, AAAlign &QueryingAA,
5159 Value &AssociatedValue, const Use *U,
5160 const Instruction *I, bool &TrackUse) {
5161 // We need to follow common pointer manipulation uses to the accesses they
5162 // feed into.
5163 if (isa<CastInst>(I)) {
5164 // Follow all but ptr2int casts.
5165 TrackUse = !isa<PtrToIntInst>(I);
5166 return 0;
5167 }
5168 if (auto *GEP = dyn_cast<GetElementPtrInst>(I)) {
5169 if (GEP->hasAllConstantIndices())
5170 TrackUse = true;
5171 return 0;
5172 }
5173
5174 MaybeAlign MA;
5175 if (const auto *CB = dyn_cast<CallBase>(I)) {
5176 if (CB->isBundleOperand(U) || CB->isCallee(U))
5177 return 0;
5178
5179 unsigned ArgNo = CB->getArgOperandNo(U);
5180 IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo);
5181 // As long as we only use known information there is no need to track
5182 // dependences here.
5183 auto *AlignAA = A.getAAFor<AAAlign>(QueryingAA, IRP, DepClassTy::NONE);
5184 if (AlignAA)
5185 MA = MaybeAlign(AlignAA->getKnownAlign());
5186 }
5187
5188 const DataLayout &DL = A.getDataLayout();
5189 const Value *UseV = U->get();
5190 if (auto *SI = dyn_cast<StoreInst>(I)) {
5191 if (SI->getPointerOperand() == UseV)
5192 MA = SI->getAlign();
5193 } else if (auto *LI = dyn_cast<LoadInst>(I)) {
5194 if (LI->getPointerOperand() == UseV)
5195 MA = LI->getAlign();
5196 } else if (auto *AI = dyn_cast<AtomicRMWInst>(I)) {
5197 if (AI->getPointerOperand() == UseV)
5198 MA = AI->getAlign();
5199 } else if (auto *AI = dyn_cast<AtomicCmpXchgInst>(I)) {
5200 if (AI->getPointerOperand() == UseV)
5201 MA = AI->getAlign();
5202 }
5203
5204 if (!MA || *MA <= QueryingAA.getKnownAlign())
5205 return 0;
5206
5207 unsigned Alignment = MA->value();
5208 int64_t Offset;
5209
5210 if (const Value *Base = GetPointerBaseWithConstantOffset(UseV, Offset, DL)) {
5211 if (Base == &AssociatedValue) {
5212 // BasePointerAddr + Offset = Alignment * Q for some integer Q.
5213 // So we can say that the maximum power of two which is a divisor of
5214 // gcd(Offset, Alignment) is an alignment.
5215
5216 uint32_t gcd = std::gcd(uint32_t(abs((int32_t)Offset)), Alignment);
5217 Alignment = llvm::bit_floor(gcd);
5218 }
5219 }
5220
5221 return Alignment;
5222}
5223
5224struct AAAlignImpl : AAAlign {
5225 AAAlignImpl(const IRPosition &IRP, Attributor &A) : AAAlign(IRP, A) {}
5226
5227 /// See AbstractAttribute::initialize(...).
5228 void initialize(Attributor &A) override {
5230 A.getAttrs(getIRPosition(), {Attribute::Alignment}, Attrs);
5231 for (const Attribute &Attr : Attrs)
5232 takeKnownMaximum(Attr.getValueAsInt());
5233
5234 Value &V = *getAssociatedValue().stripPointerCasts();
5235 takeKnownMaximum(V.getPointerAlignment(A.getDataLayout()).value());
5236
5237 if (Instruction *CtxI = getCtxI())
5238 followUsesInMBEC(*this, A, getState(), *CtxI);
5239 }
5240
5241 /// See AbstractAttribute::manifest(...).
5242 ChangeStatus manifest(Attributor &A) override {
5243 ChangeStatus LoadStoreChanged = ChangeStatus::UNCHANGED;
5244
5245 // Check for users that allow alignment annotations.
5246 Value &AssociatedValue = getAssociatedValue();
5247 for (const Use &U : AssociatedValue.uses()) {
5248 if (auto *SI = dyn_cast<StoreInst>(U.getUser())) {
5249 if (SI->getPointerOperand() == &AssociatedValue)
5250 if (SI->getAlign() < getAssumedAlign()) {
5251 STATS_DECLTRACK(AAAlign, Store,
5252 "Number of times alignment added to a store");
5253 SI->setAlignment(getAssumedAlign());
5254 LoadStoreChanged = ChangeStatus::CHANGED;
5255 }
5256 } else if (auto *LI = dyn_cast<LoadInst>(U.getUser())) {
5257 if (LI->getPointerOperand() == &AssociatedValue)
5258 if (LI->getAlign() < getAssumedAlign()) {
5259 LI->setAlignment(getAssumedAlign());
5261 "Number of times alignment added to a load");
5262 LoadStoreChanged = ChangeStatus::CHANGED;
5263 }
5264 }
5265 }
5266
5267 ChangeStatus Changed = AAAlign::manifest(A);
5268
5269 Align InheritAlign =
5270 getAssociatedValue().getPointerAlignment(A.getDataLayout());
5271 if (InheritAlign >= getAssumedAlign())
5272 return LoadStoreChanged;
5273 return Changed | LoadStoreChanged;
5274 }
5275
5276 // TODO: Provide a helper to determine the implied ABI alignment and check in
5277 // the existing manifest method and a new one for AAAlignImpl that value
5278 // to avoid making the alignment explicit if it did not improve.
5279
5280 /// See AbstractAttribute::getDeducedAttributes
5281 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
5282 SmallVectorImpl<Attribute> &Attrs) const override {
5283 if (getAssumedAlign() > 1)
5284 Attrs.emplace_back(
5285 Attribute::getWithAlignment(Ctx, Align(getAssumedAlign())));
5286 }
5287
5288 /// See followUsesInMBEC
5289 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
5290 AAAlign::StateType &State) {
5291 bool TrackUse = false;
5292
5293 unsigned int KnownAlign =
5294 getKnownAlignForUse(A, *this, getAssociatedValue(), U, I, TrackUse);
5295 State.takeKnownMaximum(KnownAlign);
5296
5297 return TrackUse;
5298 }
5299
5300 /// See AbstractAttribute::getAsStr().
5301 const std::string getAsStr(Attributor *A) const override {
5302 return "align<" + std::to_string(getKnownAlign().value()) + "-" +
5303 std::to_string(getAssumedAlign().value()) + ">";
5304 }
5305};
5306
5307/// Align attribute for a floating value.
5308struct AAAlignFloating : AAAlignImpl {
5309 AAAlignFloating(const IRPosition &IRP, Attributor &A) : AAAlignImpl(IRP, A) {}
5310
5311 /// See AbstractAttribute::updateImpl(...).
5312 ChangeStatus updateImpl(Attributor &A) override {
5313 const DataLayout &DL = A.getDataLayout();
5314
5315 bool Stripped;
5316 bool UsedAssumedInformation = false;
5318 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
5319 AA::AnyScope, UsedAssumedInformation)) {
5320 Values.push_back({getAssociatedValue(), getCtxI()});
5321 Stripped = false;
5322 } else {
5323 Stripped = Values.size() != 1 ||
5324 Values.front().getValue() != &getAssociatedValue();
5325 }
5326
5327 StateType T;
5328 auto VisitValueCB = [&](Value &V) -> bool {
5329 if (isa<UndefValue>(V) || isa<ConstantPointerNull>(V))
5330 return true;
5331 const auto *AA = A.getAAFor<AAAlign>(*this, IRPosition::value(V),
5332 DepClassTy::REQUIRED);
5333 if (!AA || (!Stripped && this == AA)) {
5334 int64_t Offset;
5335 unsigned Alignment = 1;
5336 if (const Value *Base =
5338 // TODO: Use AAAlign for the base too.
5339 Align PA = Base->getPointerAlignment(DL);
5340 // BasePointerAddr + Offset = Alignment * Q for some integer Q.
5341 // So we can say that the maximum power of two which is a divisor of
5342 // gcd(Offset, Alignment) is an alignment.
5343
5344 uint32_t gcd =
5345 std::gcd(uint32_t(abs((int32_t)Offset)), uint32_t(PA.value()));
5346 Alignment = llvm::bit_floor(gcd);
5347 } else {
5348 Alignment = V.getPointerAlignment(DL).value();
5349 }
5350 // Use only IR information if we did not strip anything.
5351 T.takeKnownMaximum(Alignment);
5352 T.indicatePessimisticFixpoint();
5353 } else {
5354 // Use abstract attribute information.
5355 const AAAlign::StateType &DS = AA->getState();
5356 T ^= DS;
5357 }
5358 return T.isValidState();
5359 };
5360
5361 for (const auto &VAC : Values) {
5362 if (!VisitValueCB(*VAC.getValue()))
5363 return indicatePessimisticFixpoint();
5364 }
5365
5366 // TODO: If we know we visited all incoming values, thus no are assumed
5367 // dead, we can take the known information from the state T.
5368 return clampStateAndIndicateChange(getState(), T);
5369 }
5370
5371 /// See AbstractAttribute::trackStatistics()
5372 void trackStatistics() const override { STATS_DECLTRACK_FLOATING_ATTR(align) }
5373};
5374
5375/// Align attribute for function return value.
5376struct AAAlignReturned final
5377 : AAReturnedFromReturnedValues<AAAlign, AAAlignImpl> {
5378 using Base = AAReturnedFromReturnedValues<AAAlign, AAAlignImpl>;
5379 AAAlignReturned(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {}
5380
5381 /// See AbstractAttribute::trackStatistics()
5382 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(aligned) }
5383};
5384
5385/// Align attribute for function argument.
5386struct AAAlignArgument final
5387 : AAArgumentFromCallSiteArguments<AAAlign, AAAlignImpl> {
5388 using Base = AAArgumentFromCallSiteArguments<AAAlign, AAAlignImpl>;
5389 AAAlignArgument(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {}
5390
5391 /// See AbstractAttribute::manifest(...).
5392 ChangeStatus manifest(Attributor &A) override {
5393 // If the associated argument is involved in a must-tail call we give up
5394 // because we would need to keep the argument alignments of caller and
5395 // callee in-sync. Just does not seem worth the trouble right now.
5396 if (A.getInfoCache().isInvolvedInMustTailCall(*getAssociatedArgument()))
5397 return ChangeStatus::UNCHANGED;
5398 return Base::manifest(A);
5399 }
5400
5401 /// See AbstractAttribute::trackStatistics()
5402 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(aligned) }
5403};
5404
5405struct AAAlignCallSiteArgument final : AAAlignFloating {
5406 AAAlignCallSiteArgument(const IRPosition &IRP, Attributor &A)
5407 : AAAlignFloating(IRP, A) {}
5408
5409 /// See AbstractAttribute::manifest(...).
5410 ChangeStatus manifest(Attributor &A) override {
5411 // If the associated argument is involved in a must-tail call we give up
5412 // because we would need to keep the argument alignments of caller and
5413 // callee in-sync. Just does not seem worth the trouble right now.
5414 if (Argument *Arg = getAssociatedArgument())
5415 if (A.getInfoCache().isInvolvedInMustTailCall(*Arg))
5416 return ChangeStatus::UNCHANGED;
5417 ChangeStatus Changed = AAAlignImpl::manifest(A);
5418 Align InheritAlign =
5419 getAssociatedValue().getPointerAlignment(A.getDataLayout());
5420 if (InheritAlign >= getAssumedAlign())
5421 Changed = ChangeStatus::UNCHANGED;
5422 return Changed;
5423 }
5424
5425 /// See AbstractAttribute::updateImpl(Attributor &A).
5426 ChangeStatus updateImpl(Attributor &A) override {
5427 ChangeStatus Changed = AAAlignFloating::updateImpl(A);
5428 if (Argument *Arg = getAssociatedArgument()) {
5429 // We only take known information from the argument
5430 // so we do not need to track a dependence.
5431 const auto *ArgAlignAA = A.getAAFor<AAAlign>(
5432 *this, IRPosition::argument(*Arg), DepClassTy::NONE);
5433 if (ArgAlignAA)
5434 takeKnownMaximum(ArgAlignAA->getKnownAlign().value());
5435 }
5436 return Changed;
5437 }
5438
5439 /// See AbstractAttribute::trackStatistics()
5440 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(aligned) }
5441};
5442
5443/// Align attribute deduction for a call site return value.
5444struct AAAlignCallSiteReturned final
5445 : AACalleeToCallSite<AAAlign, AAAlignImpl> {
5446 using Base = AACalleeToCallSite<AAAlign, AAAlignImpl>;
5447 AAAlignCallSiteReturned(const IRPosition &IRP, Attributor &A)
5448 : Base(IRP, A) {}
5449
5450 /// See AbstractAttribute::trackStatistics()
5451 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(align); }
5452};
5453} // namespace
5454
5455/// ------------------ Function No-Return Attribute ----------------------------
5456namespace {
5457struct AANoReturnImpl : public AANoReturn {
5458 AANoReturnImpl(const IRPosition &IRP, Attributor &A) : AANoReturn(IRP, A) {}
5459
5460 /// See AbstractAttribute::initialize(...).
5461 void initialize(Attributor &A) override {
5462 bool IsKnown;
5463 assert(!AA::hasAssumedIRAttr<Attribute::NoReturn>(
5464 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
5465 (void)IsKnown;
5466 }
5467
5468 /// See AbstractAttribute::getAsStr().
5469 const std::string getAsStr(Attributor *A) const override {
5470 return getAssumed() ? "noreturn" : "may-return";
5471 }
5472
5473 /// See AbstractAttribute::updateImpl(Attributor &A).
5474 ChangeStatus updateImpl(Attributor &A) override {
5475 auto CheckForNoReturn = [](Instruction &) { return false; };
5476 bool UsedAssumedInformation = false;
5477 if (!A.checkForAllInstructions(CheckForNoReturn, *this,
5478 {(unsigned)Instruction::Ret},
5479 UsedAssumedInformation))
5480 return indicatePessimisticFixpoint();
5481 return ChangeStatus::UNCHANGED;
5482 }
5483};
5484
5485struct AANoReturnFunction final : AANoReturnImpl {
5486 AANoReturnFunction(const IRPosition &IRP, Attributor &A)
5487 : AANoReturnImpl(IRP, A) {}
5488
5489 /// See AbstractAttribute::trackStatistics()
5490 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(noreturn) }
5491};
5492
5493/// NoReturn attribute deduction for a call sites.
5494struct AANoReturnCallSite final
5495 : AACalleeToCallSite<AANoReturn, AANoReturnImpl> {
5496 AANoReturnCallSite(const IRPosition &IRP, Attributor &A)
5497 : AACalleeToCallSite<AANoReturn, AANoReturnImpl>(IRP, A) {}
5498
5499 /// See AbstractAttribute::trackStatistics()
5500 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(noreturn); }
5501};
5502} // namespace
5503
5504/// ----------------------- Instance Info ---------------------------------
5505
5506namespace {
5507/// A class to hold the state of for no-capture attributes.
5508struct AAInstanceInfoImpl : public AAInstanceInfo {
5509 AAInstanceInfoImpl(const IRPosition &IRP, Attributor &A)
5510 : AAInstanceInfo(IRP, A) {}
5511
5512 /// See AbstractAttribute::initialize(...).
5513 void initialize(Attributor &A) override {
5514 Value &V = getAssociatedValue();
5515 if (auto *C = dyn_cast<Constant>(&V)) {
5516 if (C->isThreadDependent())
5517 indicatePessimisticFixpoint();
5518 else
5519 indicateOptimisticFixpoint();
5520 return;
5521 }
5522 if (auto *CB = dyn_cast<CallBase>(&V))
5523 if (CB->arg_size() == 0 && !CB->mayHaveSideEffects() &&
5524 !CB->mayReadFromMemory()) {
5525 indicateOptimisticFixpoint();
5526 return;
5527 }
5528 if (auto *I = dyn_cast<Instruction>(&V)) {
5529 const auto *CI =
5530 A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>(
5531 *I->getFunction());
5532 if (mayBeInCycle(CI, I, /* HeaderOnly */ false)) {
5533 indicatePessimisticFixpoint();
5534 return;
5535 }
5536 }
5537 }
5538
5539 /// See AbstractAttribute::updateImpl(...).
5540 ChangeStatus updateImpl(Attributor &A) override {
5541 ChangeStatus Changed = ChangeStatus::UNCHANGED;
5542
5543 Value &V = getAssociatedValue();
5544 const Function *Scope = nullptr;
5545 if (auto *I = dyn_cast<Instruction>(&V))
5546 Scope = I->getFunction();
5547 if (auto *A = dyn_cast<Argument>(&V)) {
5548 Scope = A->getParent();
5549 if (!Scope->hasLocalLinkage())
5550 return Changed;
5551 }
5552 if (!Scope)
5553 return indicateOptimisticFixpoint();
5554
5555 bool IsKnownNoRecurse;
5556 if (AA::hasAssumedIRAttr<Attribute::NoRecurse>(
5557 A, this, IRPosition::function(*Scope), DepClassTy::OPTIONAL,
5558 IsKnownNoRecurse))
5559 return Changed;
5560
5561 auto UsePred = [&](const Use &U, bool &Follow) {
5562 const Instruction *UserI = dyn_cast<Instruction>(U.getUser());
5563 if (!UserI || isa<GetElementPtrInst>(UserI) || isa<CastInst>(UserI) ||
5564 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) {
5565 Follow = true;
5566 return true;
5567 }
5568 if (isa<LoadInst>(UserI) || isa<CmpInst>(UserI) ||
5569 (isa<StoreInst>(UserI) &&
5570 cast<StoreInst>(UserI)->getValueOperand() != U.get()))
5571 return true;
5572 if (auto *CB = dyn_cast<CallBase>(UserI)) {
5573 // This check is not guaranteeing uniqueness but for now that we cannot
5574 // end up with two versions of \p U thinking it was one.
5575 auto *Callee = dyn_cast_if_present<Function>(CB->getCalledOperand());
5576 if (!Callee || !Callee->hasLocalLinkage())
5577 return true;
5578 if (!CB->isArgOperand(&U))
5579 return false;
5580 const auto *ArgInstanceInfoAA = A.getAAFor<AAInstanceInfo>(
5582 DepClassTy::OPTIONAL);
5583 if (!ArgInstanceInfoAA ||
5584 !ArgInstanceInfoAA->isAssumedUniqueForAnalysis())
5585 return false;
5586 // If this call base might reach the scope again we might forward the
5587 // argument back here. This is very conservative.
5589 A, *CB, *Scope, *this, /* ExclusionSet */ nullptr,
5590 [Scope](const Function &Fn) { return &Fn != Scope; }))
5591 return false;
5592 return true;
5593 }
5594 return false;
5595 };
5596
5597 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) {
5598 if (auto *SI = dyn_cast<StoreInst>(OldU.getUser())) {
5599 auto *Ptr = SI->getPointerOperand()->stripPointerCasts();
5600 if ((isa<AllocaInst>(Ptr) || isNoAliasCall(Ptr)) &&
5601 AA::isDynamicallyUnique(A, *this, *Ptr))
5602 return true;
5603 }
5604 return false;
5605 };
5606
5607 if (!A.checkForAllUses(UsePred, *this, V, /* CheckBBLivenessOnly */ true,
5608 DepClassTy::OPTIONAL,
5609 /* IgnoreDroppableUses */ true, EquivalentUseCB))
5610 return indicatePessimisticFixpoint();
5611
5612 return Changed;
5613 }
5614
5615 /// See AbstractState::getAsStr().
5616 const std::string getAsStr(Attributor *A) const override {
5617 return isAssumedUniqueForAnalysis() ? "<unique [fAa]>" : "<unknown>";
5618 }
5619
5620 /// See AbstractAttribute::trackStatistics()
5621 void trackStatistics() const override {}
5622};
5623
5624/// InstanceInfo attribute for floating values.
5625struct AAInstanceInfoFloating : AAInstanceInfoImpl {
5626 AAInstanceInfoFloating(const IRPosition &IRP, Attributor &A)
5627 : AAInstanceInfoImpl(IRP, A) {}
5628};
5629
5630/// NoCapture attribute for function arguments.
5631struct AAInstanceInfoArgument final : AAInstanceInfoFloating {
5632 AAInstanceInfoArgument(const IRPosition &IRP, Attributor &A)
5633 : AAInstanceInfoFloating(IRP, A) {}
5634};
5635
5636/// InstanceInfo attribute for call site arguments.
5637struct AAInstanceInfoCallSiteArgument final : AAInstanceInfoImpl {
5638 AAInstanceInfoCallSiteArgument(const IRPosition &IRP, Attributor &A)
5639 : AAInstanceInfoImpl(IRP, A) {}
5640
5641 /// See AbstractAttribute::updateImpl(...).
5642 ChangeStatus updateImpl(Attributor &A) override {
5643 // TODO: Once we have call site specific value information we can provide
5644 // call site specific liveness information and then it makes
5645 // sense to specialize attributes for call sites arguments instead of
5646 // redirecting requests to the callee argument.
5647 Argument *Arg = getAssociatedArgument();
5648 if (!Arg)
5649 return indicatePessimisticFixpoint();
5650 const IRPosition &ArgPos = IRPosition::argument(*Arg);
5651 auto *ArgAA =
5652 A.getAAFor<AAInstanceInfo>(*this, ArgPos, DepClassTy::REQUIRED);
5653 if (!ArgAA)
5654 return indicatePessimisticFixpoint();
5655 return clampStateAndIndicateChange(getState(), ArgAA->getState());
5656 }
5657};
5658
5659/// InstanceInfo attribute for function return value.
5660struct AAInstanceInfoReturned final : AAInstanceInfoImpl {
5661 AAInstanceInfoReturned(const IRPosition &IRP, Attributor &A)
5662 : AAInstanceInfoImpl(IRP, A) {
5663 llvm_unreachable("InstanceInfo is not applicable to function returns!");
5664 }
5665
5666 /// See AbstractAttribute::initialize(...).
5667 void initialize(Attributor &A) override {
5668 llvm_unreachable("InstanceInfo is not applicable to function returns!");
5669 }
5670
5671 /// See AbstractAttribute::updateImpl(...).
5672 ChangeStatus updateImpl(Attributor &A) override {
5673 llvm_unreachable("InstanceInfo is not applicable to function returns!");
5674 }
5675};
5676
5677/// InstanceInfo attribute deduction for a call site return value.
5678struct AAInstanceInfoCallSiteReturned final : AAInstanceInfoFloating {
5679 AAInstanceInfoCallSiteReturned(const IRPosition &IRP, Attributor &A)
5680 : AAInstanceInfoFloating(IRP, A) {}
5681};
5682} // namespace
5683
5684/// ----------------------- Variable Capturing ---------------------------------
5686 Attribute::AttrKind ImpliedAttributeKind,
5687 bool IgnoreSubsumingPositions) {
5688 assert(ImpliedAttributeKind == Attribute::NoCapture &&
5689 "Unexpected attribute kind");
5690 Value &V = IRP.getAssociatedValue();
5691 if (!IRP.isArgumentPosition())
5692 return V.use_empty();
5693
5694 // You cannot "capture" null in the default address space.
5695 //
5696 // FIXME: This should use NullPointerIsDefined to account for the function
5697 // attribute.
5698 if (isa<UndefValue>(V) || (isa<ConstantPointerNull>(V) &&
5699 V.getType()->getPointerAddressSpace() == 0)) {
5700 return true;
5701 }
5702
5703 if (A.hasAttr(IRP, {Attribute::NoCapture},
5704 /* IgnoreSubsumingPositions */ true, Attribute::NoCapture))
5705 return true;
5706
5707 if (IRP.getPositionKind() == IRP_CALL_SITE_ARGUMENT)
5708 if (Argument *Arg = IRP.getAssociatedArgument())
5709 if (A.hasAttr(IRPosition::argument(*Arg),
5710 {Attribute::NoCapture, Attribute::ByVal},
5711 /* IgnoreSubsumingPositions */ true)) {
5712 A.manifestAttrs(IRP,
5713 Attribute::get(V.getContext(), Attribute::NoCapture));
5714 return true;
5715 }
5716
5717 if (const Function *F = IRP.getAssociatedFunction()) {
5718 // Check what state the associated function can actually capture.
5720 determineFunctionCaptureCapabilities(IRP, *F, State);
5721 if (State.isKnown(NO_CAPTURE)) {
5722 A.manifestAttrs(IRP,
5723 Attribute::get(V.getContext(), Attribute::NoCapture));
5724 return true;
5725 }
5726 }
5727
5728 return false;
5729}
5730
5731/// Set the NOT_CAPTURED_IN_MEM and NOT_CAPTURED_IN_RET bits in \p Known
5732/// depending on the ability of the function associated with \p IRP to capture
5733/// state in memory and through "returning/throwing", respectively.
5735 const Function &F,
5736 BitIntegerState &State) {
5737 // TODO: Once we have memory behavior attributes we should use them here.
5738
5739 // If we know we cannot communicate or write to memory, we do not care about
5740 // ptr2int anymore.
5741 bool ReadOnly = F.onlyReadsMemory();
5742 bool NoThrow = F.doesNotThrow();
5743 bool IsVoidReturn = F.getReturnType()->isVoidTy();
5744 if (ReadOnly && NoThrow && IsVoidReturn) {
5745 State.addKnownBits(NO_CAPTURE);
5746 return;
5747 }
5748
5749 // A function cannot capture state in memory if it only reads memory, it can
5750 // however return/throw state and the state might be influenced by the
5751 // pointer value, e.g., loading from a returned pointer might reveal a bit.
5752 if (ReadOnly)
5753 State.addKnownBits(NOT_CAPTURED_IN_MEM);
5754
5755 // A function cannot communicate state back if it does not through
5756 // exceptions and doesn not return values.
5757 if (NoThrow && IsVoidReturn)
5758 State.addKnownBits(NOT_CAPTURED_IN_RET);
5759
5760 // Check existing "returned" attributes.
5761 int ArgNo = IRP.getCalleeArgNo();
5762 if (!NoThrow || ArgNo < 0 ||
5763 !F.getAttributes().hasAttrSomewhere(Attribute::Returned))
5764 return;
5765
5766 for (unsigned U = 0, E = F.arg_size(); U < E; ++U)
5767 if (F.hasParamAttribute(U, Attribute::Returned)) {
5768 if (U == unsigned(ArgNo))
5769 State.removeAssumedBits(NOT_CAPTURED_IN_RET);
5770 else if (ReadOnly)
5771 State.addKnownBits(NO_CAPTURE);
5772 else
5773 State.addKnownBits(NOT_CAPTURED_IN_RET);
5774 break;
5775 }
5776}
5777
5778namespace {
5779/// A class to hold the state of for no-capture attributes.
5780struct AANoCaptureImpl : public AANoCapture {
5781 AANoCaptureImpl(const IRPosition &IRP, Attributor &A) : AANoCapture(IRP, A) {}
5782
5783 /// See AbstractAttribute::initialize(...).
5784 void initialize(Attributor &A) override {
5785 bool IsKnown;
5786 assert(!AA::hasAssumedIRAttr<Attribute::NoCapture>(
5787 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
5788 (void)IsKnown;
5789 }
5790
5791 /// See AbstractAttribute::updateImpl(...).
5792 ChangeStatus updateImpl(Attributor &A) override;
5793
5794 /// see AbstractAttribute::isAssumedNoCaptureMaybeReturned(...).
5795 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
5796 SmallVectorImpl<Attribute> &Attrs) const override {
5797 if (!isAssumedNoCaptureMaybeReturned())
5798 return;
5799
5800 if (isArgumentPosition()) {
5801 if (isAssumedNoCapture())
5802 Attrs.emplace_back(Attribute::get(Ctx, Attribute::NoCapture));
5803 else if (ManifestInternal)
5804 Attrs.emplace_back(Attribute::get(Ctx, "no-capture-maybe-returned"));
5805 }
5806 }
5807
5808 /// See AbstractState::getAsStr().
5809 const std::string getAsStr(Attributor *A) const override {
5810 if (isKnownNoCapture())
5811 return "known not-captured";
5812 if (isAssumedNoCapture())
5813 return "assumed not-captured";
5814 if (isKnownNoCaptureMaybeReturned())
5815 return "known not-captured-maybe-returned";
5816 if (isAssumedNoCaptureMaybeReturned())
5817 return "assumed not-captured-maybe-returned";
5818 return "assumed-captured";
5819 }
5820
5821 /// Check the use \p U and update \p State accordingly. Return true if we
5822 /// should continue to update the state.
5823 bool checkUse(Attributor &A, AANoCapture::StateType &State, const Use &U,
5824 bool &Follow) {
5825 Instruction *UInst = cast<Instruction>(U.getUser());
5826 LLVM_DEBUG(dbgs() << "[AANoCapture] Check use: " << *U.get() << " in "
5827 << *UInst << "\n");
5828
5829 // Deal with ptr2int by following uses.
5830 if (isa<PtrToIntInst>(UInst)) {
5831 LLVM_DEBUG(dbgs() << " - ptr2int assume the worst!\n");
5832 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
5833 /* Return */ true);
5834 }
5835
5836 // For stores we already checked if we can follow them, if they make it
5837 // here we give up.
5838 if (isa<StoreInst>(UInst))
5839 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
5840 /* Return */ true);
5841
5842 // Explicitly catch return instructions.
5843 if (isa<ReturnInst>(UInst)) {
5844 if (UInst->getFunction() == getAnchorScope())
5845 return isCapturedIn(State, /* Memory */ false, /* Integer */ false,
5846 /* Return */ true);
5847 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
5848 /* Return */ true);
5849 }
5850
5851 // For now we only use special logic for call sites. However, the tracker
5852 // itself knows about a lot of other non-capturing cases already.
5853 auto *CB = dyn_cast<CallBase>(UInst);
5854 if (!CB || !CB->isArgOperand(&U))
5855 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
5856 /* Return */ true);
5857
5858 unsigned ArgNo = CB->getArgOperandNo(&U);
5859 const IRPosition &CSArgPos = IRPosition::callsite_argument(*CB, ArgNo);
5860 // If we have a abstract no-capture attribute for the argument we can use
5861 // it to justify a non-capture attribute here. This allows recursion!
5862 bool IsKnownNoCapture;
5863 const AANoCapture *ArgNoCaptureAA = nullptr;
5864 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::NoCapture>(
5865 A, this, CSArgPos, DepClassTy::REQUIRED, IsKnownNoCapture, false,
5866 &ArgNoCaptureAA);
5867 if (IsAssumedNoCapture)
5868 return isCapturedIn(State, /* Memory */ false, /* Integer */ false,
5869 /* Return */ false);
5870 if (ArgNoCaptureAA && ArgNoCaptureAA->isAssumedNoCaptureMaybeReturned()) {
5871 Follow = true;
5872 return isCapturedIn(State, /* Memory */ false, /* Integer */ false,
5873 /* Return */ false);
5874 }
5875
5876 // Lastly, we could not find a reason no-capture can be assumed so we don't.
5877 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
5878 /* Return */ true);
5879 }
5880
5881 /// Update \p State according to \p CapturedInMem, \p CapturedInInt, and
5882 /// \p CapturedInRet, then return true if we should continue updating the
5883 /// state.
5884 static bool isCapturedIn(AANoCapture::StateType &State, bool CapturedInMem,
5885 bool CapturedInInt, bool CapturedInRet) {
5886 LLVM_DEBUG(dbgs() << " - captures [Mem " << CapturedInMem << "|Int "
5887 << CapturedInInt << "|Ret " << CapturedInRet << "]\n");
5888 if (CapturedInMem)
5889 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_MEM);
5890 if (CapturedInInt)
5891 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_INT);
5892 if (CapturedInRet)
5893 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_RET);
5894 return State.isAssumed(AANoCapture::NO_CAPTURE_MAYBE_RETURNED);
5895 }
5896};
5897
5898ChangeStatus AANoCaptureImpl::updateImpl(Attributor &A) {
5899 const IRPosition &IRP = getIRPosition();
5900 Value *V = isArgumentPosition() ? IRP.getAssociatedArgument()
5901 : &IRP.getAssociatedValue();
5902 if (!V)
5903 return indicatePessimisticFixpoint();
5904
5905 const Function *F =
5906 isArgumentPosition() ? IRP.getAssociatedFunction() : IRP.getAnchorScope();
5907
5908 // TODO: Is the checkForAllUses below useful for constants?
5909 if (!F)
5910 return indicatePessimisticFixpoint();
5911
5913 const IRPosition &FnPos = IRPosition::function(*F);
5914
5915 // Readonly means we cannot capture through memory.
5916 bool IsKnown;
5917 if (AA::isAssumedReadOnly(A, FnPos, *this, IsKnown)) {
5918 T.addKnownBits(NOT_CAPTURED_IN_MEM);
5919 if (IsKnown)
5920 addKnownBits(NOT_CAPTURED_IN_MEM);
5921 }
5922
5923 // Make sure all returned values are different than the underlying value.
5924 // TODO: we could do this in a more sophisticated way inside
5925 // AAReturnedValues, e.g., track all values that escape through returns
5926 // directly somehow.
5927 auto CheckReturnedArgs = [&](bool &UsedAssumedInformation) {
5929 if (!A.getAssumedSimplifiedValues(IRPosition::returned(*F), this, Values,
5931 UsedAssumedInformation))
5932 return false;
5933 bool SeenConstant = false;
5934 for (const AA::ValueAndContext &VAC : Values) {
5935 if (isa<Constant>(VAC.getValue())) {
5936 if (SeenConstant)
5937 return false;
5938 SeenConstant = true;
5939 } else if (!isa<Argument>(VAC.getValue()) ||
5940 VAC.getValue() == getAssociatedArgument())
5941 return false;
5942 }
5943 return true;
5944 };
5945
5946 bool IsKnownNoUnwind;
5947 if (AA::hasAssumedIRAttr<Attribute::NoUnwind>(
5948 A, this, FnPos, DepClassTy::OPTIONAL, IsKnownNoUnwind)) {
5949 bool IsVoidTy = F->getReturnType()->isVoidTy();
5950 bool UsedAssumedInformation = false;
5951 if (IsVoidTy || CheckReturnedArgs(UsedAssumedInformation)) {
5952 T.addKnownBits(NOT_CAPTURED_IN_RET);
5953 if (T.isKnown(NOT_CAPTURED_IN_MEM))
5955 if (IsKnownNoUnwind && (IsVoidTy || !UsedAssumedInformation)) {
5956 addKnownBits(NOT_CAPTURED_IN_RET);
5957 if (isKnown(NOT_CAPTURED_IN_MEM))
5958 return indicateOptimisticFixpoint();
5959 }
5960 }
5961 }
5962
5963 auto IsDereferenceableOrNull = [&](Value *O, const DataLayout &DL) {
5964 const auto *DerefAA = A.getAAFor<AADereferenceable>(
5966 return DerefAA && DerefAA->getAssumedDereferenceableBytes();
5967 };
5968
5969 auto UseCheck = [&](const Use &U, bool &Follow) -> bool {
5970 switch (DetermineUseCaptureKind(U, IsDereferenceableOrNull)) {
5972 return true;
5974 return checkUse(A, T, U, Follow);
5976 Follow = true;
5977 return true;
5978 }
5979 llvm_unreachable("Unexpected use capture kind!");
5980 };
5981
5982 if (!A.checkForAllUses(UseCheck, *this, *V))
5983 return indicatePessimisticFixpoint();
5984
5985 AANoCapture::StateType &S = getState();
5986 auto Assumed = S.getAssumed();
5987 S.intersectAssumedBits(T.getAssumed());
5988 if (!isAssumedNoCaptureMaybeReturned())
5989 return indicatePessimisticFixpoint();
5990 return Assumed == S.getAssumed() ? ChangeStatus::UNCHANGED
5992}
5993
5994/// NoCapture attribute for function arguments.
5995struct AANoCaptureArgument final : AANoCaptureImpl {
5996 AANoCaptureArgument(const IRPosition &IRP, Attributor &A)
5997 : AANoCaptureImpl(IRP, A) {}
5998
5999 /// See AbstractAttribute::trackStatistics()
6000 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nocapture) }
6001};
6002
6003/// NoCapture attribute for call site arguments.
6004struct AANoCaptureCallSiteArgument final : AANoCaptureImpl {
6005 AANoCaptureCallSiteArgument(const IRPosition &IRP, Attributor &A)
6006 : AANoCaptureImpl(IRP, A) {}
6007
6008 /// See AbstractAttribute::updateImpl(...).
6009 ChangeStatus updateImpl(Attributor &A) override {
6010 // TODO: Once we have call site specific value information we can provide
6011 // call site specific liveness information and then it makes
6012 // sense to specialize attributes for call sites arguments instead of
6013 // redirecting requests to the callee argument.
6014 Argument *Arg = getAssociatedArgument();
6015 if (!Arg)
6016 return indicatePessimisticFixpoint();
6017 const IRPosition &ArgPos = IRPosition::argument(*Arg);
6018 bool IsKnownNoCapture;
6019 const AANoCapture *ArgAA = nullptr;
6020 if (AA::hasAssumedIRAttr<Attribute::NoCapture>(
6021 A, this, ArgPos, DepClassTy::REQUIRED, IsKnownNoCapture, false,
6022 &ArgAA))
6023 return ChangeStatus::UNCHANGED;
6024 if (!ArgAA || !ArgAA->isAssumedNoCaptureMaybeReturned())
6025 return indicatePessimisticFixpoint();
6026 return clampStateAndIndicateChange(getState(), ArgAA->getState());
6027 }
6028
6029 /// See AbstractAttribute::trackStatistics()
6030 void trackStatistics() const override{STATS_DECLTRACK_CSARG_ATTR(nocapture)};
6031};
6032
6033/// NoCapture attribute for floating values.
6034struct AANoCaptureFloating final : AANoCaptureImpl {
6035 AANoCaptureFloating(const IRPosition &IRP, Attributor &A)
6036 : AANoCaptureImpl(IRP, A) {}
6037
6038 /// See AbstractAttribute::trackStatistics()
6039 void trackStatistics() const override {
6041 }
6042};
6043
6044/// NoCapture attribute for function return value.
6045struct AANoCaptureReturned final : AANoCaptureImpl {
6046 AANoCaptureReturned(const IRPosition &IRP, Attributor &A)
6047 : AANoCaptureImpl(IRP, A) {
6048 llvm_unreachable("NoCapture is not applicable to function returns!");
6049 }
6050
6051 /// See AbstractAttribute::initialize(...).
6052 void initialize(Attributor &A) override {
6053 llvm_unreachable("NoCapture is not applicable to function returns!");
6054 }
6055
6056 /// See AbstractAttribute::updateImpl(...).
6057 ChangeStatus updateImpl(Attributor &A) override {
6058 llvm_unreachable("NoCapture is not applicable to function returns!");
6059 }
6060
6061 /// See AbstractAttribute::trackStatistics()
6062 void trackStatistics() const override {}
6063};
6064
6065/// NoCapture attribute deduction for a call site return value.
6066struct AANoCaptureCallSiteReturned final : AANoCaptureImpl {
6067 AANoCaptureCallSiteReturned(const IRPosition &IRP, Attributor &A)
6068 : AANoCaptureImpl(IRP, A) {}
6069
6070 /// See AbstractAttribute::initialize(...).
6071 void initialize(Attributor &A) override {
6072 const Function *F = getAnchorScope();
6073 // Check what state the associated function can actually capture.
6074 determineFunctionCaptureCapabilities(getIRPosition(), *F, *this);
6075 }
6076
6077 /// See AbstractAttribute::trackStatistics()
6078 void trackStatistics() const override {
6080 }
6081};
6082} // namespace
6083
6084/// ------------------ Value Simplify Attribute ----------------------------
6085
6086bool ValueSimplifyStateType::unionAssumed(std::optional<Value *> Other) {
6087 // FIXME: Add a typecast support.
6088 SimplifiedAssociatedValue = AA::combineOptionalValuesInAAValueLatice(
6089 SimplifiedAssociatedValue, Other, Ty);
6090 if (SimplifiedAssociatedValue == std::optional<Value *>(nullptr))
6091 return false;
6092
6093 LLVM_DEBUG({
6094 if (SimplifiedAssociatedValue)
6095 dbgs() << "[ValueSimplify] is assumed to be "
6096 << **SimplifiedAssociatedValue << "\n";
6097 else
6098 dbgs() << "[ValueSimplify] is assumed to be <none>\n";
6099 });
6100 return true;
6101}
6102
6103namespace {
6104struct AAValueSimplifyImpl : AAValueSimplify {
6105 AAValueSimplifyImpl(const IRPosition &IRP, Attributor &A)
6106 : AAValueSimplify(IRP, A) {}
6107
6108 /// See AbstractAttribute::initialize(...).
6109 void initialize(Attributor &A) override {
6110 if (getAssociatedValue().getType()->isVoidTy())
6111 indicatePessimisticFixpoint();
6112 if (A.hasSimplificationCallback(getIRPosition()))
6113 indicatePessimisticFixpoint();
6114 }
6115
6116 /// See AbstractAttribute::getAsStr().
6117 const std::string getAsStr(Attributor *A) const override {
6118 LLVM_DEBUG({
6119 dbgs() << "SAV: " << (bool)SimplifiedAssociatedValue << " ";
6120 if (SimplifiedAssociatedValue && *SimplifiedAssociatedValue)
6121 dbgs() << "SAV: " << **SimplifiedAssociatedValue << " ";
6122 });
6123 return isValidState() ? (isAtFixpoint() ? "simplified" : "maybe-simple")
6124 : "not-simple";
6125 }
6126
6127 /// See AbstractAttribute::trackStatistics()
6128 void trackStatistics() const override {}
6129
6130 /// See AAValueSimplify::getAssumedSimplifiedValue()
6131 std::optional<Value *>
6132 getAssumedSimplifiedValue(Attributor &A) const override {
6133 return SimplifiedAssociatedValue;
6134 }
6135
6136 /// Ensure the return value is \p V with type \p Ty, if not possible return
6137 /// nullptr. If \p Check is true we will only verify such an operation would
6138 /// suceed and return a non-nullptr value if that is the case. No IR is
6139 /// generated or modified.
6140 static Value *ensureType(Attributor &A, Value &V, Type &Ty, Instruction *CtxI,
6141 bool Check) {
6142 if (auto *TypedV = AA::getWithType(V, Ty))
6143 return TypedV;
6144 if (CtxI && V.getType()->canLosslesslyBitCastTo(&Ty))
6145 return Check ? &V
6146 : BitCastInst::CreatePointerBitCastOrAddrSpaceCast(
6147 &V, &Ty, "", CtxI->getIterator());
6148 return nullptr;
6149 }
6150
6151 /// Reproduce \p I with type \p Ty or return nullptr if that is not posisble.
6152 /// If \p Check is true we will only verify such an operation would suceed and
6153 /// return a non-nullptr value if that is the case. No IR is generated or
6154 /// modified.
6155 static Value *reproduceInst(Attributor &A,
6156 const AbstractAttribute &QueryingAA,
6157 Instruction &I, Type &Ty, Instruction *CtxI,
6158 bool Check, ValueToValueMapTy &VMap) {
6159 assert(CtxI && "Cannot reproduce an instruction without context!");
6160 if (Check && (I.mayReadFromMemory() ||
6161 !isSafeToSpeculativelyExecute(&I, CtxI, /* DT */ nullptr,
6162 /* TLI */ nullptr)))
6163 return nullptr;
6164 for (Value *Op : I.operands()) {
6165 Value *NewOp = reproduceValue(A, QueryingAA, *Op, Ty, CtxI, Check, VMap);
6166 if (!NewOp) {
6167 assert(Check && "Manifest of new value unexpectedly failed!");
6168 return nullptr;
6169 }
6170 if (!Check)
6171 VMap[Op] = NewOp;
6172 }
6173 if (Check)
6174 return &I;
6175
6176 Instruction *CloneI = I.clone();
6177 // TODO: Try to salvage debug information here.
6178 CloneI->setDebugLoc(DebugLoc());
6179 VMap[&I] = CloneI;
6180 CloneI->insertBefore(CtxI);
6181 RemapInstruction(CloneI, VMap);
6182 return CloneI;
6183 }
6184
6185 /// Reproduce \p V with type \p Ty or return nullptr if that is not posisble.
6186 /// If \p Check is true we will only verify such an operation would suceed and
6187 /// return a non-nullptr value if that is the case. No IR is generated or
6188 /// modified.
6189 static Value *reproduceValue(Attributor &A,
6190 const AbstractAttribute &QueryingAA, Value &V,
6191 Type &Ty, Instruction *CtxI, bool Check,
6192 ValueToValueMapTy &VMap) {
6193 if (const auto &NewV = VMap.lookup(&V))
6194 return NewV;
6195 bool UsedAssumedInformation = false;
6196 std::optional<Value *> SimpleV = A.getAssumedSimplified(
6197 V, QueryingAA, UsedAssumedInformation, AA::Interprocedural);
6198 if (!SimpleV.has_value())
6199 return PoisonValue::get(&Ty);
6200 Value *EffectiveV = &V;
6201 if (*SimpleV)
6202 EffectiveV = *SimpleV;
6203 if (auto *C = dyn_cast<Constant>(EffectiveV))
6204 return C;
6205 if (CtxI && AA::isValidAtPosition(AA::ValueAndContext(*EffectiveV, *CtxI),
6206 A.getInfoCache()))
6207 return ensureType(A, *EffectiveV, Ty, CtxI, Check);
6208 if (auto *I = dyn_cast<Instruction>(EffectiveV))
6209 if (Value *NewV = reproduceInst(A, QueryingAA, *I, Ty, CtxI, Check, VMap))
6210 return ensureType(A, *NewV, Ty, CtxI, Check);
6211 return nullptr;
6212 }
6213
6214 /// Return a value we can use as replacement for the associated one, or
6215 /// nullptr if we don't have one that makes sense.
6216 Value *manifestReplacementValue(Attributor &A, Instruction *CtxI) const {
6217 Value *NewV = SimplifiedAssociatedValue
6218 ? *SimplifiedAssociatedValue
6219 : UndefValue::get(getAssociatedType());
6220 if (NewV && NewV != &getAssociatedValue()) {
6221 ValueToValueMapTy VMap;
6222 // First verify we can reprduce the value with the required type at the
6223 // context location before we actually start modifying the IR.
6224 if (reproduceValue(A, *this, *NewV, *getAssociatedType(), CtxI,
6225 /* CheckOnly */ true, VMap))
6226 return reproduceValue(A, *this, *NewV, *getAssociatedType(), CtxI,
6227 /* CheckOnly */ false, VMap);
6228 }
6229 return nullptr;
6230 }
6231
6232 /// Helper function for querying AAValueSimplify and updating candidate.
6233 /// \param IRP The value position we are trying to unify with SimplifiedValue
6234 bool checkAndUpdate(Attributor &A, const AbstractAttribute &QueryingAA,
6235 const IRPosition &IRP, bool Simplify = true) {
6236 bool UsedAssumedInformation = false;
6237 std::optional<Value *> QueryingValueSimplified = &IRP.getAssociatedValue();
6238 if (Simplify)
6239 QueryingValueSimplified = A.getAssumedSimplified(
6240 IRP, QueryingAA, UsedAssumedInformation, AA::Interprocedural);
6241 return unionAssumed(QueryingValueSimplified);
6242 }
6243
6244 /// Returns a candidate is found or not
6245 template <typename AAType> bool askSimplifiedValueFor(Attributor &A) {
6246 if (!getAssociatedValue().getType()->isIntegerTy())
6247 return false;
6248
6249 // This will also pass the call base context.
6250 const auto *AA =
6251 A.getAAFor<AAType>(*this, getIRPosition(), DepClassTy::NONE);
6252 if (!AA)
6253 return false;
6254
6255 std::optional<Constant *> COpt = AA->getAssumedConstant(A);
6256
6257 if (!COpt) {
6258 SimplifiedAssociatedValue = std::nullopt;
6259 A.recordDependence(*AA, *this, DepClassTy::OPTIONAL);
6260 return true;
6261 }
6262 if (auto *C = *COpt) {
6263 SimplifiedAssociatedValue = C;
6264 A.recordDependence(*AA, *this, DepClassTy::OPTIONAL);
6265 return true;
6266 }
6267 return false;
6268 }
6269
6270 bool askSimplifiedValueForOtherAAs(Attributor &A) {
6271 if (askSimplifiedValueFor<AAValueConstantRange>(A))
6272 return true;
6273 if (askSimplifiedValueFor<AAPotentialConstantValues>(A))
6274 return true;
6275 return false;
6276 }
6277
6278 /// See AbstractAttribute::manifest(...).
6279 ChangeStatus manifest(Attributor &A) override {
6280 ChangeStatus Changed = ChangeStatus::UNCHANGED;
6281 for (auto &U : getAssociatedValue().uses()) {
6282 // Check if we need to adjust the insertion point to make sure the IR is
6283 // valid.
6284 Instruction *IP = dyn_cast<Instruction>(U.getUser());
6285 if (auto *PHI = dyn_cast_or_null<PHINode>(IP))
6286 IP = PHI->getIncomingBlock(U)->getTerminator();
6287 if (auto *NewV = manifestReplacementValue(A, IP)) {
6288 LLVM_DEBUG(dbgs() << "[ValueSimplify] " << getAssociatedValue()
6289 << " -> " << *NewV << " :: " << *this << "\n");
6290 if (A.changeUseAfterManifest(U, *NewV))
6291 Changed = ChangeStatus::CHANGED;
6292 }
6293 }
6294
6295 return Changed | AAValueSimplify::manifest(A);
6296 }
6297
6298 /// See AbstractState::indicatePessimisticFixpoint(...).
6299 ChangeStatus indicatePessimisticFixpoint() override {
6300 SimplifiedAssociatedValue = &getAssociatedValue();
6301 return AAValueSimplify::indicatePessimisticFixpoint();
6302 }
6303};
6304
6305struct AAValueSimplifyArgument final : AAValueSimplifyImpl {
6306 AAValueSimplifyArgument(const IRPosition &IRP, Attributor &A)
6307 : AAValueSimplifyImpl(IRP, A) {}
6308
6309 void initialize(Attributor &A) override {
6310 AAValueSimplifyImpl::initialize(A);
6311 if (A.hasAttr(getIRPosition(),
6312 {Attribute::InAlloca, Attribute::Preallocated,
6313 Attribute::StructRet, Attribute::Nest, Attribute::ByVal},
6314 /* IgnoreSubsumingPositions */ true))
6315 indicatePessimisticFixpoint();
6316 }
6317
6318 /// See AbstractAttribute::updateImpl(...).
6319 ChangeStatus updateImpl(Attributor &A) override {
6320 // Byval is only replacable if it is readonly otherwise we would write into
6321 // the replaced value and not the copy that byval creates implicitly.
6322 Argument *Arg = getAssociatedArgument();
6323 if (Arg->hasByValAttr()) {
6324 // TODO: We probably need to verify synchronization is not an issue, e.g.,
6325 // there is no race by not copying a constant byval.
6326 bool IsKnown;
6327 if (!AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown))
6328 return indicatePessimisticFixpoint();
6329 }
6330
6331 auto Before = SimplifiedAssociatedValue;
6332
6333 auto PredForCallSite = [&](AbstractCallSite ACS) {
6334 const IRPosition &ACSArgPos =
6335 IRPosition::callsite_argument(ACS, getCallSiteArgNo());
6336 // Check if a coresponding argument was found or if it is on not
6337 // associated (which can happen for callback calls).
6338 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
6339 return false;
6340
6341 // Simplify the argument operand explicitly and check if the result is
6342 // valid in the current scope. This avoids refering to simplified values
6343 // in other functions, e.g., we don't want to say a an argument in a
6344 // static function is actually an argument in a different function.
6345 bool UsedAssumedInformation = false;
6346 std::optional<Constant *> SimpleArgOp =
6347 A.getAssumedConstant(ACSArgPos, *this, UsedAssumedInformation);
6348 if (!SimpleArgOp)
6349 return true;
6350 if (!*SimpleArgOp)
6351 return false;
6352 if (!AA::isDynamicallyUnique(A, *this, **SimpleArgOp))
6353 return false;
6354 return unionAssumed(*SimpleArgOp);
6355 };
6356
6357 // Generate a answer specific to a call site context.
6358 bool Success;
6359 bool UsedAssumedInformation = false;
6360 if (hasCallBaseContext() &&
6361 getCallBaseContext()->getCalledOperand() == Arg->getParent())
6362 Success = PredForCallSite(
6363 AbstractCallSite(&getCallBaseContext()->getCalledOperandUse()));
6364 else
6365 Success = A.checkForAllCallSites(PredForCallSite, *this, true,
6366 UsedAssumedInformation);
6367
6368 if (!Success)
6369 if (!askSimplifiedValueForOtherAAs(A))
6370 return indicatePessimisticFixpoint();
6371
6372 // If a candidate was found in this update, return CHANGED.
6373 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED
6374 : ChangeStatus ::CHANGED;
6375 }
6376
6377 /// See AbstractAttribute::trackStatistics()
6378 void trackStatistics() const override {
6379 STATS_DECLTRACK_ARG_ATTR(value_simplify)
6380 }
6381};
6382
6383struct AAValueSimplifyReturned : AAValueSimplifyImpl {
6384 AAValueSimplifyReturned(const IRPosition &IRP, Attributor &A)
6385 : AAValueSimplifyImpl(IRP, A) {}
6386
6387 /// See AAValueSimplify::getAssumedSimplifiedValue()
6388 std::optional<Value *>
6389 getAssumedSimplifiedValue(Attributor &A) const override {
6390 if (!isValidState())
6391 return nullptr;
6392 return SimplifiedAssociatedValue;
6393 }
6394
6395 /// See AbstractAttribute::updateImpl(...).
6396 ChangeStatus updateImpl(Attributor &A) override {
6397 auto Before = SimplifiedAssociatedValue;
6398
6399 auto ReturnInstCB = [&](Instruction &I) {
6400 auto &RI = cast<ReturnInst>(I);
6401 return checkAndUpdate(
6402 A, *this,
6403 IRPosition::value(*RI.getReturnValue(), getCallBaseContext()));
6404 };
6405
6406 bool UsedAssumedInformation = false;
6407 if (!A.checkForAllInstructions(ReturnInstCB, *this, {Instruction::Ret},
6408 UsedAssumedInformation))
6409 if (!askSimplifiedValueForOtherAAs(A))
6410 return indicatePessimisticFixpoint();
6411
6412 // If a candidate was found in this update, return CHANGED.
6413 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED
6414 : ChangeStatus ::CHANGED;
6415 }
6416
6417 ChangeStatus manifest(Attributor &A) override {
6418 // We queried AAValueSimplify for the returned values so they will be
6419 // replaced if a simplified form was found. Nothing to do here.
6420 return ChangeStatus::UNCHANGED;
6421 }
6422
6423 /// See AbstractAttribute::trackStatistics()
6424 void trackStatistics() const override {
6425 STATS_DECLTRACK_FNRET_ATTR(value_simplify)
6426 }
6427};
6428
6429struct AAValueSimplifyFloating : AAValueSimplifyImpl {
6430 AAValueSimplifyFloating(const IRPosition &IRP, Attributor &A)
6431 : AAValueSimplifyImpl(IRP, A) {}
6432
6433 /// See AbstractAttribute::initialize(...).
6434 void initialize(Attributor &A) override {
6435 AAValueSimplifyImpl::initialize(A);
6436 Value &V = getAnchorValue();
6437
6438 // TODO: add other stuffs
6439 if (isa<Constant>(V))
6440 indicatePessimisticFixpoint();
6441 }
6442
6443 /// See AbstractAttribute::updateImpl(...).
6444 ChangeStatus updateImpl(Attributor &A) override {
6445 auto Before = SimplifiedAssociatedValue;
6446 if (!askSimplifiedValueForOtherAAs(A))
6447 return indicatePessimisticFixpoint();
6448
6449 // If a candidate was found in this update, return CHANGED.
6450 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED
6451 : ChangeStatus ::CHANGED;
6452 }
6453
6454 /// See AbstractAttribute::trackStatistics()
6455 void trackStatistics() const override {
6456 STATS_DECLTRACK_FLOATING_ATTR(value_simplify)
6457 }
6458};
6459
6460struct AAValueSimplifyFunction : AAValueSimplifyImpl {
6461 AAValueSimplifyFunction(const IRPosition &IRP, Attributor &A)
6462 : AAValueSimplifyImpl(IRP, A) {}
6463
6464 /// See AbstractAttribute::initialize(...).
6465 void initialize(Attributor &A) override {
6466 SimplifiedAssociatedValue = nullptr;
6467 indicateOptimisticFixpoint();
6468 }
6469 /// See AbstractAttribute::initialize(...).
6470 ChangeStatus updateImpl(Attributor &A) override {
6472 "AAValueSimplify(Function|CallSite)::updateImpl will not be called");
6473 }
6474 /// See AbstractAttribute::trackStatistics()
6475 void trackStatistics() const override {
6476 STATS_DECLTRACK_FN_ATTR(value_simplify)
6477 }
6478};
6479
6480struct AAValueSimplifyCallSite : AAValueSimplifyFunction {
6481 AAValueSimplifyCallSite(const IRPosition &IRP, Attributor &A)
6482 : AAValueSimplifyFunction(IRP, A) {}
6483 /// See AbstractAttribute::trackStatistics()
6484 void trackStatistics() const override {
6485 STATS_DECLTRACK_CS_ATTR(value_simplify)
6486 }
6487};
6488
6489struct AAValueSimplifyCallSiteReturned : AAValueSimplifyImpl {
6490 AAValueSimplifyCallSiteReturned(const IRPosition &IRP, Attributor &A)
6491 : AAValueSimplifyImpl(IRP, A) {}
6492
6493 void initialize(Attributor &A) override {
6494 AAValueSimplifyImpl::initialize(A);
6495 Function *Fn = getAssociatedFunction();
6496 assert(Fn && "Did expect an associted function");
6497 for (Argument &Arg : Fn->args()) {
6498 if (Arg.hasReturnedAttr()) {
6499 auto IRP = IRPosition::callsite_argument(*cast<CallBase>(getCtxI()),
6500 Arg.getArgNo());
6502 checkAndUpdate(A, *this, IRP))
6503 indicateOptimisticFixpoint();
6504 else
6505 indicatePessimisticFixpoint();
6506 return;
6507 }
6508 }
6509 }
6510
6511 /// See AbstractAttribute::updateImpl(...).
6512 ChangeStatus updateImpl(Attributor &A) override {
6513 return indicatePessimisticFixpoint();
6514 }
6515
6516 void trackStatistics() const override {
6517 STATS_DECLTRACK_CSRET_ATTR(value_simplify)
6518 }
6519};
6520
6521struct AAValueSimplifyCallSiteArgument : AAValueSimplifyFloating {
6522 AAValueSimplifyCallSiteArgument(const IRPosition &IRP, Attributor &A)
6523 : AAValueSimplifyFloating(IRP, A) {}
6524
6525 /// See AbstractAttribute::manifest(...).
6526 ChangeStatus manifest(Attributor &A) override {
6527 ChangeStatus Changed = ChangeStatus::UNCHANGED;
6528 // TODO: We should avoid simplification duplication to begin with.
6529 auto *FloatAA = A.lookupAAFor<AAValueSimplify>(
6530 IRPosition::value(getAssociatedValue()), this, DepClassTy::NONE);
6531 if (FloatAA && FloatAA->getState().isValidState())
6532 return Changed;
6533
6534 if (auto *NewV = manifestReplacementValue(A, getCtxI())) {
6535 Use &U = cast<CallBase>(&getAnchorValue())
6536 ->getArgOperandUse(getCallSiteArgNo());
6537 if (A.changeUseAfterManifest(U, *NewV))
6538 Changed = ChangeStatus::CHANGED;
6539 }
6540
6541 return Changed | AAValueSimplify::manifest(A);
6542 }
6543
6544 void trackStatistics() const override {
6545 STATS_DECLTRACK_CSARG_ATTR(value_simplify)
6546 }
6547};
6548} // namespace
6549
6550/// ----------------------- Heap-To-Stack Conversion ---------------------------
6551namespace {
6552struct AAHeapToStackFunction final : public AAHeapToStack {
6553
6554 struct AllocationInfo {
6555 /// The call that allocates the memory.
6556 CallBase *const CB;
6557
6558 /// The library function id for the allocation.
6559 LibFunc LibraryFunctionId = NotLibFunc;
6560
6561 /// The status wrt. a rewrite.
6562 enum {
6563 STACK_DUE_TO_USE,
6564 STACK_DUE_TO_FREE,
6565 INVALID,
6566 } Status = STACK_DUE_TO_USE;
6567
6568 /// Flag to indicate if we encountered a use that might free this allocation
6569 /// but which is not in the deallocation infos.
6570 bool HasPotentiallyFreeingUnknownUses = false;
6571
6572 /// Flag to indicate that we should place the new alloca in the function
6573 /// entry block rather than where the call site (CB) is.
6574 bool MoveAllocaIntoEntry = true;
6575
6576 /// The set of free calls that use this allocation.
6577 SmallSetVector<CallBase *, 1> PotentialFreeCalls{};
6578 };
6579
6580 struct DeallocationInfo {
6581 /// The call that deallocates the memory.
6582 CallBase *const CB;
6583 /// The value freed by the call.
6584 Value *FreedOp;
6585
6586 /// Flag to indicate if we don't know all objects this deallocation might
6587 /// free.
6588 bool MightFreeUnknownObjects = false;
6589
6590 /// The set of allocation calls that are potentially freed.
6591 SmallSetVector<CallBase *, 1> PotentialAllocationCalls{};
6592 };
6593
6594 AAHeapToStackFunction(const IRPosition &IRP, Attributor &A)
6595 : AAHeapToStack(IRP, A) {}
6596
6597 ~AAHeapToStackFunction() {
6598 // Ensure we call the destructor so we release any memory allocated in the
6599 // sets.
6600 for (auto &It : AllocationInfos)
6601 It.second->~AllocationInfo();
6602 for (auto &It : DeallocationInfos)
6603 It.second->~DeallocationInfo();
6604 }
6605
6606 void initialize(Attributor &A) override {
6607 AAHeapToStack::initialize(A);
6608
6609 const Function *F = getAnchorScope();
6610 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
6611
6612 auto AllocationIdentifierCB = [&](Instruction &I) {
6613 CallBase *CB = dyn_cast<CallBase>(&I);
6614 if (!CB)
6615 return true;
6616 if (Value *FreedOp = getFreedOperand(CB, TLI)) {
6617 DeallocationInfos[CB] = new (A.Allocator) DeallocationInfo{CB, FreedOp};
6618 return true;
6619 }
6620 // To do heap to stack, we need to know that the allocation itself is
6621 // removable once uses are rewritten, and that we can initialize the
6622 // alloca to the same pattern as the original allocation result.
6623 if (isRemovableAlloc(CB, TLI)) {
6624 auto *I8Ty = Type::getInt8Ty(CB->getParent()->getContext());
6625 if (nullptr != getInitialValueOfAllocation(CB, TLI, I8Ty)) {
6626 AllocationInfo *AI = new (A.Allocator) AllocationInfo{CB};
6627 AllocationInfos[CB] = AI;
6628 if (TLI)
6629 TLI->getLibFunc(*CB, AI->LibraryFunctionId);
6630 }
6631 }
6632 return true;
6633 };
6634
6635 bool UsedAssumedInformation = false;
6636 bool Success = A.checkForAllCallLikeInstructions(
6637 AllocationIdentifierCB, *this, UsedAssumedInformation,
6638 /* CheckBBLivenessOnly */ false,
6639 /* CheckPotentiallyDead */ true);
6640 (void)Success;
6641 assert(Success && "Did not expect the call base visit callback to fail!");
6642
6644 [](const IRPosition &, const AbstractAttribute *,
6645 bool &) -> std::optional<Value *> { return nullptr; };
6646 for (const auto &It : AllocationInfos)
6647 A.registerSimplificationCallback(IRPosition::callsite_returned(*It.first),
6648 SCB);
6649 for (const auto &It : DeallocationInfos)
6650 A.registerSimplificationCallback(IRPosition::callsite_returned(*It.first),
6651 SCB);
6652 }
6653
6654 const std::string getAsStr(Attributor *A) const override {
6655 unsigned NumH2SMallocs = 0, NumInvalidMallocs = 0;
6656 for (const auto &It : AllocationInfos) {
6657 if (It.second->Status == AllocationInfo::INVALID)
6658 ++NumInvalidMallocs;
6659 else
6660 ++NumH2SMallocs;
6661 }
6662 return "[H2S] Mallocs Good/Bad: " + std::to_string(NumH2SMallocs) + "/" +
6663 std::to_string(NumInvalidMallocs);
6664 }
6665
6666 /// See AbstractAttribute::trackStatistics().
6667 void trackStatistics() const override {
6668 STATS_DECL(
6669 MallocCalls, Function,
6670 "Number of malloc/calloc/aligned_alloc calls converted to allocas");
6671 for (const auto &It : AllocationInfos)
6672 if (It.second->Status != AllocationInfo::INVALID)
6673 ++BUILD_STAT_NAME(MallocCalls, Function);
6674 }
6675
6676 bool isAssumedHeapToStack(const CallBase &CB) const override {
6677 if (isValidState())
6678 if (AllocationInfo *AI =
6679 AllocationInfos.lookup(const_cast<CallBase *>(&CB)))
6680 return AI->Status != AllocationInfo::INVALID;
6681 return false;
6682 }
6683
6684 bool isAssumedHeapToStackRemovedFree(CallBase &CB) const override {
6685 if (!isValidState())
6686 return false;
6687
6688 for (const auto &It : AllocationInfos) {
6689 AllocationInfo &AI = *It.second;
6690 if (AI.Status == AllocationInfo::INVALID)
6691 continue;
6692
6693 if (AI.PotentialFreeCalls.count(&CB))
6694 return true;
6695 }
6696
6697 return false;
6698 }
6699
6700 ChangeStatus manifest(Attributor &A) override {
6701 assert(getState().isValidState() &&
6702 "Attempted to manifest an invalid state!");
6703
6704 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
6705 Function *F = getAnchorScope();
6706 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
6707
6708 for (auto &It : AllocationInfos) {
6709 AllocationInfo &AI = *It.second;
6710 if (AI.Status == AllocationInfo::INVALID)
6711 continue;
6712
6713 for (CallBase *FreeCall : AI.PotentialFreeCalls) {
6714 LLVM_DEBUG(dbgs() << "H2S: Removing free call: " << *FreeCall << "\n");
6715 A.deleteAfterManifest(*FreeCall);
6716 HasChanged = ChangeStatus::CHANGED;
6717 }
6718
6719 LLVM_DEBUG(dbgs() << "H2S: Removing malloc-like call: " << *AI.CB
6720 << "\n");
6721
6722 auto Remark = [&](OptimizationRemark OR) {
6723 LibFunc IsAllocShared;
6724 if (TLI->getLibFunc(*AI.CB, IsAllocShared))
6725 if (IsAllocShared == LibFunc___kmpc_alloc_shared)
6726 return OR << "Moving globalized variable to the stack.";
6727 return OR << "Moving memory allocation from the heap to the stack.";
6728 };
6729 if (AI.LibraryFunctionId == LibFunc___kmpc_alloc_shared)
6730 A.emitRemark<OptimizationRemark>(AI.CB, "OMP110", Remark);
6731 else
6732 A.emitRemark<OptimizationRemark>(AI.CB, "HeapToStack", Remark);
6733
6734 const DataLayout &DL = A.getInfoCache().getDL();
6735 Value *Size;
6736 std::optional<APInt> SizeAPI = getSize(A, *this, AI);
6737 if (SizeAPI) {
6738 Size = ConstantInt::get(AI.CB->getContext(), *SizeAPI);
6739 } else {
6740 LLVMContext &Ctx = AI.CB->getContext();
6741 ObjectSizeOpts Opts;
6742 ObjectSizeOffsetEvaluator Eval(DL, TLI, Ctx, Opts);
6743 SizeOffsetValue SizeOffsetPair = Eval.compute(AI.CB);
6744 assert(SizeOffsetPair != ObjectSizeOffsetEvaluator::unknown() &&
6745 cast<ConstantInt>(SizeOffsetPair.Offset)->isZero());
6746 Size = SizeOffsetPair.Size;
6747 }
6748
6749 BasicBlock::iterator IP = AI.MoveAllocaIntoEntry
6750 ? F->getEntryBlock().begin()
6751 : AI.CB->getIterator();
6752
6753 Align Alignment(1);
6754 if (MaybeAlign RetAlign = AI.CB->getRetAlign())
6755 Alignment = std::max(Alignment, *RetAlign);
6756 if (Value *Align = getAllocAlignment(AI.CB, TLI)) {
6757 std::optional<APInt> AlignmentAPI = getAPInt(A, *this, *Align);
6758 assert(AlignmentAPI && AlignmentAPI->getZExtValue() > 0 &&
6759 "Expected an alignment during manifest!");
6760 Alignment =
6761 std::max(Alignment, assumeAligned(AlignmentAPI->getZExtValue()));
6762 }
6763
6764 // TODO: Hoist the alloca towards the function entry.
6765 unsigned AS = DL.getAllocaAddrSpace();
6766 Instruction *Alloca =
6767 new AllocaInst(Type::getInt8Ty(F->getContext()), AS, Size, Alignment,
6768 AI.CB->getName() + ".h2s", IP);
6769
6770 if (Alloca->getType() != AI.CB->getType())
6771 Alloca = BitCastInst::CreatePointerBitCastOrAddrSpaceCast(
6772 Alloca, AI.CB->getType(), "malloc_cast", AI.CB->getIterator());
6773
6774 auto *I8Ty = Type::getInt8Ty(F->getContext());
6775 auto *InitVal = getInitialValueOfAllocation(AI.CB, TLI, I8Ty);
6776 assert(InitVal &&
6777 "Must be able to materialize initial memory state of allocation");
6778
6779 A.changeAfterManifest(IRPosition::inst(*AI.CB), *Alloca);
6780
6781 if (auto *II = dyn_cast<InvokeInst>(AI.CB)) {
6782 auto *NBB = II->getNormalDest();
6783 BranchInst::Create(NBB, AI.CB->getParent());
6784 A.deleteAfterManifest(*AI.CB);
6785 } else {
6786 A.deleteAfterManifest(*AI.CB);
6787 }
6788
6789 // Initialize the alloca with the same value as used by the allocation
6790 // function. We can skip undef as the initial value of an alloc is
6791 // undef, and the memset would simply end up being DSEd.
6792 if (!isa<UndefValue>(InitVal)) {
6793 IRBuilder<> Builder(Alloca->getNextNode());
6794 // TODO: Use alignment above if align!=1
6795 Builder.CreateMemSet(Alloca, InitVal, Size, std::nullopt);
6796 }
6797 HasChanged = ChangeStatus::CHANGED;
6798 }
6799
6800 return HasChanged;
6801 }
6802
6803 std::optional<APInt> getAPInt(Attributor &A, const AbstractAttribute &AA,
6804 Value &V) {
6805 bool UsedAssumedInformation = false;
6806 std::optional<Constant *> SimpleV =
6807 A.getAssumedConstant(V, AA, UsedAssumedInformation);
6808 if (!SimpleV)
6809 return APInt(64, 0);
6810 if (auto *CI = dyn_cast_or_null<ConstantInt>(*SimpleV))
6811 return CI->getValue();
6812 return std::nullopt;
6813 }
6814
6815 std::optional<APInt> getSize(Attributor &A, const AbstractAttribute &AA,
6816 AllocationInfo &AI) {
6817 auto Mapper = [&](const Value *V) -> const Value * {
6818 bool UsedAssumedInformation = false;
6819 if (std::optional<Constant *> SimpleV =
6820 A.getAssumedConstant(*V, AA, UsedAssumedInformation))
6821 if (*SimpleV)
6822 return *SimpleV;
6823 return V;
6824 };
6825
6826 const Function *F = getAnchorScope();
6827 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
6828 return getAllocSize(AI.CB, TLI, Mapper);
6829 }
6830
6831 /// Collection of all malloc-like calls in a function with associated
6832 /// information.
6834
6835 /// Collection of all free-like calls in a function with associated
6836 /// information.
6838
6839 ChangeStatus updateImpl(Attributor &A) override;
6840};
6841
6842ChangeStatus AAHeapToStackFunction::updateImpl(Attributor &A) {
6844 const Function *F = getAnchorScope();
6845 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
6846
6847 const auto *LivenessAA =
6848 A.getAAFor<AAIsDead>(*this, IRPosition::function(*F), DepClassTy::NONE);
6849
6851 A.getInfoCache().getMustBeExecutedContextExplorer();
6852
6853 bool StackIsAccessibleByOtherThreads =
6854 A.getInfoCache().stackIsAccessibleByOtherThreads();
6855
6856 LoopInfo *LI =
6857 A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(*F);
6858 std::optional<bool> MayContainIrreducibleControl;
6859 auto IsInLoop = [&](BasicBlock &BB) {
6860 if (&F->getEntryBlock() == &BB)
6861 return false;
6862 if (!MayContainIrreducibleControl.has_value())
6863 MayContainIrreducibleControl = mayContainIrreducibleControl(*F, LI);
6864 if (*MayContainIrreducibleControl)
6865 return true;
6866 if (!LI)
6867 return true;
6868 return LI->getLoopFor(&BB) != nullptr;
6869 };
6870
6871 // Flag to ensure we update our deallocation information at most once per
6872 // updateImpl call and only if we use the free check reasoning.
6873 bool HasUpdatedFrees = false;
6874
6875 auto UpdateFrees = [&]() {
6876 HasUpdatedFrees = true;
6877
6878 for (auto &It : DeallocationInfos) {
6879 DeallocationInfo &DI = *It.second;
6880 // For now we cannot use deallocations that have unknown inputs, skip
6881 // them.
6882 if (DI.MightFreeUnknownObjects)
6883 continue;
6884
6885 // No need to analyze dead calls, ignore them instead.
6886 bool UsedAssumedInformation = false;
6887 if (A.isAssumedDead(*DI.CB, this, LivenessAA, UsedAssumedInformation,
6888 /* CheckBBLivenessOnly */ true))
6889 continue;
6890
6891 // Use the non-optimistic version to get the freed object.
6892 Value *Obj = getUnderlyingObject(DI.FreedOp);
6893 if (!Obj) {
6894 LLVM_DEBUG(dbgs() << "[H2S] Unknown underlying object for free!\n");
6895 DI.MightFreeUnknownObjects = true;
6896 continue;
6897 }
6898
6899 // Free of null and undef can be ignored as no-ops (or UB in the latter
6900 // case).
6901 if (isa<ConstantPointerNull>(Obj) || isa<UndefValue>(Obj))
6902 continue;
6903
6904 CallBase *ObjCB = dyn_cast<CallBase>(Obj);
6905 if (!ObjCB) {
6906 LLVM_DEBUG(dbgs() << "[H2S] Free of a non-call object: " << *Obj
6907 << "\n");
6908 DI.MightFreeUnknownObjects = true;
6909 continue;
6910 }
6911
6912 AllocationInfo *AI = AllocationInfos.lookup(ObjCB);
6913 if (!AI) {
6914 LLVM_DEBUG(dbgs() << "[H2S] Free of a non-allocation object: " << *Obj
6915 << "\n");
6916 DI.MightFreeUnknownObjects = true;
6917 continue;
6918 }
6919
6920 DI.PotentialAllocationCalls.insert(ObjCB);
6921 }
6922 };
6923
6924 auto FreeCheck = [&](AllocationInfo &AI) {
6925 // If the stack is not accessible by other threads, the "must-free" logic
6926 // doesn't apply as the pointer could be shared and needs to be places in
6927 // "shareable" memory.
6928 if (!StackIsAccessibleByOtherThreads) {
6929 bool IsKnownNoSycn;
6930 if (!AA::hasAssumedIRAttr<Attribute::NoSync>(
6931 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNoSycn)) {
6932 LLVM_DEBUG(
6933 dbgs() << "[H2S] found an escaping use, stack is not accessible by "
6934 "other threads and function is not nosync:\n");
6935 return false;
6936 }
6937 }
6938 if (!HasUpdatedFrees)
6939 UpdateFrees();
6940
6941 // TODO: Allow multi exit functions that have different free calls.
6942 if (AI.PotentialFreeCalls.size() != 1) {
6943 LLVM_DEBUG(dbgs() << "[H2S] did not find one free call but "
6944 << AI.PotentialFreeCalls.size() << "\n");
6945 return false;
6946 }
6947 CallBase *UniqueFree = *AI.PotentialFreeCalls.begin();
6948 DeallocationInfo *DI = DeallocationInfos.lookup(UniqueFree);
6949 if (!DI) {
6950 LLVM_DEBUG(
6951 dbgs() << "[H2S] unique free call was not known as deallocation call "
6952 << *UniqueFree << "\n");
6953 return false;
6954 }
6955 if (DI->MightFreeUnknownObjects) {
6956 LLVM_DEBUG(
6957 dbgs() << "[H2S] unique free call might free unknown allocations\n");
6958 return false;
6959 }
6960 if (DI->PotentialAllocationCalls.empty())
6961 return true;
6962 if (DI->PotentialAllocationCalls.size() > 1) {
6963 LLVM_DEBUG(dbgs() << "[H2S] unique free call might free "
6964 << DI->PotentialAllocationCalls.size()
6965 << " different allocations\n");
6966 return false;
6967 }
6968 if (*DI->PotentialAllocationCalls.begin() != AI.CB) {
6969 LLVM_DEBUG(
6970 dbgs()
6971 << "[H2S] unique free call not known to free this allocation but "
6972 << **DI->PotentialAllocationCalls.begin() << "\n");
6973 return false;
6974 }
6975
6976 // __kmpc_alloc_shared and __kmpc_alloc_free are by construction matched.
6977 if (AI.LibraryFunctionId != LibFunc___kmpc_alloc_shared) {
6978 Instruction *CtxI = isa<InvokeInst>(AI.CB) ? AI.CB : AI.CB->getNextNode();
6979 if (!Explorer || !Explorer->findInContextOf(UniqueFree, CtxI)) {
6980 LLVM_DEBUG(dbgs() << "[H2S] unique free call might not be executed "
6981 "with the allocation "
6982 << *UniqueFree << "\n");
6983 return false;
6984 }
6985 }
6986 return true;
6987 };
6988
6989 auto UsesCheck = [&](AllocationInfo &AI) {
6990 bool ValidUsesOnly = true;
6991
6992 auto Pred = [&](const Use &U, bool &Follow) -> bool {
6993 Instruction *UserI = cast<Instruction>(U.getUser());
6994 if (isa<LoadInst>(UserI))
6995 return true;
6996 if (auto *SI = dyn_cast<StoreInst>(UserI)) {
6997 if (SI->getValueOperand() == U.get()) {
6999 << "[H2S] escaping store to memory: " << *UserI << "\n");
7000 ValidUsesOnly = false;
7001 } else {
7002 // A store into the malloc'ed memory is fine.
7003 }
7004 return true;
7005 }
7006 if (auto *CB = dyn_cast<CallBase>(UserI)) {
7007 if (!CB->isArgOperand(&U) || CB->isLifetimeStartOrEnd())
7008 return true;
7009 if (DeallocationInfos.count(CB)) {
7010 AI.PotentialFreeCalls.insert(CB);
7011 return true;
7012 }
7013
7014 unsigned ArgNo = CB->getArgOperandNo(&U);
7015 auto CBIRP = IRPosition::callsite_argument(*CB, ArgNo);
7016
7017 bool IsKnownNoCapture;
7018 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::NoCapture>(
7019 A, this, CBIRP, DepClassTy::OPTIONAL, IsKnownNoCapture);
7020
7021 // If a call site argument use is nofree, we are fine.
7022 bool IsKnownNoFree;
7023 bool IsAssumedNoFree = AA::hasAssumedIRAttr<Attribute::NoFree>(
7024 A, this, CBIRP, DepClassTy::OPTIONAL, IsKnownNoFree);
7025
7026 if (!IsAssumedNoCapture ||
7027 (AI.LibraryFunctionId != LibFunc___kmpc_alloc_shared &&
7028 !IsAssumedNoFree)) {
7029 AI.HasPotentiallyFreeingUnknownUses |= !IsAssumedNoFree;
7030
7031 // Emit a missed remark if this is missed OpenMP globalization.
7032 auto Remark = [&](OptimizationRemarkMissed ORM) {
7033 return ORM
7034 << "Could not move globalized variable to the stack. "
7035 "Variable is potentially captured in call. Mark "
7036 "parameter as `__attribute__((noescape))` to override.";
7037 };
7038
7039 if (ValidUsesOnly &&
7040 AI.LibraryFunctionId == LibFunc___kmpc_alloc_shared)
7041 A.emitRemark<OptimizationRemarkMissed>(CB, "OMP113", Remark);
7042
7043 LLVM_DEBUG(dbgs() << "[H2S] Bad user: " << *UserI << "\n");
7044 ValidUsesOnly = false;
7045 }
7046 return true;
7047 }
7048
7049 if (isa<GetElementPtrInst>(UserI) || isa<BitCastInst>(UserI) ||
7050 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) {
7051 Follow = true;
7052 return true;
7053 }
7054 // Unknown user for which we can not track uses further (in a way that
7055 // makes sense).
7056 LLVM_DEBUG(dbgs() << "[H2S] Unknown user: " << *UserI << "\n");
7057 ValidUsesOnly = false;
7058 return true;
7059 };
7060 if (!A.checkForAllUses(Pred, *this, *AI.CB, /* CheckBBLivenessOnly */ false,
7061 DepClassTy::OPTIONAL, /* IgnoreDroppableUses */ true,
7062 [&](const Use &OldU, const Use &NewU) {
7063 auto *SI = dyn_cast<StoreInst>(OldU.getUser());
7064 return !SI || StackIsAccessibleByOtherThreads ||
7065 AA::isAssumedThreadLocalObject(
7066 A, *SI->getPointerOperand(), *this);
7067 }))
7068 return false;
7069 return ValidUsesOnly;
7070 };
7071
7072 // The actual update starts here. We look at all allocations and depending on
7073 // their status perform the appropriate check(s).
7074 for (auto &It : AllocationInfos) {
7075 AllocationInfo &AI = *It.second;
7076 if (AI.Status == AllocationInfo::INVALID)
7077 continue;
7078
7079 if (Value *Align = getAllocAlignment(AI.CB, TLI)) {
7080 std::optional<APInt> APAlign = getAPInt(A, *this, *Align);
7081 if (!APAlign) {
7082 // Can't generate an alloca which respects the required alignment
7083 // on the allocation.
7084 LLVM_DEBUG(dbgs() << "[H2S] Unknown allocation alignment: " << *AI.CB
7085 << "\n");
7086 AI.Status = AllocationInfo::INVALID;
7087 Changed = ChangeStatus::CHANGED;
7088 continue;
7089 }
7090 if (APAlign->ugt(llvm::Value::MaximumAlignment) ||
7091 !APAlign->isPowerOf2()) {
7092 LLVM_DEBUG(dbgs() << "[H2S] Invalid allocation alignment: " << APAlign
7093 << "\n");
7094 AI.Status = AllocationInfo::INVALID;
7095 Changed = ChangeStatus::CHANGED;
7096 continue;
7097 }
7098 }
7099
7100 std::optional<APInt> Size = getSize(A, *this, AI);
7101 if (AI.LibraryFunctionId != LibFunc___kmpc_alloc_shared &&
7102 MaxHeapToStackSize != -1) {
7103 if (!Size || Size->ugt(MaxHeapToStackSize)) {
7104 LLVM_DEBUG({
7105 if (!Size)
7106 dbgs() << "[H2S] Unknown allocation size: " << *AI.CB << "\n";
7107 else
7108 dbgs() << "[H2S] Allocation size too large: " << *AI.CB << " vs. "
7109 << MaxHeapToStackSize << "\n";
7110 });
7111
7112 AI.Status = AllocationInfo::INVALID;
7113 Changed = ChangeStatus::CHANGED;
7114 continue;
7115 }
7116 }
7117
7118 switch (AI.Status) {
7119 case AllocationInfo::STACK_DUE_TO_USE:
7120 if (UsesCheck(AI))
7121 break;
7122 AI.Status = AllocationInfo::STACK_DUE_TO_FREE;
7123 [[fallthrough]];
7124 case AllocationInfo::STACK_DUE_TO_FREE:
7125 if (FreeCheck(AI))
7126 break;
7127 AI.Status = AllocationInfo::INVALID;
7128 Changed = ChangeStatus::CHANGED;
7129 break;
7130 case AllocationInfo::INVALID:
7131 llvm_unreachable("Invalid allocations should never reach this point!");
7132 };
7133
7134 // Check if we still think we can move it into the entry block. If the
7135 // alloca comes from a converted __kmpc_alloc_shared then we can usually
7136 // ignore the potential compilations associated with loops.
7137 bool IsGlobalizedLocal =
7138 AI.LibraryFunctionId == LibFunc___kmpc_alloc_shared;
7139 if (AI.MoveAllocaIntoEntry &&
7140 (!Size.has_value() ||
7141 (!IsGlobalizedLocal && IsInLoop(*AI.CB->getParent()))))
7142 AI.MoveAllocaIntoEntry = false;
7143 }
7144
7145 return Changed;
7146}
7147} // namespace
7148
7149/// ----------------------- Privatizable Pointers ------------------------------
7150namespace {
7151struct AAPrivatizablePtrImpl : public AAPrivatizablePtr {
7152 AAPrivatizablePtrImpl(const IRPosition &IRP, Attributor &A)
7153 : AAPrivatizablePtr(IRP, A), PrivatizableType(std::nullopt) {}
7154
7155 ChangeStatus indicatePessimisticFixpoint() override {
7156 AAPrivatizablePtr::indicatePessimisticFixpoint();
7157 PrivatizableType = nullptr;
7158 return ChangeStatus::CHANGED;
7159 }
7160
7161 /// Identify the type we can chose for a private copy of the underlying
7162 /// argument. std::nullopt means it is not clear yet, nullptr means there is
7163 /// none.
7164 virtual std::optional<Type *> identifyPrivatizableType(Attributor &A) = 0;
7165
7166 /// Return a privatizable type that encloses both T0 and T1.
7167 /// TODO: This is merely a stub for now as we should manage a mapping as well.
7168 std::optional<Type *> combineTypes(std::optional<Type *> T0,
7169 std::optional<Type *> T1) {
7170 if (!T0)
7171 return T1;
7172 if (!T1)
7173 return T0;
7174 if (T0 == T1)
7175 return T0;
7176 return nullptr;
7177 }
7178
7179 std::optional<Type *> getPrivatizableType() const override {
7180 return PrivatizableType;
7181 }
7182
7183 const std::string getAsStr(Attributor *A) const override {
7184 return isAssumedPrivatizablePtr() ? "[priv]" : "[no-priv]";
7185 }
7186
7187protected:
7188 std::optional<Type *> PrivatizableType;
7189};
7190
7191// TODO: Do this for call site arguments (probably also other values) as well.
7192
7193struct AAPrivatizablePtrArgument final : public AAPrivatizablePtrImpl {
7194 AAPrivatizablePtrArgument(const IRPosition &IRP, Attributor &A)
7195 : AAPrivatizablePtrImpl(IRP, A) {}
7196
7197 /// See AAPrivatizablePtrImpl::identifyPrivatizableType(...)
7198 std::optional<Type *> identifyPrivatizableType(Attributor &A) override {
7199 // If this is a byval argument and we know all the call sites (so we can
7200 // rewrite them), there is no need to check them explicitly.
7201 bool UsedAssumedInformation = false;
7203 A.getAttrs(getIRPosition(), {Attribute::ByVal}, Attrs,
7204 /* IgnoreSubsumingPositions */ true);
7205 if (!Attrs.empty() &&
7206 A.checkForAllCallSites([](AbstractCallSite ACS) { return true; }, *this,
7207 true, UsedAssumedInformation))
7208 return Attrs[0].getValueAsType();
7209
7210 std::optional<Type *> Ty;
7211 unsigned ArgNo = getIRPosition().getCallSiteArgNo();
7212
7213 // Make sure the associated call site argument has the same type at all call
7214 // sites and it is an allocation we know is safe to privatize, for now that
7215 // means we only allow alloca instructions.
7216 // TODO: We can additionally analyze the accesses in the callee to create
7217 // the type from that information instead. That is a little more
7218 // involved and will be done in a follow up patch.
7219 auto CallSiteCheck = [&](AbstractCallSite ACS) {
7220 IRPosition ACSArgPos = IRPosition::callsite_argument(ACS, ArgNo);
7221 // Check if a coresponding argument was found or if it is one not
7222 // associated (which can happen for callback calls).
7223 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
7224 return false;
7225
7226 // Check that all call sites agree on a type.
7227 auto *PrivCSArgAA =
7228 A.getAAFor<AAPrivatizablePtr>(*this, ACSArgPos, DepClassTy::REQUIRED);
7229 if (!PrivCSArgAA)
7230 return false;
7231 std::optional<Type *> CSTy = PrivCSArgAA->getPrivatizableType();
7232
7233 LLVM_DEBUG({
7234 dbgs() << "[AAPrivatizablePtr] ACSPos: " << ACSArgPos << ", CSTy: ";
7235 if (CSTy && *CSTy)
7236 (*CSTy)->print(dbgs());
7237 else if (CSTy)
7238 dbgs() << "<nullptr>";
7239 else
7240 dbgs() << "<none>";
7241 });
7242
7243 Ty = combineTypes(Ty, CSTy);
7244
7245 LLVM_DEBUG({
7246 dbgs() << " : New Type: ";
7247 if (Ty && *Ty)
7248 (*Ty)->print(dbgs());
7249 else if (Ty)
7250 dbgs() << "<nullptr>";
7251 else
7252 dbgs() << "<none>";
7253 dbgs() << "\n";
7254 });
7255
7256 return !Ty || *Ty;
7257 };
7258
7259 if (!A.checkForAllCallSites(CallSiteCheck, *this, true,
7260 UsedAssumedInformation))
7261 return nullptr;
7262 return Ty;
7263 }
7264
7265 /// See AbstractAttribute::updateImpl(...).
7266 ChangeStatus updateImpl(Attributor &A) override {
7267 PrivatizableType = identifyPrivatizableType(A);
7268 if (!PrivatizableType)
7269 return ChangeStatus::UNCHANGED;
7270 if (!*PrivatizableType)
7271 return indicatePessimisticFixpoint();
7272
7273 // The dependence is optional so we don't give up once we give up on the
7274 // alignment.
7275 A.getAAFor<AAAlign>(*this, IRPosition::value(getAssociatedValue()),
7276 DepClassTy::OPTIONAL);
7277
7278 // Avoid arguments with padding for now.
7279 if (!A.hasAttr(getIRPosition(), Attribute::ByVal) &&
7280 !isDenselyPacked(*PrivatizableType, A.getInfoCache().getDL())) {
7281 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Padding detected\n");
7282 return indicatePessimisticFixpoint();
7283 }
7284
7285 // Collect the types that will replace the privatizable type in the function
7286 // signature.
7287 SmallVector<Type *, 16> ReplacementTypes;
7288 identifyReplacementTypes(*PrivatizableType, ReplacementTypes);
7289
7290 // Verify callee and caller agree on how the promoted argument would be
7291 // passed.
7292 Function &Fn = *getIRPosition().getAnchorScope();
7293 const auto *TTI =
7294 A.getInfoCache().getAnalysisResultForFunction<TargetIRAnalysis>(Fn);
7295 if (!TTI) {
7296 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Missing TTI for function "
7297 << Fn.getName() << "\n");
7298 return indicatePessimisticFixpoint();
7299 }
7300
7301 auto CallSiteCheck = [&](AbstractCallSite ACS) {
7302 CallBase *CB = ACS.getInstruction();
7303 return TTI->areTypesABICompatible(
7304 CB->getCaller(),
7305 dyn_cast_if_present<Function>(CB->getCalledOperand()),
7306 ReplacementTypes);
7307 };
7308 bool UsedAssumedInformation = false;
7309 if (!A.checkForAllCallSites(CallSiteCheck, *this, true,
7310 UsedAssumedInformation)) {
7311 LLVM_DEBUG(
7312 dbgs() << "[AAPrivatizablePtr] ABI incompatibility detected for "
7313 << Fn.getName() << "\n");
7314 return indicatePessimisticFixpoint();
7315 }
7316
7317 // Register a rewrite of the argument.
7318 Argument *Arg = getAssociatedArgument();
7319 if (!A.isValidFunctionSignatureRewrite(*Arg, ReplacementTypes)) {
7320 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Rewrite not valid\n");
7321 return indicatePessimisticFixpoint();
7322 }
7323
7324 unsigned ArgNo = Arg->getArgNo();
7325
7326 // Helper to check if for the given call site the associated argument is
7327 // passed to a callback where the privatization would be different.
7328 auto IsCompatiblePrivArgOfCallback = [&](CallBase &CB) {
7329 SmallVector<const Use *, 4> CallbackUses;
7330 AbstractCallSite::getCallbackUses(CB, CallbackUses);
7331 for (const Use *U : CallbackUses) {
7332 AbstractCallSite CBACS(U);
7333 assert(CBACS && CBACS.isCallbackCall());
7334 for (Argument &CBArg : CBACS.getCalledFunction()->args()) {
7335 int CBArgNo = CBACS.getCallArgOperandNo(CBArg);
7336
7337 LLVM_DEBUG({
7338 dbgs()
7339 << "[AAPrivatizablePtr] Argument " << *Arg
7340 << "check if can be privatized in the context of its parent ("
7341 << Arg->getParent()->getName()
7342 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7343 "callback ("
7344 << CBArgNo << "@" << CBACS.getCalledFunction()->getName()
7345 << ")\n[AAPrivatizablePtr] " << CBArg << " : "
7346 << CBACS.getCallArgOperand(CBArg) << " vs "
7347 << CB.getArgOperand(ArgNo) << "\n"
7348 << "[AAPrivatizablePtr] " << CBArg << " : "
7349 << CBACS.getCallArgOperandNo(CBArg) << " vs " << ArgNo << "\n";
7350 });
7351
7352 if (CBArgNo != int(ArgNo))
7353 continue;
7354 const auto *CBArgPrivAA = A.getAAFor<AAPrivatizablePtr>(
7355 *this, IRPosition::argument(CBArg), DepClassTy::REQUIRED);
7356 if (CBArgPrivAA && CBArgPrivAA->isValidState()) {
7357 auto CBArgPrivTy = CBArgPrivAA->getPrivatizableType();
7358 if (!CBArgPrivTy)
7359 continue;
7360 if (*CBArgPrivTy == PrivatizableType)
7361 continue;
7362 }
7363
7364 LLVM_DEBUG({
7365 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
7366 << " cannot be privatized in the context of its parent ("
7367 << Arg->getParent()->getName()
7368 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7369 "callback ("
7370 << CBArgNo << "@" << CBACS.getCalledFunction()->getName()
7371 << ").\n[AAPrivatizablePtr] for which the argument "
7372 "privatization is not compatible.\n";
7373 });
7374 return false;
7375 }
7376 }
7377 return true;
7378 };
7379
7380 // Helper to check if for the given call site the associated argument is
7381 // passed to a direct call where the privatization would be different.
7382 auto IsCompatiblePrivArgOfDirectCS = [&](AbstractCallSite ACS) {
7383 CallBase *DC = cast<CallBase>(ACS.getInstruction());
7384 int DCArgNo = ACS.getCallArgOperandNo(ArgNo);
7385 assert(DCArgNo >= 0 && unsigned(DCArgNo) < DC->arg_size() &&
7386 "Expected a direct call operand for callback call operand");
7387
7388 Function *DCCallee =
7389 dyn_cast_if_present<Function>(DC->getCalledOperand());
7390 LLVM_DEBUG({
7391 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
7392 << " check if be privatized in the context of its parent ("
7393 << Arg->getParent()->getName()
7394 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7395 "direct call of ("
7396 << DCArgNo << "@" << DCCallee->getName() << ").\n";
7397 });
7398
7399 if (unsigned(DCArgNo) < DCCallee->arg_size()) {
7400 const auto *DCArgPrivAA = A.getAAFor<AAPrivatizablePtr>(
7401 *this, IRPosition::argument(*DCCallee->getArg(DCArgNo)),
7402 DepClassTy::REQUIRED);
7403 if (DCArgPrivAA && DCArgPrivAA->isValidState()) {
7404 auto DCArgPrivTy = DCArgPrivAA->getPrivatizableType();
7405 if (!DCArgPrivTy)
7406 return true;
7407 if (*DCArgPrivTy == PrivatizableType)
7408 return true;
7409 }
7410 }
7411
7412 LLVM_DEBUG({
7413 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
7414 << " cannot be privatized in the context of its parent ("
7415 << Arg->getParent()->getName()
7416 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7417 "direct call of ("
7419 << ").\n[AAPrivatizablePtr] for which the argument "
7420 "privatization is not compatible.\n";
7421 });
7422 return false;
7423 };
7424
7425 // Helper to check if the associated argument is used at the given abstract
7426 // call site in a way that is incompatible with the privatization assumed
7427 // here.
7428 auto IsCompatiblePrivArgOfOtherCallSite = [&](AbstractCallSite ACS) {
7429 if (ACS.isDirectCall())
7430 return IsCompatiblePrivArgOfCallback(*ACS.getInstruction());
7431 if (ACS.isCallbackCall())
7432 return IsCompatiblePrivArgOfDirectCS(ACS);
7433 return false;
7434 };
7435
7436 if (!A.checkForAllCallSites(IsCompatiblePrivArgOfOtherCallSite, *this, true,
7437 UsedAssumedInformation))
7438 return indicatePessimisticFixpoint();
7439
7440 return ChangeStatus::UNCHANGED;
7441 }
7442
7443 /// Given a type to private \p PrivType, collect the constituates (which are
7444 /// used) in \p ReplacementTypes.
7445 static void
7446 identifyReplacementTypes(Type *PrivType,
7447 SmallVectorImpl<Type *> &ReplacementTypes) {
7448 // TODO: For now we expand the privatization type to the fullest which can
7449 // lead to dead arguments that need to be removed later.
7450 assert(PrivType && "Expected privatizable type!");
7451
7452 // Traverse the type, extract constituate types on the outermost level.
7453 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) {
7454 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++)
7455 ReplacementTypes.push_back(PrivStructType->getElementType(u));
7456 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) {
7457 ReplacementTypes.append(PrivArrayType->getNumElements(),
7458 PrivArrayType->getElementType());
7459 } else {
7460 ReplacementTypes.push_back(PrivType);
7461 }
7462 }
7463
7464 /// Initialize \p Base according to the type \p PrivType at position \p IP.
7465 /// The values needed are taken from the arguments of \p F starting at
7466 /// position \p ArgNo.
7467 static void createInitialization(Type *PrivType, Value &Base, Function &F,
7468 unsigned ArgNo, BasicBlock::iterator IP) {
7469 assert(PrivType && "Expected privatizable type!");
7470
7471 IRBuilder<NoFolder> IRB(IP->getParent(), IP);
7472 const DataLayout &DL = F.getDataLayout();
7473
7474 // Traverse the type, build GEPs and stores.
7475 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) {
7476 const StructLayout *PrivStructLayout = DL.getStructLayout(PrivStructType);
7477 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++) {
7478 Value *Ptr =
7479 constructPointer(&Base, PrivStructLayout->getElementOffset(u), IRB);
7480 new StoreInst(F.getArg(ArgNo + u), Ptr, IP);
7481 }
7482 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) {
7483 Type *PointeeTy = PrivArrayType->getElementType();
7484 uint64_t PointeeTySize = DL.getTypeStoreSize(PointeeTy);
7485 for (unsigned u = 0, e = PrivArrayType->getNumElements(); u < e; u++) {
7486 Value *Ptr = constructPointer(&Base, u * PointeeTySize, IRB);
7487 new StoreInst(F.getArg(ArgNo + u), Ptr, IP);
7488 }
7489 } else {
7490 new StoreInst(F.getArg(ArgNo), &Base, IP);
7491 }
7492 }
7493
7494 /// Extract values from \p Base according to the type \p PrivType at the
7495 /// call position \p ACS. The values are appended to \p ReplacementValues.
7496 void createReplacementValues(Align Alignment, Type *PrivType,
7498 SmallVectorImpl<Value *> &ReplacementValues) {
7499 assert(Base && "Expected base value!");
7500 assert(PrivType && "Expected privatizable type!");
7501 Instruction *IP = ACS.getInstruction();
7502
7503 IRBuilder<NoFolder> IRB(IP);
7504 const DataLayout &DL = IP->getDataLayout();
7505
7506 // Traverse the type, build GEPs and loads.
7507 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) {
7508 const StructLayout *PrivStructLayout = DL.getStructLayout(PrivStructType);
7509 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++) {
7510 Type *PointeeTy = PrivStructType->getElementType(u);
7511 Value *Ptr =
7512 constructPointer(Base, PrivStructLayout->getElementOffset(u), IRB);
7513 LoadInst *L = new LoadInst(PointeeTy, Ptr, "", IP->getIterator());
7514 L->setAlignment(Alignment);
7515 ReplacementValues.push_back(L);
7516 }
7517 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) {
7518 Type *PointeeTy = PrivArrayType->getElementType();
7519 uint64_t PointeeTySize = DL.getTypeStoreSize(PointeeTy);
7520 for (unsigned u = 0, e = PrivArrayType->getNumElements(); u < e; u++) {
7521 Value *Ptr = constructPointer(Base, u * PointeeTySize, IRB);
7522 LoadInst *L = new LoadInst(PointeeTy, Ptr, "", IP->getIterator());
7523 L->setAlignment(Alignment);
7524 ReplacementValues.push_back(L);
7525 }
7526 } else {
7527 LoadInst *L = new LoadInst(PrivType, Base, "", IP->getIterator());
7528 L->setAlignment(Alignment);
7529 ReplacementValues.push_back(L);
7530 }
7531 }
7532
7533 /// See AbstractAttribute::manifest(...)
7534 ChangeStatus manifest(Attributor &A) override {
7535 if (!PrivatizableType)
7536 return ChangeStatus::UNCHANGED;
7537 assert(*PrivatizableType && "Expected privatizable type!");
7538
7539 // Collect all tail calls in the function as we cannot allow new allocas to
7540 // escape into tail recursion.
7541 // TODO: Be smarter about new allocas escaping into tail calls.
7543 bool UsedAssumedInformation = false;
7544 if (!A.checkForAllInstructions(
7545 [&](Instruction &I) {
7546 CallInst &CI = cast<CallInst>(I);
7547 if (CI.isTailCall())
7548 TailCalls.push_back(&CI);
7549 return true;
7550 },
7551 *this, {Instruction::Call}, UsedAssumedInformation))
7552 return ChangeStatus::UNCHANGED;
7553
7554 Argument *Arg = getAssociatedArgument();
7555 // Query AAAlign attribute for alignment of associated argument to
7556 // determine the best alignment of loads.
7557 const auto *AlignAA =
7558 A.getAAFor<AAAlign>(*this, IRPosition::value(*Arg), DepClassTy::NONE);
7559
7560 // Callback to repair the associated function. A new alloca is placed at the
7561 // beginning and initialized with the values passed through arguments. The
7562 // new alloca replaces the use of the old pointer argument.
7565 Function &ReplacementFn, Function::arg_iterator ArgIt) {
7566 BasicBlock &EntryBB = ReplacementFn.getEntryBlock();
7568 const DataLayout &DL = IP->getDataLayout();
7569 unsigned AS = DL.getAllocaAddrSpace();
7570 Instruction *AI = new AllocaInst(*PrivatizableType, AS,
7571 Arg->getName() + ".priv", IP);
7572 createInitialization(*PrivatizableType, *AI, ReplacementFn,
7573 ArgIt->getArgNo(), IP);
7574
7575 if (AI->getType() != Arg->getType())
7576 AI = BitCastInst::CreatePointerBitCastOrAddrSpaceCast(
7577 AI, Arg->getType(), "", IP);
7578 Arg->replaceAllUsesWith(AI);
7579
7580 for (CallInst *CI : TailCalls)
7581 CI->setTailCall(false);
7582 };
7583
7584 // Callback to repair a call site of the associated function. The elements
7585 // of the privatizable type are loaded prior to the call and passed to the
7586 // new function version.
7589 AbstractCallSite ACS, SmallVectorImpl<Value *> &NewArgOperands) {
7590 // When no alignment is specified for the load instruction,
7591 // natural alignment is assumed.
7592 createReplacementValues(
7593 AlignAA ? AlignAA->getAssumedAlign() : Align(0),
7594 *PrivatizableType, ACS,
7595 ACS.getCallArgOperand(ARI.getReplacedArg().getArgNo()),
7596 NewArgOperands);
7597 };
7598
7599 // Collect the types that will replace the privatizable type in the function
7600 // signature.
7601 SmallVector<Type *, 16> ReplacementTypes;
7602 identifyReplacementTypes(*PrivatizableType, ReplacementTypes);
7603
7604 // Register a rewrite of the argument.
7605 if (A.registerFunctionSignatureRewrite(*Arg, ReplacementTypes,
7606 std::move(FnRepairCB),
7607 std::move(ACSRepairCB)))
7608 return ChangeStatus::CHANGED;
7609 return ChangeStatus::UNCHANGED;
7610 }
7611
7612 /// See AbstractAttribute::trackStatistics()
7613 void trackStatistics() const override {
7614 STATS_DECLTRACK_ARG_ATTR(privatizable_ptr);
7615 }
7616};
7617
7618struct AAPrivatizablePtrFloating : public AAPrivatizablePtrImpl {
7619 AAPrivatizablePtrFloating(const IRPosition &IRP, Attributor &A)
7620 : AAPrivatizablePtrImpl(IRP, A) {}
7621
7622 /// See AbstractAttribute::initialize(...).
7623 void initialize(Attributor &A) override {
7624 // TODO: We can privatize more than arguments.
7625 indicatePessimisticFixpoint();
7626 }
7627
7628 ChangeStatus updateImpl(Attributor &A) override {
7629 llvm_unreachable("AAPrivatizablePtr(Floating|Returned|CallSiteReturned)::"
7630 "updateImpl will not be called");
7631 }
7632
7633 /// See AAPrivatizablePtrImpl::identifyPrivatizableType(...)
7634 std::optional<Type *> identifyPrivatizableType(Attributor &A) override {
7635 Value *Obj = getUnderlyingObject(&getAssociatedValue());
7636 if (!Obj) {
7637 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] No underlying object found!\n");
7638 return nullptr;
7639 }
7640
7641 if (auto *AI = dyn_cast<AllocaInst>(Obj))
7642 if (auto *CI = dyn_cast<ConstantInt>(AI->getArraySize()))
7643 if (CI->isOne())
7644 return AI->getAllocatedType();
7645 if (auto *Arg = dyn_cast<Argument>(Obj)) {
7646 auto *PrivArgAA = A.getAAFor<AAPrivatizablePtr>(
7647 *this, IRPosition::argument(*Arg), DepClassTy::REQUIRED);
7648 if (PrivArgAA && PrivArgAA->isAssumedPrivatizablePtr())
7649 return PrivArgAA->getPrivatizableType();
7650 }
7651
7652 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Underlying object neither valid "
7653 "alloca nor privatizable argument: "
7654 << *Obj << "!\n");
7655 return nullptr;
7656 }
7657
7658 /// See AbstractAttribute::trackStatistics()
7659 void trackStatistics() const override {
7660 STATS_DECLTRACK_FLOATING_ATTR(privatizable_ptr);
7661 }
7662};
7663
7664struct AAPrivatizablePtrCallSiteArgument final
7665 : public AAPrivatizablePtrFloating {
7666 AAPrivatizablePtrCallSiteArgument(const IRPosition &IRP, Attributor &A)
7667 : AAPrivatizablePtrFloating(IRP, A) {}
7668
7669 /// See AbstractAttribute::initialize(...).
7670 void initialize(Attributor &A) override {
7671 if (A.hasAttr(getIRPosition(), Attribute::ByVal))
7672 indicateOptimisticFixpoint();
7673 }
7674
7675 /// See AbstractAttribute::updateImpl(...).
7676 ChangeStatus updateImpl(Attributor &A) override {
7677 PrivatizableType = identifyPrivatizableType(A);
7678 if (!PrivatizableType)
7679 return ChangeStatus::UNCHANGED;
7680 if (!*PrivatizableType)
7681 return indicatePessimisticFixpoint();
7682
7683 const IRPosition &IRP = getIRPosition();
7684 bool IsKnownNoCapture;
7685 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::NoCapture>(
7686 A, this, IRP, DepClassTy::REQUIRED, IsKnownNoCapture);
7687 if (!IsAssumedNoCapture) {
7688 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer might be captured!\n");
7689 return indicatePessimisticFixpoint();
7690 }
7691
7692 bool IsKnownNoAlias;
7693 if (!AA::hasAssumedIRAttr<Attribute::NoAlias>(
7694 A, this, IRP, DepClassTy::REQUIRED, IsKnownNoAlias)) {
7695 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer might alias!\n");
7696 return indicatePessimisticFixpoint();
7697 }
7698
7699 bool IsKnown;
7700 if (!AA::isAssumedReadOnly(A, IRP, *this, IsKnown)) {
7701 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer is written!\n");
7702 return indicatePessimisticFixpoint();
7703 }
7704
7705 return ChangeStatus::UNCHANGED;
7706 }
7707
7708 /// See AbstractAttribute::trackStatistics()
7709 void trackStatistics() const override {
7710 STATS_DECLTRACK_CSARG_ATTR(privatizable_ptr);
7711 }
7712};
7713
7714struct AAPrivatizablePtrCallSiteReturned final
7715 : public AAPrivatizablePtrFloating {
7716 AAPrivatizablePtrCallSiteReturned(const IRPosition &IRP, Attributor &A)
7717 : AAPrivatizablePtrFloating(IRP, A) {}
7718
7719 /// See AbstractAttribute::initialize(...).
7720 void initialize(Attributor &A) override {
7721 // TODO: We can privatize more than arguments.
7722 indicatePessimisticFixpoint();
7723 }
7724
7725 /// See AbstractAttribute::trackStatistics()
7726 void trackStatistics() const override {
7727 STATS_DECLTRACK_CSRET_ATTR(privatizable_ptr);
7728 }
7729};
7730
7731struct AAPrivatizablePtrReturned final : public AAPrivatizablePtrFloating {
7732 AAPrivatizablePtrReturned(const IRPosition &IRP, Attributor &A)
7733 : AAPrivatizablePtrFloating(IRP, A) {}
7734
7735 /// See AbstractAttribute::initialize(...).
7736 void initialize(Attributor &A) override {
7737 // TODO: We can privatize more than arguments.
7738 indicatePessimisticFixpoint();
7739 }
7740
7741 /// See AbstractAttribute::trackStatistics()
7742 void trackStatistics() const override {
7743 STATS_DECLTRACK_FNRET_ATTR(privatizable_ptr);
7744 }
7745};
7746} // namespace
7747
7748/// -------------------- Memory Behavior Attributes ----------------------------
7749/// Includes read-none, read-only, and write-only.
7750/// ----------------------------------------------------------------------------
7751namespace {
7752struct AAMemoryBehaviorImpl : public AAMemoryBehavior {
7753 AAMemoryBehaviorImpl(const IRPosition &IRP, Attributor &A)
7754 : AAMemoryBehavior(IRP, A) {}
7755
7756 /// See AbstractAttribute::initialize(...).
7757 void initialize(Attributor &A) override {
7758 intersectAssumedBits(BEST_STATE);
7759 getKnownStateFromValue(A, getIRPosition(), getState());
7760 AAMemoryBehavior::initialize(A);
7761 }
7762
7763 /// Return the memory behavior information encoded in the IR for \p IRP.
7764 static void getKnownStateFromValue(Attributor &A, const IRPosition &IRP,
7765 BitIntegerState &State,
7766 bool IgnoreSubsumingPositions = false) {
7768 A.getAttrs(IRP, AttrKinds, Attrs, IgnoreSubsumingPositions);
7769 for (const Attribute &Attr : Attrs) {
7770 switch (Attr.getKindAsEnum()) {
7771 case Attribute::ReadNone:
7772 State.addKnownBits(NO_ACCESSES);
7773 break;
7774 case Attribute::ReadOnly:
7775 State.addKnownBits(NO_WRITES);
7776 break;
7777 case Attribute::WriteOnly:
7778 State.addKnownBits(NO_READS);
7779 break;
7780 default:
7781 llvm_unreachable("Unexpected attribute!");
7782 }
7783 }
7784
7785 if (auto *I = dyn_cast<Instruction>(&IRP.getAnchorValue())) {
7786 if (!I->mayReadFromMemory())
7787 State.addKnownBits(NO_READS);
7788 if (!I->mayWriteToMemory())
7789 State.addKnownBits(NO_WRITES);
7790 }
7791 }
7792
7793 /// See AbstractAttribute::getDeducedAttributes(...).
7794 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
7795 SmallVectorImpl<Attribute> &Attrs) const override {
7796 assert(Attrs.size() == 0);
7797 if (isAssumedReadNone())
7798 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadNone));
7799 else if (isAssumedReadOnly())
7800 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadOnly));
7801 else if (isAssumedWriteOnly())
7802 Attrs.push_back(Attribute::get(Ctx, Attribute::WriteOnly));
7803 assert(Attrs.size() <= 1);
7804 }
7805
7806 /// See AbstractAttribute::manifest(...).
7807 ChangeStatus manifest(Attributor &A) override {
7808 const IRPosition &IRP = getIRPosition();
7809
7810 if (A.hasAttr(IRP, Attribute::ReadNone,
7811 /* IgnoreSubsumingPositions */ true))
7812 return ChangeStatus::UNCHANGED;
7813
7814 // Check if we would improve the existing attributes first.
7815 SmallVector<Attribute, 4> DeducedAttrs;
7816 getDeducedAttributes(A, IRP.getAnchorValue().getContext(), DeducedAttrs);
7817 if (llvm::all_of(DeducedAttrs, [&](const Attribute &Attr) {
7818 return A.hasAttr(IRP, Attr.getKindAsEnum(),
7819 /* IgnoreSubsumingPositions */ true);
7820 }))
7821 return ChangeStatus::UNCHANGED;
7822
7823 // Clear existing attributes.
7824 A.removeAttrs(IRP, AttrKinds);
7825 // Clear conflicting writable attribute.
7826 if (isAssumedReadOnly())
7827 A.removeAttrs(IRP, Attribute::Writable);
7828
7829 // Use the generic manifest method.
7830 return IRAttribute::manifest(A);
7831 }
7832
7833 /// See AbstractState::getAsStr().
7834 const std::string getAsStr(Attributor *A) const override {
7835 if (isAssumedReadNone())
7836 return "readnone";
7837 if (isAssumedReadOnly())
7838 return "readonly";
7839 if (isAssumedWriteOnly())
7840 return "writeonly";
7841 return "may-read/write";
7842 }
7843
7844 /// The set of IR attributes AAMemoryBehavior deals with.
7845 static const Attribute::AttrKind AttrKinds[3];
7846};
7847
7848const Attribute::AttrKind AAMemoryBehaviorImpl::AttrKinds[] = {
7849 Attribute::ReadNone, Attribute::ReadOnly, Attribute::WriteOnly};
7850
7851/// Memory behavior attribute for a floating value.
7852struct AAMemoryBehaviorFloating : AAMemoryBehaviorImpl {
7853 AAMemoryBehaviorFloating(const IRPosition &IRP, Attributor &A)
7854 : AAMemoryBehaviorImpl(IRP, A) {}
7855
7856 /// See AbstractAttribute::updateImpl(...).
7857 ChangeStatus updateImpl(Attributor &A) override;
7858
7859 /// See AbstractAttribute::trackStatistics()
7860 void trackStatistics() const override {
7861 if (isAssumedReadNone())
7863 else if (isAssumedReadOnly())
7865 else if (isAssumedWriteOnly())
7867 }
7868
7869private:
7870 /// Return true if users of \p UserI might access the underlying
7871 /// variable/location described by \p U and should therefore be analyzed.
7872 bool followUsersOfUseIn(Attributor &A, const Use &U,
7873 const Instruction *UserI);
7874
7875 /// Update the state according to the effect of use \p U in \p UserI.
7876 void analyzeUseIn(Attributor &A, const Use &U, const Instruction *UserI);
7877};
7878
7879/// Memory behavior attribute for function argument.
7880struct AAMemoryBehaviorArgument : AAMemoryBehaviorFloating {
7881 AAMemoryBehaviorArgument(const IRPosition &IRP, Attributor &A)
7882 : AAMemoryBehaviorFloating(IRP, A) {}
7883
7884 /// See AbstractAttribute::initialize(...).
7885 void initialize(Attributor &A) override {
7886 intersectAssumedBits(BEST_STATE);
7887 const IRPosition &IRP = getIRPosition();
7888 // TODO: Make IgnoreSubsumingPositions a property of an IRAttribute so we
7889 // can query it when we use has/getAttr. That would allow us to reuse the
7890 // initialize of the base class here.
7891 bool HasByVal = A.hasAttr(IRP, {Attribute::ByVal},
7892 /* IgnoreSubsumingPositions */ true);
7893 getKnownStateFromValue(A, IRP, getState(),
7894 /* IgnoreSubsumingPositions */ HasByVal);
7895 }
7896
7897 ChangeStatus manifest(Attributor &A) override {
7898 // TODO: Pointer arguments are not supported on vectors of pointers yet.
7899 if (!getAssociatedValue().getType()->isPointerTy())
7900 return ChangeStatus::UNCHANGED;
7901
7902 // TODO: From readattrs.ll: "inalloca parameters are always
7903 // considered written"
7904 if (A.hasAttr(getIRPosition(),
7905 {Attribute::InAlloca, Attribute::Preallocated})) {
7906 removeKnownBits(NO_WRITES);
7907 removeAssumedBits(NO_WRITES);
7908 }
7909 A.removeAttrs(getIRPosition(), AttrKinds);
7910 return AAMemoryBehaviorFloating::manifest(A);
7911 }
7912
7913 /// See AbstractAttribute::trackStatistics()
7914 void trackStatistics() const override {
7915 if (isAssumedReadNone())
7916 STATS_DECLTRACK_ARG_ATTR(readnone)
7917 else if (isAssumedReadOnly())
7918 STATS_DECLTRACK_ARG_ATTR(readonly)
7919 else if (isAssumedWriteOnly())
7920 STATS_DECLTRACK_ARG_ATTR(writeonly)
7921 }
7922};
7923
7924struct AAMemoryBehaviorCallSiteArgument final : AAMemoryBehaviorArgument {
7925 AAMemoryBehaviorCallSiteArgument(const IRPosition &IRP, Attributor &A)
7926 : AAMemoryBehaviorArgument(IRP, A) {}
7927
7928 /// See AbstractAttribute::initialize(...).
7929 void initialize(Attributor &A) override {
7930 // If we don't have an associated attribute this is either a variadic call
7931 // or an indirect call, either way, nothing to do here.
7932 Argument *Arg = getAssociatedArgument();
7933 if (!Arg) {
7934 indicatePessimisticFixpoint();
7935 return;
7936 }
7937 if (Arg->hasByValAttr()) {
7938 addKnownBits(NO_WRITES);
7939 removeKnownBits(NO_READS);
7940 removeAssumedBits(NO_READS);
7941 }
7942 AAMemoryBehaviorArgument::initialize(A);
7943 if (getAssociatedFunction()->isDeclaration())
7944 indicatePessimisticFixpoint();
7945 }
7946
7947 /// See AbstractAttribute::updateImpl(...).
7948 ChangeStatus updateImpl(Attributor &A) override {
7949 // TODO: Once we have call site specific value information we can provide
7950 // call site specific liveness liveness information and then it makes
7951 // sense to specialize attributes for call sites arguments instead of
7952 // redirecting requests to the callee argument.
7953 Argument *Arg = getAssociatedArgument();
7954 const IRPosition &ArgPos = IRPosition::argument(*Arg);
7955 auto *ArgAA =
7956 A.getAAFor<AAMemoryBehavior>(*this, ArgPos, DepClassTy::REQUIRED);
7957 if (!ArgAA)
7958 return indicatePessimisticFixpoint();
7959 return clampStateAndIndicateChange(getState(), ArgAA->getState());
7960 }
7961
7962 /// See AbstractAttribute::trackStatistics()
7963 void trackStatistics() const override {
7964 if (isAssumedReadNone())
7966 else if (isAssumedReadOnly())
7968 else if (isAssumedWriteOnly())
7970 }
7971};
7972
7973/// Memory behavior attribute for a call site return position.
7974struct AAMemoryBehaviorCallSiteReturned final : AAMemoryBehaviorFloating {
7975 AAMemoryBehaviorCallSiteReturned(const IRPosition &IRP, Attributor &A)
7976 : AAMemoryBehaviorFloating(IRP, A) {}
7977
7978 /// See AbstractAttribute::initialize(...).
7979 void initialize(Attributor &A) override {
7980 AAMemoryBehaviorImpl::initialize(A);
7981 }
7982 /// See AbstractAttribute::manifest(...).
7983 ChangeStatus manifest(Attributor &A) override {
7984 // We do not annotate returned values.
7985 return ChangeStatus::UNCHANGED;
7986 }
7987
7988 /// See AbstractAttribute::trackStatistics()
7989 void trackStatistics() const override {}
7990};
7991
7992/// An AA to represent the memory behavior function attributes.
7993struct AAMemoryBehaviorFunction final : public AAMemoryBehaviorImpl {
7994 AAMemoryBehaviorFunction(const IRPosition &IRP, Attributor &A)
7995 : AAMemoryBehaviorImpl(IRP, A) {}
7996
7997 /// See AbstractAttribute::updateImpl(Attributor &A).
7998 ChangeStatus updateImpl(Attributor &A) override;
7999
8000 /// See AbstractAttribute::manifest(...).
8001 ChangeStatus manifest(Attributor &A) override {
8002 // TODO: It would be better to merge this with AAMemoryLocation, so that
8003 // we could determine read/write per location. This would also have the
8004 // benefit of only one place trying to manifest the memory attribute.
8005 Function &F = cast<Function>(getAnchorValue());
8007 if (isAssumedReadNone())
8008 ME = MemoryEffects::none();
8009 else if (isAssumedReadOnly())
8011 else if (isAssumedWriteOnly())
8013
8014 A.removeAttrs(getIRPosition(), AttrKinds);
8015 // Clear conflicting writable attribute.
8016 if (ME.onlyReadsMemory())
8017 for (Argument &Arg : F.args())
8018 A.removeAttrs(IRPosition::argument(Arg), Attribute::Writable);
8019 return A.manifestAttrs(getIRPosition(),
8020 Attribute::getWithMemoryEffects(F.getContext(), ME));
8021 }
8022
8023 /// See AbstractAttribute::trackStatistics()
8024 void trackStatistics() const override {
8025 if (isAssumedReadNone())
8026 STATS_DECLTRACK_FN_ATTR(readnone)
8027 else if (isAssumedReadOnly())
8028 STATS_DECLTRACK_FN_ATTR(readonly)
8029 else if (isAssumedWriteOnly())
8030 STATS_DECLTRACK_FN_ATTR(writeonly)
8031 }
8032};
8033
8034/// AAMemoryBehavior attribute for call sites.
8035struct AAMemoryBehaviorCallSite final
8036 : AACalleeToCallSite<AAMemoryBehavior, AAMemoryBehaviorImpl> {
8037 AAMemoryBehaviorCallSite(const IRPosition &IRP, Attributor &A)
8038 : AACalleeToCallSite<AAMemoryBehavior, AAMemoryBehaviorImpl>(IRP, A) {}
8039
8040 /// See AbstractAttribute::manifest(...).
8041 ChangeStatus manifest(Attributor &A) override {
8042 // TODO: Deduplicate this with AAMemoryBehaviorFunction.
8043 CallBase &CB = cast<CallBase>(getAnchorValue());
8045 if (isAssumedReadNone())
8046 ME = MemoryEffects::none();
8047 else if (isAssumedReadOnly())
8049 else if (isAssumedWriteOnly())
8051
8052 A.removeAttrs(getIRPosition(), AttrKinds);
8053 // Clear conflicting writable attribute.
8054 if (ME.onlyReadsMemory())
8055 for (Use &U : CB.args())
8056 A.removeAttrs(IRPosition::callsite_argument(CB, U.getOperandNo()),
8057 Attribute::Writable);
8058 return A.manifestAttrs(
8059 getIRPosition(), Attribute::getWithMemoryEffects(CB.getContext(), ME));
8060 }
8061
8062 /// See AbstractAttribute::trackStatistics()
8063 void trackStatistics() const override {
8064 if (isAssumedReadNone())
8065 STATS_DECLTRACK_CS_ATTR(readnone)
8066 else if (isAssumedReadOnly())
8067 STATS_DECLTRACK_CS_ATTR(readonly)
8068 else if (isAssumedWriteOnly())
8069 STATS_DECLTRACK_CS_ATTR(writeonly)
8070 }
8071};
8072
8073ChangeStatus AAMemoryBehaviorFunction::updateImpl(Attributor &A) {
8074
8075 // The current assumed state used to determine a change.
8076 auto AssumedState = getAssumed();
8077
8078 auto CheckRWInst = [&](Instruction &I) {
8079 // If the instruction has an own memory behavior state, use it to restrict
8080 // the local state. No further analysis is required as the other memory
8081 // state is as optimistic as it gets.
8082 if (const auto *CB = dyn_cast<CallBase>(&I)) {
8083 const auto *MemBehaviorAA = A.getAAFor<AAMemoryBehavior>(
8085 if (MemBehaviorAA) {
8086 intersectAssumedBits(MemBehaviorAA->getAssumed());
8087 return !isAtFixpoint();
8088 }
8089 }
8090
8091 // Remove access kind modifiers if necessary.
8092 if (I.mayReadFromMemory())
8093 removeAssumedBits(NO_READS);
8094 if (I.mayWriteToMemory())
8095 removeAssumedBits(NO_WRITES);
8096 return !isAtFixpoint();
8097 };
8098
8099 bool UsedAssumedInformation = false;
8100 if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this,
8101 UsedAssumedInformation))
8102 return indicatePessimisticFixpoint();
8103
8104 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
8106}
8107
8108ChangeStatus AAMemoryBehaviorFloating::updateImpl(Attributor &A) {
8109
8110 const IRPosition &IRP = getIRPosition();
8111 const IRPosition &FnPos = IRPosition::function_scope(IRP);
8112 AAMemoryBehavior::StateType &S = getState();
8113
8114 // First, check the function scope. We take the known information and we avoid
8115 // work if the assumed information implies the current assumed information for
8116 // this attribute. This is a valid for all but byval arguments.
8117 Argument *Arg = IRP.getAssociatedArgument();
8118 AAMemoryBehavior::base_t FnMemAssumedState =
8120 if (!Arg || !Arg->hasByValAttr()) {
8121 const auto *FnMemAA =
8122 A.getAAFor<AAMemoryBehavior>(*this, FnPos, DepClassTy::OPTIONAL);
8123 if (FnMemAA) {
8124 FnMemAssumedState = FnMemAA->getAssumed();
8125 S.addKnownBits(FnMemAA->getKnown());
8126 if ((S.getAssumed() & FnMemAA->getAssumed()) == S.getAssumed())
8128 }
8129 }
8130
8131 // The current assumed state used to determine a change.
8132 auto AssumedState = S.getAssumed();
8133
8134 // Make sure the value is not captured (except through "return"), if
8135 // it is, any information derived would be irrelevant anyway as we cannot
8136 // check the potential aliases introduced by the capture. However, no need
8137 // to fall back to anythign less optimistic than the function state.
8138 bool IsKnownNoCapture;
8139 const AANoCapture *ArgNoCaptureAA = nullptr;
8140 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::NoCapture>(
8141 A, this, IRP, DepClassTy::OPTIONAL, IsKnownNoCapture, false,
8142 &ArgNoCaptureAA);
8143
8144 if (!IsAssumedNoCapture &&
8145 (!ArgNoCaptureAA || !ArgNoCaptureAA->isAssumedNoCaptureMaybeReturned())) {
8146 S.intersectAssumedBits(FnMemAssumedState);
8147 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
8149 }
8150
8151 // Visit and expand uses until all are analyzed or a fixpoint is reached.
8152 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
8153 Instruction *UserI = cast<Instruction>(U.getUser());
8154 LLVM_DEBUG(dbgs() << "[AAMemoryBehavior] Use: " << *U << " in " << *UserI
8155 << " \n");
8156
8157 // Droppable users, e.g., llvm::assume does not actually perform any action.
8158 if (UserI->isDroppable())
8159 return true;
8160
8161 // Check if the users of UserI should also be visited.
8162 Follow = followUsersOfUseIn(A, U, UserI);
8163
8164 // If UserI might touch memory we analyze the use in detail.
8165 if (UserI->mayReadOrWriteMemory())
8166 analyzeUseIn(A, U, UserI);
8167
8168 return !isAtFixpoint();
8169 };
8170
8171 if (!A.checkForAllUses(UsePred, *this, getAssociatedValue()))
8172 return indicatePessimisticFixpoint();
8173
8174 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
8176}
8177
8178bool AAMemoryBehaviorFloating::followUsersOfUseIn(Attributor &A, const Use &U,
8179 const Instruction *UserI) {
8180 // The loaded value is unrelated to the pointer argument, no need to
8181 // follow the users of the load.
8182 if (isa<LoadInst>(UserI) || isa<ReturnInst>(UserI))
8183 return false;
8184
8185 // By default we follow all uses assuming UserI might leak information on U,
8186 // we have special handling for call sites operands though.
8187 const auto *CB = dyn_cast<CallBase>(UserI);
8188 if (!CB || !CB->isArgOperand(&U))
8189 return true;
8190
8191 // If the use is a call argument known not to be captured, the users of
8192 // the call do not need to be visited because they have to be unrelated to
8193 // the input. Note that this check is not trivial even though we disallow
8194 // general capturing of the underlying argument. The reason is that the
8195 // call might the argument "through return", which we allow and for which we
8196 // need to check call users.
8197 if (U.get()->getType()->isPointerTy()) {
8198 unsigned ArgNo = CB->getArgOperandNo(&U);
8199 bool IsKnownNoCapture;
8200 return !AA::hasAssumedIRAttr<Attribute::NoCapture>(
8201 A, this, IRPosition::callsite_argument(*CB, ArgNo),
8202 DepClassTy::OPTIONAL, IsKnownNoCapture);
8203 }
8204
8205 return true;
8206}
8207
8208void AAMemoryBehaviorFloating::analyzeUseIn(Attributor &A, const Use &U,
8209 const Instruction *UserI) {
8210 assert(UserI->mayReadOrWriteMemory());
8211
8212 switch (UserI->getOpcode()) {
8213 default:
8214 // TODO: Handle all atomics and other side-effect operations we know of.
8215 break;
8216 case Instruction::Load:
8217 // Loads cause the NO_READS property to disappear.
8218 removeAssumedBits(NO_READS);
8219 return;
8220
8221 case Instruction::Store:
8222 // Stores cause the NO_WRITES property to disappear if the use is the
8223 // pointer operand. Note that while capturing was taken care of somewhere
8224 // else we need to deal with stores of the value that is not looked through.
8225 if (cast<StoreInst>(UserI)->getPointerOperand() == U.get())
8226 removeAssumedBits(NO_WRITES);
8227 else
8228 indicatePessimisticFixpoint();
8229 return;
8230
8231 case Instruction::Call:
8232 case Instruction::CallBr:
8233 case Instruction::Invoke: {
8234 // For call sites we look at the argument memory behavior attribute (this
8235 // could be recursive!) in order to restrict our own state.
8236 const auto *CB = cast<CallBase>(UserI);
8237
8238 // Give up on operand bundles.
8239 if (CB->isBundleOperand(&U)) {
8240 indicatePessimisticFixpoint();
8241 return;
8242 }
8243
8244 // Calling a function does read the function pointer, maybe write it if the
8245 // function is self-modifying.
8246 if (CB->isCallee(&U)) {
8247 removeAssumedBits(NO_READS);
8248 break;
8249 }
8250
8251 // Adjust the possible access behavior based on the information on the
8252 // argument.
8253 IRPosition Pos;
8254 if (U.get()->getType()->isPointerTy())
8256 else
8258 const auto *MemBehaviorAA =
8259 A.getAAFor<AAMemoryBehavior>(*this, Pos, DepClassTy::OPTIONAL);
8260 if (!MemBehaviorAA)
8261 break;
8262 // "assumed" has at most the same bits as the MemBehaviorAA assumed
8263 // and at least "known".
8264 intersectAssumedBits(MemBehaviorAA->getAssumed());
8265 return;
8266 }
8267 };
8268
8269 // Generally, look at the "may-properties" and adjust the assumed state if we
8270 // did not trigger special handling before.
8271 if (UserI->mayReadFromMemory())
8272 removeAssumedBits(NO_READS);
8273 if (UserI->mayWriteToMemory())
8274 removeAssumedBits(NO_WRITES);
8275}
8276} // namespace
8277
8278/// -------------------- Memory Locations Attributes ---------------------------
8279/// Includes read-none, argmemonly, inaccessiblememonly,
8280/// inaccessiblememorargmemonly
8281/// ----------------------------------------------------------------------------
8282
8285 if (0 == (MLK & AAMemoryLocation::NO_LOCATIONS))
8286 return "all memory";
8288 return "no memory";
8289 std::string S = "memory:";
8290 if (0 == (MLK & AAMemoryLocation::NO_LOCAL_MEM))
8291 S += "stack,";
8292 if (0 == (MLK & AAMemoryLocation::NO_CONST_MEM))
8293 S += "constant,";
8295 S += "internal global,";
8297 S += "external global,";
8298 if (0 == (MLK & AAMemoryLocation::NO_ARGUMENT_MEM))
8299 S += "argument,";
8301 S += "inaccessible,";
8302 if (0 == (MLK & AAMemoryLocation::NO_MALLOCED_MEM))
8303 S += "malloced,";
8304 if (0 == (MLK & AAMemoryLocation::NO_UNKOWN_MEM))
8305 S += "unknown,";
8306 S.pop_back();
8307 return S;
8308}
8309
8310namespace {
8311struct AAMemoryLocationImpl : public AAMemoryLocation {
8312
8313 AAMemoryLocationImpl(const IRPosition &IRP, Attributor &A)
8315 AccessKind2Accesses.fill(nullptr);
8316 }
8317
8318 ~AAMemoryLocationImpl() {
8319 // The AccessSets are allocated via a BumpPtrAllocator, we call
8320 // the destructor manually.
8321 for (AccessSet *AS : AccessKind2Accesses)
8322 if (AS)
8323 AS->~AccessSet();
8324 }
8325
8326 /// See AbstractAttribute::initialize(...).
8327 void initialize(Attributor &A) override {
8328 intersectAssumedBits(BEST_STATE);
8329 getKnownStateFromValue(A, getIRPosition(), getState());
8330 AAMemoryLocation::initialize(A);
8331 }
8332
8333 /// Return the memory behavior information encoded in the IR for \p IRP.
8334 static void getKnownStateFromValue(Attributor &A, const IRPosition &IRP,
8335 BitIntegerState &State,
8336 bool IgnoreSubsumingPositions = false) {
8337 // For internal functions we ignore `argmemonly` and
8338 // `inaccessiblememorargmemonly` as we might break it via interprocedural
8339 // constant propagation. It is unclear if this is the best way but it is
8340 // unlikely this will cause real performance problems. If we are deriving
8341 // attributes for the anchor function we even remove the attribute in
8342 // addition to ignoring it.
8343 // TODO: A better way to handle this would be to add ~NO_GLOBAL_MEM /
8344 // MemoryEffects::Other as a possible location.
8345 bool UseArgMemOnly = true;
8346 Function *AnchorFn = IRP.getAnchorScope();
8347 if (AnchorFn && A.isRunOn(*AnchorFn))
8348 UseArgMemOnly = !AnchorFn->hasLocalLinkage();
8349
8351 A.getAttrs(IRP, {Attribute::Memory}, Attrs, IgnoreSubsumingPositions);
8352 for (const Attribute &Attr : Attrs) {
8353 // TODO: We can map MemoryEffects to Attributor locations more precisely.
8354 MemoryEffects ME = Attr.getMemoryEffects();
8355 if (ME.doesNotAccessMemory()) {
8356 State.addKnownBits(NO_LOCAL_MEM | NO_CONST_MEM);
8357 continue;
8358 }
8359 if (ME.onlyAccessesInaccessibleMem()) {
8360 State.addKnownBits(inverseLocation(NO_INACCESSIBLE_MEM, true, true));
8361 continue;
8362 }
8363 if (ME.onlyAccessesArgPointees()) {
8364 if (UseArgMemOnly)
8365 State.addKnownBits(inverseLocation(NO_ARGUMENT_MEM, true, true));
8366 else {
8367 // Remove location information, only keep read/write info.
8368 ME = MemoryEffects(ME.getModRef());
8369 A.manifestAttrs(IRP,
8371 IRP.getAnchorValue().getContext(), ME),
8372 /*ForceReplace*/ true);
8373 }
8374 continue;
8375 }
8377 if (UseArgMemOnly)
8378 State.addKnownBits(inverseLocation(
8379 NO_INACCESSIBLE_MEM | NO_ARGUMENT_MEM, true, true));
8380 else {
8381 // Remove location information, only keep read/write info.
8382 ME = MemoryEffects(ME.getModRef());
8383 A.manifestAttrs(IRP,
8385 IRP.getAnchorValue().getContext(), ME),
8386 /*ForceReplace*/ true);
8387 }
8388 continue;
8389 }
8390 }
8391 }
8392
8393 /// See AbstractAttribute::getDeducedAttributes(...).
8394 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
8395 SmallVectorImpl<Attribute> &Attrs) const override {
8396 // TODO: We can map Attributor locations to MemoryEffects more precisely.
8397 assert(Attrs.size() == 0);
8398 if (getIRPosition().getPositionKind() == IRPosition::IRP_FUNCTION) {
8399 if (isAssumedReadNone())
8400 Attrs.push_back(
8402 else if (isAssumedInaccessibleMemOnly())
8405 else if (isAssumedArgMemOnly())
8406 Attrs.push_back(
8408 else if (isAssumedInaccessibleOrArgMemOnly())
8411 }
8412 assert(Attrs.size() <= 1);
8413 }
8414
8415 /// See AbstractAttribute::manifest(...).
8416 ChangeStatus manifest(Attributor &A) override {
8417 // TODO: If AAMemoryLocation and AAMemoryBehavior are merged, we could
8418 // provide per-location modref information here.
8419 const IRPosition &IRP = getIRPosition();
8420
8421 SmallVector<Attribute, 1> DeducedAttrs;
8422 getDeducedAttributes(A, IRP.getAnchorValue().getContext(), DeducedAttrs);
8423 if (DeducedAttrs.size() != 1)
8424 return ChangeStatus::UNCHANGED;
8425 MemoryEffects ME = DeducedAttrs[0].getMemoryEffects();
8426
8427 return A.manifestAttrs(IRP, Attribute::getWithMemoryEffects(
8428 IRP.getAnchorValue().getContext(), ME));
8429 }
8430
8431 /// See AAMemoryLocation::checkForAllAccessesToMemoryKind(...).
8432 bool checkForAllAccessesToMemoryKind(
8433 function_ref<bool(const Instruction *, const Value *, AccessKind,
8434 MemoryLocationsKind)>
8435 Pred,
8436 MemoryLocationsKind RequestedMLK) const override {
8437 if (!isValidState())
8438 return false;
8439
8440 MemoryLocationsKind AssumedMLK = getAssumedNotAccessedLocation();
8441 if (AssumedMLK == NO_LOCATIONS)
8442 return true;
8443
8444 unsigned Idx = 0;
8445 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS;
8446 CurMLK *= 2, ++Idx) {
8447 if (CurMLK & RequestedMLK)
8448 continue;
8449
8450 if (const AccessSet *Accesses = AccessKind2Accesses[Idx])
8451 for (const AccessInfo &AI : *Accesses)
8452 if (!Pred(AI.I, AI.Ptr, AI.Kind, CurMLK))
8453 return false;
8454 }
8455
8456 return true;
8457 }
8458
8459 ChangeStatus indicatePessimisticFixpoint() override {
8460 // If we give up and indicate a pessimistic fixpoint this instruction will
8461 // become an access for all potential access kinds:
8462 // TODO: Add pointers for argmemonly and globals to improve the results of
8463 // checkForAllAccessesToMemoryKind.
8464 bool Changed = false;
8465 MemoryLocationsKind KnownMLK = getKnown();
8466 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
8467 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS; CurMLK *= 2)
8468 if (!(CurMLK & KnownMLK))
8469 updateStateAndAccessesMap(getState(), CurMLK, I, nullptr, Changed,
8470 getAccessKindFromInst(I));
8471 return AAMemoryLocation::indicatePessimisticFixpoint();
8472 }
8473
8474protected:
8475 /// Helper struct to tie together an instruction that has a read or write
8476 /// effect with the pointer it accesses (if any).
8477 struct AccessInfo {
8478
8479 /// The instruction that caused the access.
8480 const Instruction *I;
8481
8482 /// The base pointer that is accessed, or null if unknown.
8483 const Value *Ptr;
8484
8485 /// The kind of access (read/write/read+write).
8487
8488 bool operator==(const AccessInfo &RHS) const {
8489 return I == RHS.I && Ptr == RHS.Ptr && Kind == RHS.Kind;
8490 }
8491 bool operator()(const AccessInfo &LHS, const AccessInfo &RHS) const {
8492 if (LHS.I != RHS.I)
8493 return LHS.I < RHS.I;
8494 if (LHS.Ptr != RHS.Ptr)
8495 return LHS.Ptr < RHS.Ptr;
8496 if (LHS.Kind != RHS.Kind)
8497 return LHS.Kind < RHS.Kind;
8498 return false;
8499 }
8500 };
8501
8502 /// Mapping from *single* memory location kinds, e.g., LOCAL_MEM with the
8503 /// value of NO_LOCAL_MEM, to the accesses encountered for this memory kind.
8504 using AccessSet = SmallSet<AccessInfo, 2, AccessInfo>;
8505 std::array<AccessSet *, llvm::CTLog2<VALID_STATE>()> AccessKind2Accesses;
8506
8507 /// Categorize the pointer arguments of CB that might access memory in
8508 /// AccessedLoc and update the state and access map accordingly.
8509 void
8510 categorizeArgumentPointerLocations(Attributor &A, CallBase &CB,
8511 AAMemoryLocation::StateType &AccessedLocs,
8512 bool &Changed);
8513
8514 /// Return the kind(s) of location that may be accessed by \p V.
8516 categorizeAccessedLocations(Attributor &A, Instruction &I, bool &Changed);
8517
8518 /// Return the access kind as determined by \p I.
8519 AccessKind getAccessKindFromInst(const Instruction *I) {
8520 AccessKind AK = READ_WRITE;
8521 if (I) {
8522 AK = I->mayReadFromMemory() ? READ : NONE;
8523 AK = AccessKind(AK | (I->mayWriteToMemory() ? WRITE : NONE));
8524 }
8525 return AK;
8526 }
8527
8528 /// Update the state \p State and the AccessKind2Accesses given that \p I is
8529 /// an access of kind \p AK to a \p MLK memory location with the access
8530 /// pointer \p Ptr.
8531 void updateStateAndAccessesMap(AAMemoryLocation::StateType &State,
8532 MemoryLocationsKind MLK, const Instruction *I,
8533 const Value *Ptr, bool &Changed,
8534 AccessKind AK = READ_WRITE) {
8535
8536 assert(isPowerOf2_32(MLK) && "Expected a single location set!");
8537 auto *&Accesses = AccessKind2Accesses[llvm::Log2_32(MLK)];
8538 if (!Accesses)
8539 Accesses = new (Allocator) AccessSet();
8540 Changed |= Accesses->insert(AccessInfo{I, Ptr, AK}).second;
8541 if (MLK == NO_UNKOWN_MEM)
8542 MLK = NO_LOCATIONS;
8543 State.removeAssumedBits(MLK);
8544 }
8545
8546 /// Determine the underlying locations kinds for \p Ptr, e.g., globals or
8547 /// arguments, and update the state and access map accordingly.
8548 void categorizePtrValue(Attributor &A, const Instruction &I, const Value &Ptr,
8549 AAMemoryLocation::StateType &State, bool &Changed,
8550 unsigned AccessAS = 0);
8551
8552 /// Used to allocate access sets.
8554};
8555
8556void AAMemoryLocationImpl::categorizePtrValue(
8557 Attributor &A, const Instruction &I, const Value &Ptr,
8558 AAMemoryLocation::StateType &State, bool &Changed, unsigned AccessAS) {
8559 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize pointer locations for "
8560 << Ptr << " ["
8561 << getMemoryLocationsAsStr(State.getAssumed()) << "]\n");
8562
8563 auto Pred = [&](Value &Obj) {
8564 unsigned ObjectAS = Obj.getType()->getPointerAddressSpace();
8565 // TODO: recognize the TBAA used for constant accesses.
8566 MemoryLocationsKind MLK = NO_LOCATIONS;
8567
8568 // Filter accesses to constant (GPU) memory if we have an AS at the access
8569 // site or the object is known to actually have the associated AS.
8570 if ((AccessAS == (unsigned)AA::GPUAddressSpace::Constant ||
8571 (ObjectAS == (unsigned)AA::GPUAddressSpace::Constant &&
8572 isIdentifiedObject(&Obj))) &&
8573 AA::isGPU(*I.getModule()))
8574 return true;
8575
8576 if (isa<UndefValue>(&Obj))
8577 return true;
8578 if (isa<Argument>(&Obj)) {
8579 // TODO: For now we do not treat byval arguments as local copies performed
8580 // on the call edge, though, we should. To make that happen we need to
8581 // teach various passes, e.g., DSE, about the copy effect of a byval. That
8582 // would also allow us to mark functions only accessing byval arguments as
8583 // readnone again, arguably their accesses have no effect outside of the
8584 // function, like accesses to allocas.
8585 MLK = NO_ARGUMENT_MEM;
8586 } else if (auto *GV = dyn_cast<GlobalValue>(&Obj)) {
8587 // Reading constant memory is not treated as a read "effect" by the
8588 // function attr pass so we won't neither. Constants defined by TBAA are
8589 // similar. (We know we do not write it because it is constant.)
8590 if (auto *GVar = dyn_cast<GlobalVariable>(GV))
8591 if (GVar->isConstant())
8592 return true;
8593
8594 if (GV->hasLocalLinkage())
8595 MLK = NO_GLOBAL_INTERNAL_MEM;
8596 else
8597 MLK = NO_GLOBAL_EXTERNAL_MEM;
8598 } else if (isa<ConstantPointerNull>(&Obj) &&
8599 (!NullPointerIsDefined(getAssociatedFunction(), AccessAS) ||
8600 !NullPointerIsDefined(getAssociatedFunction(), ObjectAS))) {
8601 return true;
8602 } else if (isa<AllocaInst>(&Obj)) {
8603 MLK = NO_LOCAL_MEM;
8604 } else if (const auto *CB = dyn_cast<CallBase>(&Obj)) {
8605 bool IsKnownNoAlias;
8606 if (AA::hasAssumedIRAttr<Attribute::NoAlias>(
8608 IsKnownNoAlias))
8609 MLK = NO_MALLOCED_MEM;
8610 else
8611 MLK = NO_UNKOWN_MEM;
8612 } else {
8613 MLK = NO_UNKOWN_MEM;
8614 }
8615
8616 assert(MLK != NO_LOCATIONS && "No location specified!");
8617 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Ptr value can be categorized: "
8618 << Obj << " -> " << getMemoryLocationsAsStr(MLK) << "\n");
8619 updateStateAndAccessesMap(State, MLK, &I, &Obj, Changed,
8620 getAccessKindFromInst(&I));
8621
8622 return true;
8623 };
8624
8625 const auto *AA = A.getAAFor<AAUnderlyingObjects>(
8627 if (!AA || !AA->forallUnderlyingObjects(Pred, AA::Intraprocedural)) {
8628 LLVM_DEBUG(
8629 dbgs() << "[AAMemoryLocation] Pointer locations not categorized\n");
8630 updateStateAndAccessesMap(State, NO_UNKOWN_MEM, &I, nullptr, Changed,
8631 getAccessKindFromInst(&I));
8632 return;
8633 }
8634
8635 LLVM_DEBUG(
8636 dbgs() << "[AAMemoryLocation] Accessed locations with pointer locations: "
8637 << getMemoryLocationsAsStr(State.getAssumed()) << "\n");
8638}
8639
8640void AAMemoryLocationImpl::categorizeArgumentPointerLocations(
8641 Attributor &A, CallBase &CB, AAMemoryLocation::StateType &AccessedLocs,
8642 bool &Changed) {
8643 for (unsigned ArgNo = 0, E = CB.arg_size(); ArgNo < E; ++ArgNo) {
8644
8645 // Skip non-pointer arguments.
8646 const Value *ArgOp = CB.getArgOperand(ArgNo);
8647 if (!ArgOp->getType()->isPtrOrPtrVectorTy())
8648 continue;
8649
8650 // Skip readnone arguments.
8651 const IRPosition &ArgOpIRP = IRPosition::callsite_argument(CB, ArgNo);
8652 const auto *ArgOpMemLocationAA =
8653 A.getAAFor<AAMemoryBehavior>(*this, ArgOpIRP, DepClassTy::OPTIONAL);
8654
8655 if (ArgOpMemLocationAA && ArgOpMemLocationAA->isAssumedReadNone())
8656 continue;
8657
8658 // Categorize potentially accessed pointer arguments as if there was an
8659 // access instruction with them as pointer.
8660 categorizePtrValue(A, CB, *ArgOp, AccessedLocs, Changed);
8661 }
8662}
8663
8665AAMemoryLocationImpl::categorizeAccessedLocations(Attributor &A, Instruction &I,
8666 bool &Changed) {
8667 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize accessed locations for "
8668 << I << "\n");
8669
8670 AAMemoryLocation::StateType AccessedLocs;
8671 AccessedLocs.intersectAssumedBits(NO_LOCATIONS);
8672
8673 if (auto *CB = dyn_cast<CallBase>(&I)) {
8674
8675 // First check if we assume any memory is access is visible.
8676 const auto *CBMemLocationAA = A.getAAFor<AAMemoryLocation>(
8678 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize call site: " << I
8679 << " [" << CBMemLocationAA << "]\n");
8680 if (!CBMemLocationAA) {
8681 updateStateAndAccessesMap(AccessedLocs, NO_UNKOWN_MEM, &I, nullptr,
8682 Changed, getAccessKindFromInst(&I));
8683 return NO_UNKOWN_MEM;
8684 }
8685
8686 if (CBMemLocationAA->isAssumedReadNone())
8687 return NO_LOCATIONS;
8688
8689 if (CBMemLocationAA->isAssumedInaccessibleMemOnly()) {
8690 updateStateAndAccessesMap(AccessedLocs, NO_INACCESSIBLE_MEM, &I, nullptr,
8691 Changed, getAccessKindFromInst(&I));
8692 return AccessedLocs.getAssumed();
8693 }
8694
8695 uint32_t CBAssumedNotAccessedLocs =
8696 CBMemLocationAA->getAssumedNotAccessedLocation();
8697
8698 // Set the argmemonly and global bit as we handle them separately below.
8699 uint32_t CBAssumedNotAccessedLocsNoArgMem =
8700 CBAssumedNotAccessedLocs | NO_ARGUMENT_MEM | NO_GLOBAL_MEM;
8701
8702 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS; CurMLK *= 2) {
8703 if (CBAssumedNotAccessedLocsNoArgMem & CurMLK)
8704 continue;
8705 updateStateAndAccessesMap(AccessedLocs, CurMLK, &I, nullptr, Changed,
8706 getAccessKindFromInst(&I));
8707 }
8708
8709 // Now handle global memory if it might be accessed. This is slightly tricky
8710 // as NO_GLOBAL_MEM has multiple bits set.
8711 bool HasGlobalAccesses = ((~CBAssumedNotAccessedLocs) & NO_GLOBAL_MEM);
8712 if (HasGlobalAccesses) {
8713 auto AccessPred = [&](const Instruction *, const Value *Ptr,
8714 AccessKind Kind, MemoryLocationsKind MLK) {
8715 updateStateAndAccessesMap(AccessedLocs, MLK, &I, Ptr, Changed,
8716 getAccessKindFromInst(&I));
8717 return true;
8718 };
8719 if (!CBMemLocationAA->checkForAllAccessesToMemoryKind(
8720 AccessPred, inverseLocation(NO_GLOBAL_MEM, false, false)))
8721 return AccessedLocs.getWorstState();
8722 }
8723
8724 LLVM_DEBUG(
8725 dbgs() << "[AAMemoryLocation] Accessed state before argument handling: "
8726 << getMemoryLocationsAsStr(AccessedLocs.getAssumed()) << "\n");
8727
8728 // Now handle argument memory if it might be accessed.
8729 bool HasArgAccesses = ((~CBAssumedNotAccessedLocs) & NO_ARGUMENT_MEM);
8730 if (HasArgAccesses)
8731 categorizeArgumentPointerLocations(A, *CB, AccessedLocs, Changed);
8732
8733 LLVM_DEBUG(
8734 dbgs() << "[AAMemoryLocation] Accessed state after argument handling: "
8735 << getMemoryLocationsAsStr(AccessedLocs.getAssumed()) << "\n");
8736
8737 return AccessedLocs.getAssumed();
8738 }
8739
8740 if (const Value *Ptr = getPointerOperand(&I, /* AllowVolatile */ true)) {
8741 LLVM_DEBUG(
8742 dbgs() << "[AAMemoryLocation] Categorize memory access with pointer: "
8743 << I << " [" << *Ptr << "]\n");
8744 categorizePtrValue(A, I, *Ptr, AccessedLocs, Changed,
8745 Ptr->getType()->getPointerAddressSpace());
8746 return AccessedLocs.getAssumed();
8747 }
8748
8749 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Failed to categorize instruction: "
8750 << I << "\n");
8751 updateStateAndAccessesMap(AccessedLocs, NO_UNKOWN_MEM, &I, nullptr, Changed,
8752 getAccessKindFromInst(&I));
8753 return AccessedLocs.getAssumed();
8754}
8755
8756/// An AA to represent the memory behavior function attributes.
8757struct AAMemoryLocationFunction final : public AAMemoryLocationImpl {
8758 AAMemoryLocationFunction(const IRPosition &IRP, Attributor &A)
8759 : AAMemoryLocationImpl(IRP, A) {}
8760
8761 /// See AbstractAttribute::updateImpl(Attributor &A).
8762 ChangeStatus updateImpl(Attributor &A) override {
8763
8764 const auto *MemBehaviorAA =
8765 A.getAAFor<AAMemoryBehavior>(*this, getIRPosition(), DepClassTy::NONE);
8766 if (MemBehaviorAA && MemBehaviorAA->isAssumedReadNone()) {
8767 if (MemBehaviorAA->isKnownReadNone())
8768 return indicateOptimisticFixpoint();
8770 "AAMemoryLocation was not read-none but AAMemoryBehavior was!");
8771 A.recordDependence(*MemBehaviorAA, *this, DepClassTy::OPTIONAL);
8772 return ChangeStatus::UNCHANGED;
8773 }
8774
8775 // The current assumed state used to determine a change.
8776 auto AssumedState = getAssumed();
8777 bool Changed = false;
8778
8779 auto CheckRWInst = [&](Instruction &I) {
8780 MemoryLocationsKind MLK = categorizeAccessedLocations(A, I, Changed);
8781 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Accessed locations for " << I
8782 << ": " << getMemoryLocationsAsStr(MLK) << "\n");
8783 removeAssumedBits(inverseLocation(MLK, false, false));
8784 // Stop once only the valid bit set in the *not assumed location*, thus
8785 // once we don't actually exclude any memory locations in the state.
8786 return getAssumedNotAccessedLocation() != VALID_STATE;
8787 };
8788
8789 bool UsedAssumedInformation = false;
8790 if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this,
8791 UsedAssumedInformation))
8792 return indicatePessimisticFixpoint();
8793
8794 Changed |= AssumedState != getAssumed();
8795 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
8796 }
8797
8798 /// See AbstractAttribute::trackStatistics()
8799 void trackStatistics() const override {
8800 if (isAssumedReadNone())
8801 STATS_DECLTRACK_FN_ATTR(readnone)
8802 else if (isAssumedArgMemOnly())
8803 STATS_DECLTRACK_FN_ATTR(argmemonly)
8804 else if (isAssumedInaccessibleMemOnly())
8805 STATS_DECLTRACK_FN_ATTR(inaccessiblememonly)
8806 else if (isAssumedInaccessibleOrArgMemOnly())
8807 STATS_DECLTRACK_FN_ATTR(inaccessiblememorargmemonly)
8808 }
8809};
8810
8811/// AAMemoryLocation attribute for call sites.
8812struct AAMemoryLocationCallSite final : AAMemoryLocationImpl {
8813 AAMemoryLocationCallSite(const IRPosition &IRP, Attributor &A)
8814 : AAMemoryLocationImpl(IRP, A) {}
8815
8816 /// See AbstractAttribute::updateImpl(...).
8817 ChangeStatus updateImpl(Attributor &A) override {
8818 // TODO: Once we have call site specific value information we can provide
8819 // call site specific liveness liveness information and then it makes
8820 // sense to specialize attributes for call sites arguments instead of
8821 // redirecting requests to the callee argument.
8822 Function *F = getAssociatedFunction();
8823 const IRPosition &FnPos = IRPosition::function(*F);
8824 auto *FnAA =
8825 A.getAAFor<AAMemoryLocation>(*this, FnPos, DepClassTy::REQUIRED);
8826 if (!FnAA)
8827 return indicatePessimisticFixpoint();
8828 bool Changed = false;
8829 auto AccessPred = [&](const Instruction *I, const Value *Ptr,
8830 AccessKind Kind, MemoryLocationsKind MLK) {
8831 updateStateAndAccessesMap(getState(), MLK, I, Ptr, Changed,
8832 getAccessKindFromInst(I));
8833 return true;
8834 };
8835 if (!FnAA->checkForAllAccessesToMemoryKind(AccessPred, ALL_LOCATIONS))
8836 return indicatePessimisticFixpoint();
8837 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
8838 }
8839
8840 /// See AbstractAttribute::trackStatistics()
8841 void trackStatistics() const override {
8842 if (isAssumedReadNone())
8843 STATS_DECLTRACK_CS_ATTR(readnone)
8844 }
8845};
8846} // namespace
8847
8848/// ------------------ denormal-fp-math Attribute -------------------------
8849
8850namespace {
8851struct AADenormalFPMathImpl : public AADenormalFPMath {
8852 AADenormalFPMathImpl(const IRPosition &IRP, Attributor &A)
8853 : AADenormalFPMath(IRP, A) {}
8854
8855 const std::string getAsStr(Attributor *A) const override {
8856 std::string Str("AADenormalFPMath[");
8858
8859 DenormalState Known = getKnown();
8860 if (Known.Mode.isValid())
8861 OS << "denormal-fp-math=" << Known.Mode;
8862 else
8863 OS << "invalid";
8864
8865 if (Known.ModeF32.isValid())
8866 OS << " denormal-fp-math-f32=" << Known.ModeF32;
8867 OS << ']';
8868 return Str;
8869 }
8870};
8871
8872struct AADenormalFPMathFunction final : AADenormalFPMathImpl {
8873 AADenormalFPMathFunction(const IRPosition &IRP, Attributor &A)
8874 : AADenormalFPMathImpl(IRP, A) {}
8875
8876 void initialize(Attributor &A) override {
8877 const Function *F = getAnchorScope();
8878 DenormalMode Mode = F->getDenormalModeRaw();
8879 DenormalMode ModeF32 = F->getDenormalModeF32Raw();
8880
8881 // TODO: Handling this here prevents handling the case where a callee has a
8882 // fixed denormal-fp-math with dynamic denormal-fp-math-f32, but called from
8883 // a function with a fully fixed mode.
8884 if (ModeF32 == DenormalMode::getInvalid())
8885 ModeF32 = Mode;
8886 Known = DenormalState{Mode, ModeF32};
8887 if (isModeFixed())
8888 indicateFixpoint();
8889 }
8890
8891 ChangeStatus updateImpl(Attributor &A) override {
8892 ChangeStatus Change = ChangeStatus::UNCHANGED;
8893
8894 auto CheckCallSite = [=, &Change, &A](AbstractCallSite CS) {
8895 Function *Caller = CS.getInstruction()->getFunction();
8896 LLVM_DEBUG(dbgs() << "[AADenormalFPMath] Call " << Caller->getName()
8897 << "->" << getAssociatedFunction()->getName() << '\n');
8898
8899 const auto *CallerInfo = A.getAAFor<AADenormalFPMath>(
8900 *this, IRPosition::function(*Caller), DepClassTy::REQUIRED);
8901 if (!CallerInfo)
8902 return false;
8903
8904 Change = Change | clampStateAndIndicateChange(this->getState(),
8905 CallerInfo->getState());
8906 return true;
8907 };
8908
8909 bool AllCallSitesKnown = true;
8910 if (!A.checkForAllCallSites(CheckCallSite, *this, true, AllCallSitesKnown))
8911 return indicatePessimisticFixpoint();
8912
8913 if (Change == ChangeStatus::CHANGED && isModeFixed())
8914 indicateFixpoint();
8915 return Change;
8916 }
8917
8918 ChangeStatus manifest(Attributor &A) override {
8919 LLVMContext &Ctx = getAssociatedFunction()->getContext();
8920
8921 SmallVector<Attribute, 2> AttrToAdd;
8922 SmallVector<StringRef, 2> AttrToRemove;
8923 if (Known.Mode == DenormalMode::getDefault()) {
8924 AttrToRemove.push_back("denormal-fp-math");
8925 } else {
8926 AttrToAdd.push_back(
8927 Attribute::get(Ctx, "denormal-fp-math", Known.Mode.str()));
8928 }
8929
8930 if (Known.ModeF32 != Known.Mode) {
8931 AttrToAdd.push_back(
8932 Attribute::get(Ctx, "denormal-fp-math-f32", Known.ModeF32.str()));
8933 } else {
8934 AttrToRemove.push_back("denormal-fp-math-f32");
8935 }
8936
8937 auto &IRP = getIRPosition();
8938
8939 // TODO: There should be a combined add and remove API.
8940 return A.removeAttrs(IRP, AttrToRemove) |
8941 A.manifestAttrs(IRP, AttrToAdd, /*ForceReplace=*/true);
8942 }
8943
8944 void trackStatistics() const override {
8945 STATS_DECLTRACK_FN_ATTR(denormal_fp_math)
8946 }
8947};
8948} // namespace
8949
8950/// ------------------ Value Constant Range Attribute -------------------------
8951
8952namespace {
8953struct AAValueConstantRangeImpl : AAValueConstantRange {
8954 using StateType = IntegerRangeState;
8955 AAValueConstantRangeImpl(const IRPosition &IRP, Attributor &A)
8956 : AAValueConstantRange(IRP, A) {}
8957
8958 /// See AbstractAttribute::initialize(..).
8959 void initialize(Attributor &A) override {
8960 if (A.hasSimplificationCallback(getIRPosition())) {
8961 indicatePessimisticFixpoint();
8962 return;
8963 }
8964
8965 // Intersect a range given by SCEV.
8966 intersectKnown(getConstantRangeFromSCEV(A, getCtxI()));
8967
8968 // Intersect a range given by LVI.
8969 intersectKnown(getConstantRangeFromLVI(A, getCtxI()));
8970 }
8971
8972 /// See AbstractAttribute::getAsStr().
8973 const std::string getAsStr(Attributor *A) const override {
8974 std::string Str;
8976 OS << "range(" << getBitWidth() << ")<";
8977 getKnown().print(OS);
8978 OS << " / ";
8979 getAssumed().print(OS);
8980 OS << ">";
8981 return Str;
8982 }
8983
8984 /// Helper function to get a SCEV expr for the associated value at program
8985 /// point \p I.
8986 const SCEV *getSCEV(Attributor &A, const Instruction *I = nullptr) const {
8987 if (!getAnchorScope())
8988 return nullptr;
8989
8990 ScalarEvolution *SE =
8991 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(
8992 *getAnchorScope());
8993
8994 LoopInfo *LI = A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(
8995 *getAnchorScope());
8996
8997 if (!SE || !LI)
8998 return nullptr;
8999
9000 const SCEV *S = SE->getSCEV(&getAssociatedValue());
9001 if (!I)
9002 return S;
9003
9004 return SE->getSCEVAtScope(S, LI->getLoopFor(I->getParent()));
9005 }
9006
9007 /// Helper function to get a range from SCEV for the associated value at
9008 /// program point \p I.
9009 ConstantRange getConstantRangeFromSCEV(Attributor &A,
9010 const Instruction *I = nullptr) const {
9011 if (!getAnchorScope())
9012 return getWorstState(getBitWidth());
9013
9014 ScalarEvolution *SE =
9015 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(
9016 *getAnchorScope());
9017
9018 const SCEV *S = getSCEV(A, I);
9019 if (!SE || !S)
9020 return getWorstState(getBitWidth());
9021
9022 return SE->getUnsignedRange(S);
9023 }
9024
9025 /// Helper function to get a range from LVI for the associated value at
9026 /// program point \p I.
9028 getConstantRangeFromLVI(Attributor &A,
9029 const Instruction *CtxI = nullptr) const {
9030 if (!getAnchorScope())
9031 return getWorstState(getBitWidth());
9032
9033 LazyValueInfo *LVI =
9034 A.getInfoCache().getAnalysisResultForFunction<LazyValueAnalysis>(
9035 *getAnchorScope());
9036
9037 if (!LVI || !CtxI)
9038 return getWorstState(getBitWidth());
9039 return LVI->getConstantRange(&getAssociatedValue(),
9040 const_cast<Instruction *>(CtxI),
9041 /*UndefAllowed*/ false);
9042 }
9043
9044 /// Return true if \p CtxI is valid for querying outside analyses.
9045 /// This basically makes sure we do not ask intra-procedural analysis
9046 /// about a context in the wrong function or a context that violates
9047 /// dominance assumptions they might have. The \p AllowAACtxI flag indicates
9048 /// if the original context of this AA is OK or should be considered invalid.
9049 bool isValidCtxInstructionForOutsideAnalysis(Attributor &A,
9050 const Instruction *CtxI,
9051 bool AllowAACtxI) const {
9052 if (!CtxI || (!AllowAACtxI && CtxI == getCtxI()))
9053 return false;
9054
9055 // Our context might be in a different function, neither intra-procedural
9056 // analysis (ScalarEvolution nor LazyValueInfo) can handle that.
9057 if (!AA::isValidInScope(getAssociatedValue(), CtxI->getFunction()))
9058 return false;
9059
9060 // If the context is not dominated by the value there are paths to the
9061 // context that do not define the value. This cannot be handled by
9062 // LazyValueInfo so we need to bail.
9063 if (auto *I = dyn_cast<Instruction>(&getAssociatedValue())) {
9064 InformationCache &InfoCache = A.getInfoCache();
9065 const DominatorTree *DT =
9067 *I->getFunction());
9068 return DT && DT->dominates(I, CtxI);
9069 }
9070
9071 return true;
9072 }
9073
9074 /// See AAValueConstantRange::getKnownConstantRange(..).
9076 getKnownConstantRange(Attributor &A,
9077 const Instruction *CtxI = nullptr) const override {
9078 if (!isValidCtxInstructionForOutsideAnalysis(A, CtxI,
9079 /* AllowAACtxI */ false))
9080 return getKnown();
9081
9082 ConstantRange LVIR = getConstantRangeFromLVI(A, CtxI);
9083 ConstantRange SCEVR = getConstantRangeFromSCEV(A, CtxI);
9084 return getKnown().intersectWith(SCEVR).intersectWith(LVIR);
9085 }
9086
9087 /// See AAValueConstantRange::getAssumedConstantRange(..).
9089 getAssumedConstantRange(Attributor &A,
9090 const Instruction *CtxI = nullptr) const override {
9091 // TODO: Make SCEV use Attributor assumption.
9092 // We may be able to bound a variable range via assumptions in
9093 // Attributor. ex.) If x is assumed to be in [1, 3] and y is known to
9094 // evolve to x^2 + x, then we can say that y is in [2, 12].
9095 if (!isValidCtxInstructionForOutsideAnalysis(A, CtxI,
9096 /* AllowAACtxI */ false))
9097 return getAssumed();
9098
9099 ConstantRange LVIR = getConstantRangeFromLVI(A, CtxI);
9100 ConstantRange SCEVR = getConstantRangeFromSCEV(A, CtxI);
9101 return getAssumed().intersectWith(SCEVR).intersectWith(LVIR);
9102 }
9103
9104 /// Helper function to create MDNode for range metadata.
9105 static MDNode *
9106 getMDNodeForConstantRange(Type *Ty, LLVMContext &Ctx,
9107 const ConstantRange &AssumedConstantRange) {
9108 Metadata *LowAndHigh[] = {ConstantAsMetadata::get(ConstantInt::get(
9109 Ty, AssumedConstantRange.getLower())),
9110 ConstantAsMetadata::get(ConstantInt::get(
9111 Ty, AssumedConstantRange.getUpper()))};
9112 return MDNode::get(Ctx, LowAndHigh);
9113 }
9114
9115 /// Return true if \p Assumed is included in \p KnownRanges.
9116 static bool isBetterRange(const ConstantRange &Assumed, MDNode *KnownRanges) {
9117
9118 if (Assumed.isFullSet())
9119 return false;
9120
9121 if (!KnownRanges)
9122 return true;
9123
9124 // If multiple ranges are annotated in IR, we give up to annotate assumed
9125 // range for now.
9126
9127 // TODO: If there exists a known range which containts assumed range, we
9128 // can say assumed range is better.
9129 if (KnownRanges->getNumOperands() > 2)
9130 return false;
9131
9133 mdconst::extract<ConstantInt>(KnownRanges->getOperand(0));
9135 mdconst::extract<ConstantInt>(KnownRanges->getOperand(1));
9136
9137 ConstantRange Known(Lower->getValue(), Upper->getValue());
9138 return Known.contains(Assumed) && Known != Assumed;
9139 }
9140
9141 /// Helper function to set range metadata.
9142 static bool
9143 setRangeMetadataIfisBetterRange(Instruction *I,
9144 const ConstantRange &AssumedConstantRange) {
9145 auto *OldRangeMD = I->getMetadata(LLVMContext::MD_range);
9146 if (isBetterRange(AssumedConstantRange, OldRangeMD)) {
9147 if (!AssumedConstantRange.isEmptySet()) {
9148 I->setMetadata(LLVMContext::MD_range,
9149 getMDNodeForConstantRange(I->getType(), I->getContext(),
9150 AssumedConstantRange));
9151 return true;
9152 }
9153 }
9154 return false;
9155 }
9156
9157 /// See AbstractAttribute::manifest()
9158 ChangeStatus manifest(Attributor &A) override {
9159 ChangeStatus Changed = ChangeStatus::UNCHANGED;
9160 ConstantRange AssumedConstantRange = getAssumedConstantRange(A);
9161 assert(!AssumedConstantRange.isFullSet() && "Invalid state");
9162
9163 auto &V = getAssociatedValue();
9164 if (!AssumedConstantRange.isEmptySet() &&
9165 !AssumedConstantRange.isSingleElement()) {
9166 if (Instruction *I = dyn_cast<Instruction>(&V)) {
9167 assert(I == getCtxI() && "Should not annotate an instruction which is "
9168 "not the context instruction");
9169 if (isa<CallInst>(I) || isa<LoadInst>(I))
9170 if (setRangeMetadataIfisBetterRange(I, AssumedConstantRange))
9171 Changed = ChangeStatus::CHANGED;
9172 }
9173 }
9174
9175 return Changed;
9176 }
9177};
9178
9179struct AAValueConstantRangeArgument final
9180 : AAArgumentFromCallSiteArguments<
9181 AAValueConstantRange, AAValueConstantRangeImpl, IntegerRangeState,
9182 true /* BridgeCallBaseContext */> {
9183 using Base = AAArgumentFromCallSiteArguments<
9184 AAValueConstantRange, AAValueConstantRangeImpl, IntegerRangeState,
9185 true /* BridgeCallBaseContext */>;
9186 AAValueConstantRangeArgument(const IRPosition &IRP, Attributor &A)
9187 : Base(IRP, A) {}
9188
9189 /// See AbstractAttribute::trackStatistics()
9190 void trackStatistics() const override {
9191 STATS_DECLTRACK_ARG_ATTR(value_range)
9192 }
9193};
9194
9195struct AAValueConstantRangeReturned
9196 : AAReturnedFromReturnedValues<AAValueConstantRange,
9197 AAValueConstantRangeImpl,
9198 AAValueConstantRangeImpl::StateType,
9199 /* PropogateCallBaseContext */ true> {
9200 using Base =
9201 AAReturnedFromReturnedValues<AAValueConstantRange,
9202 AAValueConstantRangeImpl,
9204 /* PropogateCallBaseContext */ true>;
9205 AAValueConstantRangeReturned(const IRPosition &IRP, Attributor &A)
9206 : Base(IRP, A) {}
9207
9208 /// See AbstractAttribute::initialize(...).
9209 void initialize(Attributor &A) override {
9210 if (!A.isFunctionIPOAmendable(*getAssociatedFunction()))
9211 indicatePessimisticFixpoint();
9212 }
9213
9214 /// See AbstractAttribute::trackStatistics()
9215 void trackStatistics() const override {
9216 STATS_DECLTRACK_FNRET_ATTR(value_range)
9217 }
9218};
9219
9220struct AAValueConstantRangeFloating : AAValueConstantRangeImpl {
9221 AAValueConstantRangeFloating(const IRPosition &IRP, Attributor &A)
9222 : AAValueConstantRangeImpl(IRP, A) {}
9223
9224 /// See AbstractAttribute::initialize(...).
9225 void initialize(Attributor &A) override {
9226 AAValueConstantRangeImpl::initialize(A);
9227 if (isAtFixpoint())
9228 return;
9229
9230 Value &V = getAssociatedValue();
9231
9232 if (auto *C = dyn_cast<ConstantInt>(&V)) {
9233 unionAssumed(ConstantRange(C->getValue()));
9234 indicateOptimisticFixpoint();
9235 return;
9236 }
9237
9238 if (isa<UndefValue>(&V)) {
9239 // Collapse the undef state to 0.
9240 unionAssumed(ConstantRange(APInt(getBitWidth(), 0)));
9241 indicateOptimisticFixpoint();
9242 return;
9243 }
9244
9245 if (isa<CallBase>(&V))
9246 return;
9247
9248 if (isa<BinaryOperator>(&V) || isa<CmpInst>(&V) || isa<CastInst>(&V))
9249 return;
9250
9251 // If it is a load instruction with range metadata, use it.
9252 if (LoadInst *LI = dyn_cast<LoadInst>(&V))
9253 if (auto *RangeMD = LI->getMetadata(LLVMContext::MD_range)) {
9254 intersectKnown(getConstantRangeFromMetadata(*RangeMD));
9255 return;
9256 }
9257
9258 // We can work with PHI and select instruction as we traverse their operands
9259 // during update.
9260 if (isa<SelectInst>(V) || isa<PHINode>(V))
9261 return;
9262
9263 // Otherwise we give up.
9264 indicatePessimisticFixpoint();
9265
9266 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] We give up: "
9267 << getAssociatedValue() << "\n");
9268 }
9269
9270 bool calculateBinaryOperator(
9272 const Instruction *CtxI,
9274 Value *LHS = BinOp->getOperand(0);
9275 Value *RHS = BinOp->getOperand(1);
9276
9277 // Simplify the operands first.
9278 bool UsedAssumedInformation = false;
9279 const auto &SimplifiedLHS = A.getAssumedSimplified(
9280 IRPosition::value(*LHS, getCallBaseContext()), *this,
9281 UsedAssumedInformation, AA::Interprocedural);
9282 if (!SimplifiedLHS.has_value())
9283 return true;
9284 if (!*SimplifiedLHS)
9285 return false;
9286 LHS = *SimplifiedLHS;
9287
9288 const auto &SimplifiedRHS = A.getAssumedSimplified(
9289 IRPosition::value(*RHS, getCallBaseContext()), *this,
9290 UsedAssumedInformation, AA::Interprocedural);
9291 if (!SimplifiedRHS.has_value())
9292 return true;
9293 if (!*SimplifiedRHS)
9294 return false;
9295 RHS = *SimplifiedRHS;
9296
9297 // TODO: Allow non integers as well.
9298 if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy())
9299 return false;
9300
9301 auto *LHSAA = A.getAAFor<AAValueConstantRange>(
9302 *this, IRPosition::value(*LHS, getCallBaseContext()),
9303 DepClassTy::REQUIRED);
9304 if (!LHSAA)
9305 return false;
9306 QuerriedAAs.push_back(LHSAA);
9307 auto LHSAARange = LHSAA->getAssumedConstantRange(A, CtxI);
9308
9309 auto *RHSAA = A.getAAFor<AAValueConstantRange>(
9310 *this, IRPosition::value(*RHS, getCallBaseContext()),
9311 DepClassTy::REQUIRED);
9312 if (!RHSAA)
9313 return false;
9314 QuerriedAAs.push_back(RHSAA);
9315 auto RHSAARange = RHSAA->getAssumedConstantRange(A, CtxI);
9316
9317 auto AssumedRange = LHSAARange.binaryOp(BinOp->getOpcode(), RHSAARange);
9318
9319 T.unionAssumed(AssumedRange);
9320
9321 // TODO: Track a known state too.
9322
9323 return T.isValidState();
9324 }
9325
9326 bool calculateCastInst(
9328 const Instruction *CtxI,
9330 assert(CastI->getNumOperands() == 1 && "Expected cast to be unary!");
9331 // TODO: Allow non integers as well.
9332 Value *OpV = CastI->getOperand(0);
9333
9334 // Simplify the operand first.
9335 bool UsedAssumedInformation = false;
9336 const auto &SimplifiedOpV = A.getAssumedSimplified(
9337 IRPosition::value(*OpV, getCallBaseContext()), *this,
9338 UsedAssumedInformation, AA::Interprocedural);
9339 if (!SimplifiedOpV.has_value())
9340 return true;
9341 if (!*SimplifiedOpV)
9342 return false;
9343 OpV = *SimplifiedOpV;
9344
9345 if (!OpV->getType()->isIntegerTy())
9346 return false;
9347
9348 auto *OpAA = A.getAAFor<AAValueConstantRange>(
9349 *this, IRPosition::value(*OpV, getCallBaseContext()),
9350 DepClassTy::REQUIRED);
9351 if (!OpAA)
9352 return false;
9353 QuerriedAAs.push_back(OpAA);
9354 T.unionAssumed(OpAA->getAssumed().castOp(CastI->getOpcode(),
9355 getState().getBitWidth()));
9356 return T.isValidState();
9357 }
9358
9359 bool
9360 calculateCmpInst(Attributor &A, CmpInst *CmpI, IntegerRangeState &T,
9361 const Instruction *CtxI,
9363 Value *LHS = CmpI->getOperand(0);
9364 Value *RHS = CmpI->getOperand(1);
9365
9366 // Simplify the operands first.
9367 bool UsedAssumedInformation = false;
9368 const auto &SimplifiedLHS = A.getAssumedSimplified(
9369 IRPosition::value(*LHS, getCallBaseContext()), *this,
9370 UsedAssumedInformation, AA::Interprocedural);
9371 if (!SimplifiedLHS.has_value())
9372 return true;
9373 if (!*SimplifiedLHS)
9374 return false;
9375 LHS = *SimplifiedLHS;
9376
9377 const auto &SimplifiedRHS = A.getAssumedSimplified(
9378 IRPosition::value(*RHS, getCallBaseContext()), *this,
9379 UsedAssumedInformation, AA::Interprocedural);
9380 if (!SimplifiedRHS.has_value())
9381 return true;
9382 if (!*SimplifiedRHS)
9383 return false;
9384 RHS = *SimplifiedRHS;
9385
9386 // TODO: Allow non integers as well.
9387 if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy())
9388 return false;
9389
9390 auto *LHSAA = A.getAAFor<AAValueConstantRange>(
9391 *this, IRPosition::value(*LHS, getCallBaseContext()),
9392 DepClassTy::REQUIRED);
9393 if (!LHSAA)
9394 return false;
9395 QuerriedAAs.push_back(LHSAA);
9396 auto *RHSAA = A.getAAFor<AAValueConstantRange>(
9397 *this, IRPosition::value(*RHS, getCallBaseContext()),
9398 DepClassTy::REQUIRED);
9399 if (!RHSAA)
9400 return false;
9401 QuerriedAAs.push_back(RHSAA);
9402 auto LHSAARange = LHSAA->getAssumedConstantRange(A, CtxI);
9403 auto RHSAARange = RHSAA->getAssumedConstantRange(A, CtxI);
9404
9405 // If one of them is empty set, we can't decide.
9406 if (LHSAARange.isEmptySet() || RHSAARange.isEmptySet())
9407 return true;
9408
9409 bool MustTrue = false, MustFalse = false;
9410
9411 auto AllowedRegion =
9413
9414 if (AllowedRegion.intersectWith(LHSAARange).isEmptySet())
9415 MustFalse = true;
9416
9417 if (LHSAARange.icmp(CmpI->getPredicate(), RHSAARange))
9418 MustTrue = true;
9419
9420 assert((!MustTrue || !MustFalse) &&
9421 "Either MustTrue or MustFalse should be false!");
9422
9423 if (MustTrue)
9424 T.unionAssumed(ConstantRange(APInt(/* numBits */ 1, /* val */ 1)));
9425 else if (MustFalse)
9426 T.unionAssumed(ConstantRange(APInt(/* numBits */ 1, /* val */ 0)));
9427 else
9428 T.unionAssumed(ConstantRange(/* BitWidth */ 1, /* isFullSet */ true));
9429
9430 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] " << *CmpI << " after "
9431 << (MustTrue ? "true" : (MustFalse ? "false" : "unknown"))
9432 << ": " << T << "\n\t" << *LHSAA << "\t<op>\n\t"
9433 << *RHSAA);
9434
9435 // TODO: Track a known state too.
9436 return T.isValidState();
9437 }
9438
9439 /// See AbstractAttribute::updateImpl(...).
9440 ChangeStatus updateImpl(Attributor &A) override {
9441
9443 auto VisitValueCB = [&](Value &V, const Instruction *CtxI) -> bool {
9444 Instruction *I = dyn_cast<Instruction>(&V);
9445 if (!I || isa<CallBase>(I)) {
9446
9447 // Simplify the operand first.
9448 bool UsedAssumedInformation = false;
9449 const auto &SimplifiedOpV = A.getAssumedSimplified(
9450 IRPosition::value(V, getCallBaseContext()), *this,
9451 UsedAssumedInformation, AA::Interprocedural);
9452 if (!SimplifiedOpV.has_value())
9453 return true;
9454 if (!*SimplifiedOpV)
9455 return false;
9456 Value *VPtr = *SimplifiedOpV;
9457
9458 // If the value is not instruction, we query AA to Attributor.
9459 const auto *AA = A.getAAFor<AAValueConstantRange>(
9460 *this, IRPosition::value(*VPtr, getCallBaseContext()),
9461 DepClassTy::REQUIRED);
9462
9463 // Clamp operator is not used to utilize a program point CtxI.
9464 if (AA)
9465 T.unionAssumed(AA->getAssumedConstantRange(A, CtxI));
9466 else
9467 return false;
9468
9469 return T.isValidState();
9470 }
9471
9473 if (auto *BinOp = dyn_cast<BinaryOperator>(I)) {
9474 if (!calculateBinaryOperator(A, BinOp, T, CtxI, QuerriedAAs))
9475 return false;
9476 } else if (auto *CmpI = dyn_cast<CmpInst>(I)) {
9477 if (!calculateCmpInst(A, CmpI, T, CtxI, QuerriedAAs))
9478 return false;
9479 } else if (auto *CastI = dyn_cast<CastInst>(I)) {
9480 if (!calculateCastInst(A, CastI, T, CtxI, QuerriedAAs))
9481 return false;
9482 } else {
9483 // Give up with other instructions.
9484 // TODO: Add other instructions
9485
9486 T.indicatePessimisticFixpoint();
9487 return false;
9488 }
9489
9490 // Catch circular reasoning in a pessimistic way for now.
9491 // TODO: Check how the range evolves and if we stripped anything, see also
9492 // AADereferenceable or AAAlign for similar situations.
9493 for (const AAValueConstantRange *QueriedAA : QuerriedAAs) {
9494 if (QueriedAA != this)
9495 continue;
9496 // If we are in a stady state we do not need to worry.
9497 if (T.getAssumed() == getState().getAssumed())
9498 continue;
9499 T.indicatePessimisticFixpoint();
9500 }
9501
9502 return T.isValidState();
9503 };
9504
9505 if (!VisitValueCB(getAssociatedValue(), getCtxI()))
9506 return indicatePessimisticFixpoint();
9507
9508 // Ensure that long def-use chains can't cause circular reasoning either by
9509 // introducing a cutoff below.
9510 if (clampStateAndIndicateChange(getState(), T) == ChangeStatus::UNCHANGED)
9511 return ChangeStatus::UNCHANGED;
9512 if (++NumChanges > MaxNumChanges) {
9513 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] performed " << NumChanges
9514 << " but only " << MaxNumChanges
9515 << " are allowed to avoid cyclic reasoning.");
9516 return indicatePessimisticFixpoint();
9517 }
9518 return ChangeStatus::CHANGED;
9519 }
9520
9521 /// See AbstractAttribute::trackStatistics()
9522 void trackStatistics() const override {
9524 }
9525
9526 /// Tracker to bail after too many widening steps of the constant range.
9527 int NumChanges = 0;
9528
9529 /// Upper bound for the number of allowed changes (=widening steps) for the
9530 /// constant range before we give up.
9531 static constexpr int MaxNumChanges = 5;
9532};
9533
9534struct AAValueConstantRangeFunction : AAValueConstantRangeImpl {
9535 AAValueConstantRangeFunction(const IRPosition &IRP, Attributor &A)
9536 : AAValueConstantRangeImpl(IRP, A) {}
9537
9538 /// See AbstractAttribute::initialize(...).
9539 ChangeStatus updateImpl(Attributor &A) override {
9540 llvm_unreachable("AAValueConstantRange(Function|CallSite)::updateImpl will "
9541 "not be called");
9542 }
9543
9544 /// See AbstractAttribute::trackStatistics()
9545 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(value_range) }
9546};
9547
9548struct AAValueConstantRangeCallSite : AAValueConstantRangeFunction {
9549 AAValueConstantRangeCallSite(const IRPosition &IRP, Attributor &A)
9550 : AAValueConstantRangeFunction(IRP, A) {}
9551
9552 /// See AbstractAttribute::trackStatistics()
9553 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(value_range) }
9554};
9555
9556struct AAValueConstantRangeCallSiteReturned
9557 : AACalleeToCallSite<AAValueConstantRange, AAValueConstantRangeImpl,
9558 AAValueConstantRangeImpl::StateType,
9559 /* IntroduceCallBaseContext */ true> {
9560 AAValueConstantRangeCallSiteReturned(const IRPosition &IRP, Attributor &A)
9561 : AACalleeToCallSite<AAValueConstantRange, AAValueConstantRangeImpl,
9562 AAValueConstantRangeImpl::StateType,
9563 /* IntroduceCallBaseContext */ true>(IRP, A) {}
9564
9565 /// See AbstractAttribute::initialize(...).
9566 void initialize(Attributor &A) override {
9567 // If it is a load instruction with range metadata, use the metadata.
9568 if (CallInst *CI = dyn_cast<CallInst>(&getAssociatedValue()))
9569 if (auto *RangeMD = CI->getMetadata(LLVMContext::MD_range))
9570 intersectKnown(getConstantRangeFromMetadata(*RangeMD));
9571
9572 AAValueConstantRangeImpl::initialize(A);
9573 }
9574
9575 /// See AbstractAttribute::trackStatistics()
9576 void trackStatistics() const override {
9577 STATS_DECLTRACK_CSRET_ATTR(value_range)
9578 }
9579};
9580struct AAValueConstantRangeCallSiteArgument : AAValueConstantRangeFloating {
9581 AAValueConstantRangeCallSiteArgument(const IRPosition &IRP, Attributor &A)
9582 : AAValueConstantRangeFloating(IRP, A) {}
9583
9584 /// See AbstractAttribute::manifest()
9585 ChangeStatus manifest(Attributor &A) override {
9586 return ChangeStatus::UNCHANGED;
9587 }
9588
9589 /// See AbstractAttribute::trackStatistics()
9590 void trackStatistics() const override {
9591 STATS_DECLTRACK_CSARG_ATTR(value_range)
9592 }
9593};
9594} // namespace
9595
9596/// ------------------ Potential Values Attribute -------------------------
9597
9598namespace {
9599struct AAPotentialConstantValuesImpl : AAPotentialConstantValues {
9600 using StateType = PotentialConstantIntValuesState;
9601
9602 AAPotentialConstantValuesImpl(const IRPosition &IRP, Attributor &A)
9603 : AAPotentialConstantValues(IRP, A) {}
9604
9605 /// See AbstractAttribute::initialize(..).
9606 void initialize(Attributor &A) override {
9607 if (A.hasSimplificationCallback(getIRPosition()))
9608 indicatePessimisticFixpoint();
9609 else
9610 AAPotentialConstantValues::initialize(A);
9611 }
9612
9613 bool fillSetWithConstantValues(Attributor &A, const IRPosition &IRP, SetTy &S,
9614 bool &ContainsUndef, bool ForSelf) {
9616 bool UsedAssumedInformation = false;
9617 if (!A.getAssumedSimplifiedValues(IRP, *this, Values, AA::Interprocedural,
9618 UsedAssumedInformation)) {
9619 // Avoid recursion when the caller is computing constant values for this
9620 // IRP itself.
9621 if (ForSelf)
9622 return false;
9623 if (!IRP.getAssociatedType()->isIntegerTy())
9624 return false;
9625 auto *PotentialValuesAA = A.getAAFor<AAPotentialConstantValues>(
9626 *this, IRP, DepClassTy::REQUIRED);
9627 if (!PotentialValuesAA || !PotentialValuesAA->getState().isValidState())
9628 return false;
9629 ContainsUndef = PotentialValuesAA->getState().undefIsContained();
9630 S = PotentialValuesAA->getState().getAssumedSet();
9631 return true;
9632 }
9633
9634 // Copy all the constant values, except UndefValue. ContainsUndef is true
9635 // iff Values contains only UndefValue instances. If there are other known
9636 // constants, then UndefValue is dropped.
9637 ContainsUndef = false;
9638 for (auto &It : Values) {
9639 if (isa<UndefValue>(It.getValue())) {
9640 ContainsUndef = true;
9641 continue;
9642 }
9643 auto *CI = dyn_cast<ConstantInt>(It.getValue());
9644 if (!CI)
9645 return false;
9646 S.insert(CI->getValue());
9647 }
9648 ContainsUndef &= S.empty();
9649
9650 return true;
9651 }
9652
9653 /// See AbstractAttribute::getAsStr().
9654 const std::string getAsStr(Attributor *A) const override {
9655 std::string Str;
9657 OS << getState();
9658 return Str;
9659 }
9660
9661 /// See AbstractAttribute::updateImpl(...).
9662 ChangeStatus updateImpl(Attributor &A) override {
9663 return indicatePessimisticFixpoint();
9664 }
9665};
9666
9667struct AAPotentialConstantValuesArgument final
9668 : AAArgumentFromCallSiteArguments<AAPotentialConstantValues,
9669 AAPotentialConstantValuesImpl,
9670 PotentialConstantIntValuesState> {
9671 using Base = AAArgumentFromCallSiteArguments<AAPotentialConstantValues,
9672 AAPotentialConstantValuesImpl,
9674 AAPotentialConstantValuesArgument(const IRPosition &IRP, Attributor &A)
9675 : Base(IRP, A) {}
9676
9677 /// See AbstractAttribute::trackStatistics()
9678 void trackStatistics() const override {
9679 STATS_DECLTRACK_ARG_ATTR(potential_values)
9680 }
9681};
9682
9683struct AAPotentialConstantValuesReturned
9684 : AAReturnedFromReturnedValues<AAPotentialConstantValues,
9685 AAPotentialConstantValuesImpl> {
9686 using Base = AAReturnedFromReturnedValues<AAPotentialConstantValues,
9687 AAPotentialConstantValuesImpl>;
9688 AAPotentialConstantValuesReturned(const IRPosition &IRP, Attributor &A)
9689 : Base(IRP, A) {}
9690
9691 void initialize(Attributor &A) override {
9692 if (!A.isFunctionIPOAmendable(*getAssociatedFunction()))
9693 indicatePessimisticFixpoint();
9694 Base::initialize(A);
9695 }
9696
9697 /// See AbstractAttribute::trackStatistics()
9698 void trackStatistics() const override {
9699 STATS_DECLTRACK_FNRET_ATTR(potential_values)
9700 }
9701};
9702
9703struct AAPotentialConstantValuesFloating : AAPotentialConstantValuesImpl {
9704 AAPotentialConstantValuesFloating(const IRPosition &IRP, Attributor &A)
9705 : AAPotentialConstantValuesImpl(IRP, A) {}
9706
9707 /// See AbstractAttribute::initialize(..).
9708 void initialize(Attributor &A) override {
9709 AAPotentialConstantValuesImpl::initialize(A);
9710 if (isAtFixpoint())
9711 return;
9712
9713 Value &V = getAssociatedValue();
9714
9715 if (auto *C = dyn_cast<ConstantInt>(&V)) {
9716 unionAssumed(C->getValue());
9717 indicateOptimisticFixpoint();
9718 return;
9719 }
9720
9721 if (isa<UndefValue>(&V)) {
9722 unionAssumedWithUndef();
9723 indicateOptimisticFixpoint();
9724 return;
9725 }
9726
9727 if (isa<BinaryOperator>(&V) || isa<ICmpInst>(&V) || isa<CastInst>(&V))
9728 return;
9729
9730 if (isa<SelectInst>(V) || isa<PHINode>(V) || isa<LoadInst>(V))
9731 return;
9732
9733 indicatePessimisticFixpoint();
9734
9735 LLVM_DEBUG(dbgs() << "[AAPotentialConstantValues] We give up: "
9736 << getAssociatedValue() << "\n");
9737 }
9738
9739 static bool calculateICmpInst(const ICmpInst *ICI, const APInt &LHS,
9740 const APInt &RHS) {
9741 return ICmpInst::compare(LHS, RHS, ICI->getPredicate());
9742 }
9743
9744 static APInt calculateCastInst(const CastInst *CI, const APInt &Src,
9745 uint32_t ResultBitWidth) {
9746 Instruction::CastOps CastOp = CI->getOpcode();
9747 switch (CastOp) {
9748 default:
9749 llvm_unreachable("unsupported or not integer cast");
9750 case Instruction::Trunc:
9751 return Src.trunc(ResultBitWidth);
9752 case Instruction::SExt:
9753 return Src.sext(ResultBitWidth);
9754 case Instruction::ZExt:
9755 return Src.zext(ResultBitWidth);
9756 case Instruction::BitCast:
9757 return Src;
9758 }
9759 }
9760
9761 static APInt calculateBinaryOperator(const BinaryOperator *BinOp,
9762 const APInt &LHS, const APInt &RHS,
9763 bool &SkipOperation, bool &Unsupported) {
9764 Instruction::BinaryOps BinOpcode = BinOp->getOpcode();
9765 // Unsupported is set to true when the binary operator is not supported.
9766 // SkipOperation is set to true when UB occur with the given operand pair
9767 // (LHS, RHS).
9768 // TODO: we should look at nsw and nuw keywords to handle operations
9769 // that create poison or undef value.
9770 switch (BinOpcode) {
9771 default:
9772 Unsupported = true;
9773 return LHS;
9774 case Instruction::Add:
9775 return LHS + RHS;
9776 case Instruction::Sub:
9777 return LHS - RHS;
9778 case Instruction::Mul:
9779 return LHS * RHS;
9780 case Instruction::UDiv:
9781 if (RHS.isZero()) {
9782 SkipOperation = true;
9783 return LHS;
9784 }
9785 return LHS.udiv(RHS);
9786 case Instruction::SDiv:
9787 if (RHS.isZero()) {
9788 SkipOperation = true;
9789 return LHS;
9790 }
9791 return LHS.sdiv(RHS);
9792 case Instruction::URem:
9793 if (RHS.isZero()) {
9794 SkipOperation = true;
9795 return LHS;
9796 }
9797 return LHS.urem(RHS);
9798 case Instruction::SRem:
9799 if (RHS.isZero()) {
9800 SkipOperation = true;
9801 return LHS;
9802 }
9803 return LHS.srem(RHS);
9804 case Instruction::Shl:
9805 return LHS.shl(RHS);
9806 case Instruction::LShr:
9807 return LHS.lshr(RHS);
9808 case Instruction::AShr:
9809 return LHS.ashr(RHS);
9810 case Instruction::And:
9811 return LHS & RHS;
9812 case Instruction::Or:
9813 return LHS | RHS;
9814 case Instruction::Xor:
9815 return LHS ^ RHS;
9816 }
9817 }
9818
9819 bool calculateBinaryOperatorAndTakeUnion(const BinaryOperator *BinOp,
9820 const APInt &LHS, const APInt &RHS) {
9821 bool SkipOperation = false;
9822 bool Unsupported = false;
9823 APInt Result =
9824 calculateBinaryOperator(BinOp, LHS, RHS, SkipOperation, Unsupported);
9825 if (Unsupported)
9826 return false;
9827 // If SkipOperation is true, we can ignore this operand pair (L, R).
9828 if (!SkipOperation)
9829 unionAssumed(Result);
9830 return isValidState();
9831 }
9832
9833 ChangeStatus updateWithICmpInst(Attributor &A, ICmpInst *ICI) {
9834 auto AssumedBefore = getAssumed();
9835 Value *LHS = ICI->getOperand(0);
9836 Value *RHS = ICI->getOperand(1);
9837
9838 bool LHSContainsUndef = false, RHSContainsUndef = false;
9839 SetTy LHSAAPVS, RHSAAPVS;
9840 if (!fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS,
9841 LHSContainsUndef, /* ForSelf */ false) ||
9842 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS,
9843 RHSContainsUndef, /* ForSelf */ false))
9844 return indicatePessimisticFixpoint();
9845
9846 // TODO: make use of undef flag to limit potential values aggressively.
9847 bool MaybeTrue = false, MaybeFalse = false;
9848 const APInt Zero(RHS->getType()->getIntegerBitWidth(), 0);
9849 if (LHSContainsUndef && RHSContainsUndef) {
9850 // The result of any comparison between undefs can be soundly replaced
9851 // with undef.
9852 unionAssumedWithUndef();
9853 } else if (LHSContainsUndef) {
9854 for (const APInt &R : RHSAAPVS) {
9855 bool CmpResult = calculateICmpInst(ICI, Zero, R);
9856 MaybeTrue |= CmpResult;
9857 MaybeFalse |= !CmpResult;
9858 if (MaybeTrue & MaybeFalse)
9859 return indicatePessimisticFixpoint();
9860 }
9861 } else if (RHSContainsUndef) {
9862 for (const APInt &L : LHSAAPVS) {
9863 bool CmpResult = calculateICmpInst(ICI, L, Zero);
9864 MaybeTrue |= CmpResult;
9865 MaybeFalse |= !CmpResult;
9866 if (MaybeTrue & MaybeFalse)
9867 return indicatePessimisticFixpoint();
9868 }
9869 } else {
9870 for (const APInt &L : LHSAAPVS) {
9871 for (const APInt &R : RHSAAPVS) {
9872 bool CmpResult = calculateICmpInst(ICI, L, R);
9873 MaybeTrue |= CmpResult;
9874 MaybeFalse |= !CmpResult;
9875 if (MaybeTrue & MaybeFalse)
9876 return indicatePessimisticFixpoint();
9877 }
9878 }
9879 }
9880 if (MaybeTrue)
9881 unionAssumed(APInt(/* numBits */ 1, /* val */ 1));
9882 if (MaybeFalse)
9883 unionAssumed(APInt(/* numBits */ 1, /* val */ 0));
9884 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
9885 : ChangeStatus::CHANGED;
9886 }
9887
9888 ChangeStatus updateWithSelectInst(Attributor &A, SelectInst *SI) {
9889 auto AssumedBefore = getAssumed();
9890 Value *LHS = SI->getTrueValue();
9891 Value *RHS = SI->getFalseValue();
9892
9893 bool UsedAssumedInformation = false;
9894 std::optional<Constant *> C = A.getAssumedConstant(
9895 *SI->getCondition(), *this, UsedAssumedInformation);
9896
9897 // Check if we only need one operand.
9898 bool OnlyLeft = false, OnlyRight = false;
9899 if (C && *C && (*C)->isOneValue())
9900 OnlyLeft = true;
9901 else if (C && *C && (*C)->isZeroValue())
9902 OnlyRight = true;
9903
9904 bool LHSContainsUndef = false, RHSContainsUndef = false;
9905 SetTy LHSAAPVS, RHSAAPVS;
9906 if (!OnlyRight &&
9907 !fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS,
9908 LHSContainsUndef, /* ForSelf */ false))
9909 return indicatePessimisticFixpoint();
9910
9911 if (!OnlyLeft &&
9912 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS,
9913 RHSContainsUndef, /* ForSelf */ false))
9914 return indicatePessimisticFixpoint();
9915
9916 if (OnlyLeft || OnlyRight) {
9917 // select (true/false), lhs, rhs
9918 auto *OpAA = OnlyLeft ? &LHSAAPVS : &RHSAAPVS;
9919 auto Undef = OnlyLeft ? LHSContainsUndef : RHSContainsUndef;
9920
9921 if (Undef)
9922 unionAssumedWithUndef();
9923 else {
9924 for (const auto &It : *OpAA)
9925 unionAssumed(It);
9926 }
9927
9928 } else if (LHSContainsUndef && RHSContainsUndef) {
9929 // select i1 *, undef , undef => undef
9930 unionAssumedWithUndef();
9931 } else {
9932 for (const auto &It : LHSAAPVS)
9933 unionAssumed(It);
9934 for (const auto &It : RHSAAPVS)
9935 unionAssumed(It);
9936 }
9937 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
9938 : ChangeStatus::CHANGED;
9939 }
9940
9941 ChangeStatus updateWithCastInst(Attributor &A, CastInst *CI) {
9942 auto AssumedBefore = getAssumed();
9943 if (!CI->isIntegerCast())
9944 return indicatePessimisticFixpoint();
9945 assert(CI->getNumOperands() == 1 && "Expected cast to be unary!");
9946 uint32_t ResultBitWidth = CI->getDestTy()->getIntegerBitWidth();
9947 Value *Src = CI->getOperand(0);
9948
9949 bool SrcContainsUndef = false;
9950 SetTy SrcPVS;
9951 if (!fillSetWithConstantValues(A, IRPosition::value(*Src), SrcPVS,
9952 SrcContainsUndef, /* ForSelf */ false))
9953 return indicatePessimisticFixpoint();
9954
9955 if (SrcContainsUndef)
9956 unionAssumedWithUndef();
9957 else {
9958 for (const APInt &S : SrcPVS) {
9959 APInt T = calculateCastInst(CI, S, ResultBitWidth);
9960 unionAssumed(T);
9961 }
9962 }
9963 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
9964 : ChangeStatus::CHANGED;
9965 }
9966
9967 ChangeStatus updateWithBinaryOperator(Attributor &A, BinaryOperator *BinOp) {
9968 auto AssumedBefore = getAssumed();
9969 Value *LHS = BinOp->getOperand(0);
9970 Value *RHS = BinOp->getOperand(1);
9971
9972 bool LHSContainsUndef = false, RHSContainsUndef = false;
9973 SetTy LHSAAPVS, RHSAAPVS;
9974 if (!fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS,
9975 LHSContainsUndef, /* ForSelf */ false) ||
9976 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS,
9977 RHSContainsUndef, /* ForSelf */ false))
9978 return indicatePessimisticFixpoint();
9979
9980 const APInt Zero = APInt(LHS->getType()->getIntegerBitWidth(), 0);
9981
9982 // TODO: make use of undef flag to limit potential values aggressively.
9983 if (LHSContainsUndef && RHSContainsUndef) {
9984 if (!calculateBinaryOperatorAndTakeUnion(BinOp, Zero, Zero))
9985 return indicatePessimisticFixpoint();
9986 } else if (LHSContainsUndef) {
9987 for (const APInt &R : RHSAAPVS) {
9988 if (!calculateBinaryOperatorAndTakeUnion(BinOp, Zero, R))
9989 return indicatePessimisticFixpoint();
9990 }
9991 } else if (RHSContainsUndef) {
9992 for (const APInt &L : LHSAAPVS) {
9993 if (!calculateBinaryOperatorAndTakeUnion(BinOp, L, Zero))
9994 return indicatePessimisticFixpoint();
9995 }
9996 } else {
9997 for (const APInt &L : LHSAAPVS) {
9998 for (const APInt &R : RHSAAPVS) {
9999 if (!calculateBinaryOperatorAndTakeUnion(BinOp, L, R))
10000 return indicatePessimisticFixpoint();
10001 }
10002 }
10003 }
10004 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10005 : ChangeStatus::CHANGED;
10006 }
10007
10008 ChangeStatus updateWithInstruction(Attributor &A, Instruction *Inst) {
10009 auto AssumedBefore = getAssumed();
10010 SetTy Incoming;
10011 bool ContainsUndef;
10012 if (!fillSetWithConstantValues(A, IRPosition::value(*Inst), Incoming,
10013 ContainsUndef, /* ForSelf */ true))
10014 return indicatePessimisticFixpoint();
10015 if (ContainsUndef) {
10016 unionAssumedWithUndef();
10017 } else {
10018 for (const auto &It : Incoming)
10019 unionAssumed(It);
10020 }
10021 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10022 : ChangeStatus::CHANGED;
10023 }
10024
10025 /// See AbstractAttribute::updateImpl(...).
10026 ChangeStatus updateImpl(Attributor &A) override {
10027 Value &V = getAssociatedValue();
10028 Instruction *I = dyn_cast<Instruction>(&V);
10029
10030 if (auto *ICI = dyn_cast<ICmpInst>(I))
10031 return updateWithICmpInst(A, ICI);
10032
10033 if (auto *SI = dyn_cast<SelectInst>(I))
10034 return updateWithSelectInst(A, SI);
10035
10036 if (auto *CI = dyn_cast<CastInst>(I))
10037 return updateWithCastInst(A, CI);
10038
10039 if (auto *BinOp = dyn_cast<BinaryOperator>(I))
10040 return updateWithBinaryOperator(A, BinOp);
10041
10042 if (isa<PHINode>(I) || isa<LoadInst>(I))
10043 return updateWithInstruction(A, I);
10044
10045 return indicatePessimisticFixpoint();
10046 }
10047
10048 /// See AbstractAttribute::trackStatistics()
10049 void trackStatistics() const override {
10050 STATS_DECLTRACK_FLOATING_ATTR(potential_values)
10051 }
10052};
10053
10054struct AAPotentialConstantValuesFunction : AAPotentialConstantValuesImpl {
10055 AAPotentialConstantValuesFunction(const IRPosition &IRP, Attributor &A)
10056 : AAPotentialConstantValuesImpl(IRP, A) {}
10057
10058 /// See AbstractAttribute::initialize(...).
10059 ChangeStatus updateImpl(Attributor &A) override {
10061 "AAPotentialConstantValues(Function|CallSite)::updateImpl will "
10062 "not be called");
10063 }
10064
10065 /// See AbstractAttribute::trackStatistics()
10066 void trackStatistics() const override {
10067 STATS_DECLTRACK_FN_ATTR(potential_values)
10068 }
10069};
10070
10071struct AAPotentialConstantValuesCallSite : AAPotentialConstantValuesFunction {
10072 AAPotentialConstantValuesCallSite(const IRPosition &IRP, Attributor &A)
10073 : AAPotentialConstantValuesFunction(IRP, A) {}
10074
10075 /// See AbstractAttribute::trackStatistics()
10076 void trackStatistics() const override {
10077 STATS_DECLTRACK_CS_ATTR(potential_values)
10078 }
10079};
10080
10081struct AAPotentialConstantValuesCallSiteReturned
10082 : AACalleeToCallSite<AAPotentialConstantValues,
10083 AAPotentialConstantValuesImpl> {
10084 AAPotentialConstantValuesCallSiteReturned(const IRPosition &IRP,
10085 Attributor &A)
10086 : AACalleeToCallSite<AAPotentialConstantValues,
10087 AAPotentialConstantValuesImpl>(IRP, A) {}
10088
10089 /// See AbstractAttribute::trackStatistics()
10090 void trackStatistics() const override {
10091 STATS_DECLTRACK_CSRET_ATTR(potential_values)
10092 }
10093};
10094
10095struct AAPotentialConstantValuesCallSiteArgument
10096 : AAPotentialConstantValuesFloating {
10097 AAPotentialConstantValuesCallSiteArgument(const IRPosition &IRP,
10098 Attributor &A)
10099 : AAPotentialConstantValuesFloating(IRP, A) {}
10100
10101 /// See AbstractAttribute::initialize(..).
10102 void initialize(Attributor &A) override {
10103 AAPotentialConstantValuesImpl::initialize(A);
10104 if (isAtFixpoint())
10105 return;
10106
10107 Value &V = getAssociatedValue();
10108
10109 if (auto *C = dyn_cast<ConstantInt>(&V)) {
10110 unionAssumed(C->getValue());
10111 indicateOptimisticFixpoint();
10112 return;
10113 }
10114
10115 if (isa<UndefValue>(&V)) {
10116 unionAssumedWithUndef();
10117 indicateOptimisticFixpoint();
10118 return;
10119 }
10120 }
10121
10122 /// See AbstractAttribute::updateImpl(...).
10123 ChangeStatus updateImpl(Attributor &A) override {
10124 Value &V = getAssociatedValue();
10125 auto AssumedBefore = getAssumed();
10126 auto *AA = A.getAAFor<AAPotentialConstantValues>(
10127 *this, IRPosition::value(V), DepClassTy::REQUIRED);
10128 if (!AA)
10129 return indicatePessimisticFixpoint();
10130 const auto &S = AA->getAssumed();
10131 unionAssumed(S);
10132 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10133 : ChangeStatus::CHANGED;
10134 }
10135
10136 /// See AbstractAttribute::trackStatistics()
10137 void trackStatistics() const override {
10138 STATS_DECLTRACK_CSARG_ATTR(potential_values)
10139 }
10140};
10141} // namespace
10142
10143/// ------------------------ NoUndef Attribute ---------------------------------
10145 Attribute::AttrKind ImpliedAttributeKind,
10146 bool IgnoreSubsumingPositions) {
10147 assert(ImpliedAttributeKind == Attribute::NoUndef &&
10148 "Unexpected attribute kind");
10149 if (A.hasAttr(IRP, {Attribute::NoUndef}, IgnoreSubsumingPositions,
10150 Attribute::NoUndef))
10151 return true;
10152
10153 Value &Val = IRP.getAssociatedValue();
10156 LLVMContext &Ctx = Val.getContext();
10157 A.manifestAttrs(IRP, Attribute::get(Ctx, Attribute::NoUndef));
10158 return true;
10159 }
10160
10161 return false;
10162}
10163
10164namespace {
10165struct AANoUndefImpl : AANoUndef {
10166 AANoUndefImpl(const IRPosition &IRP, Attributor &A) : AANoUndef(IRP, A) {}
10167
10168 /// See AbstractAttribute::initialize(...).
10169 void initialize(Attributor &A) override {
10170 Value &V = getAssociatedValue();
10171 if (isa<UndefValue>(V))
10172 indicatePessimisticFixpoint();
10173 assert(!isImpliedByIR(A, getIRPosition(), Attribute::NoUndef));
10174 }
10175
10176 /// See followUsesInMBEC
10177 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
10178 AANoUndef::StateType &State) {
10179 const Value *UseV = U->get();
10180 const DominatorTree *DT = nullptr;
10181 AssumptionCache *AC = nullptr;
10182 InformationCache &InfoCache = A.getInfoCache();
10183 if (Function *F = getAnchorScope()) {
10186 }
10187 State.setKnown(isGuaranteedNotToBeUndefOrPoison(UseV, AC, I, DT));
10188 bool TrackUse = false;
10189 // Track use for instructions which must produce undef or poison bits when
10190 // at least one operand contains such bits.
10191 if (isa<CastInst>(*I) || isa<GetElementPtrInst>(*I))
10192 TrackUse = true;
10193 return TrackUse;
10194 }
10195
10196 /// See AbstractAttribute::getAsStr().
10197 const std::string getAsStr(Attributor *A) const override {
10198 return getAssumed() ? "noundef" : "may-undef-or-poison";
10199 }
10200
10201 ChangeStatus manifest(Attributor &A) override {
10202 // We don't manifest noundef attribute for dead positions because the
10203 // associated values with dead positions would be replaced with undef
10204 // values.
10205 bool UsedAssumedInformation = false;
10206 if (A.isAssumedDead(getIRPosition(), nullptr, nullptr,
10207 UsedAssumedInformation))
10208 return ChangeStatus::UNCHANGED;
10209 // A position whose simplified value does not have any value is
10210 // considered to be dead. We don't manifest noundef in such positions for
10211 // the same reason above.
10212 if (!A.getAssumedSimplified(getIRPosition(), *this, UsedAssumedInformation,
10214 .has_value())
10215 return ChangeStatus::UNCHANGED;
10216 return AANoUndef::manifest(A);
10217 }
10218};
10219
10220struct AANoUndefFloating : public AANoUndefImpl {
10221 AANoUndefFloating(const IRPosition &IRP, Attributor &A)
10222 : AANoUndefImpl(IRP, A) {}
10223
10224 /// See AbstractAttribute::initialize(...).
10225 void initialize(Attributor &A) override {
10226 AANoUndefImpl::initialize(A);
10227 if (!getState().isAtFixpoint() && getAnchorScope() &&
10228 !getAnchorScope()->isDeclaration())
10229 if (Instruction *CtxI = getCtxI())
10230 followUsesInMBEC(*this, A, getState(), *CtxI);
10231 }
10232
10233 /// See AbstractAttribute::updateImpl(...).
10234 ChangeStatus updateImpl(Attributor &A) override {
10235 auto VisitValueCB = [&](const IRPosition &IRP) -> bool {
10236 bool IsKnownNoUndef;
10237 return AA::hasAssumedIRAttr<Attribute::NoUndef>(
10238 A, this, IRP, DepClassTy::REQUIRED, IsKnownNoUndef);
10239 };
10240
10241 bool Stripped;
10242 bool UsedAssumedInformation = false;
10243 Value *AssociatedValue = &getAssociatedValue();
10245 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
10246 AA::AnyScope, UsedAssumedInformation))
10247 Stripped = false;
10248 else
10249 Stripped =
10250 Values.size() != 1 || Values.front().getValue() != AssociatedValue;
10251
10252 if (!Stripped) {
10253 // If we haven't stripped anything we might still be able to use a
10254 // different AA, but only if the IRP changes. Effectively when we
10255 // interpret this not as a call site value but as a floating/argument
10256 // value.
10257 const IRPosition AVIRP = IRPosition::value(*AssociatedValue);
10258 if (AVIRP == getIRPosition() || !VisitValueCB(AVIRP))
10259 return indicatePessimisticFixpoint();
10260 return ChangeStatus::UNCHANGED;
10261 }
10262
10263 for (const auto &VAC : Values)
10264 if (!VisitValueCB(IRPosition::value(*VAC.getValue())))
10265 return indicatePessimisticFixpoint();
10266
10267 return ChangeStatus::UNCHANGED;
10268 }
10269
10270 /// See AbstractAttribute::trackStatistics()
10271 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noundef) }
10272};
10273
10274struct AANoUndefReturned final
10275 : AAReturnedFromReturnedValues<AANoUndef, AANoUndefImpl> {
10276 AANoUndefReturned(const IRPosition &IRP, Attributor &A)
10277 : AAReturnedFromReturnedValues<AANoUndef, AANoUndefImpl>(IRP, A) {}
10278
10279 /// See AbstractAttribute::trackStatistics()
10280 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noundef) }
10281};
10282
10283struct AANoUndefArgument final
10284 : AAArgumentFromCallSiteArguments<AANoUndef, AANoUndefImpl> {
10285 AANoUndefArgument(const IRPosition &IRP, Attributor &A)
10286 : AAArgumentFromCallSiteArguments<AANoUndef, AANoUndefImpl>(IRP, A) {}
10287
10288 /// See AbstractAttribute::trackStatistics()
10289 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noundef) }
10290};
10291
10292struct AANoUndefCallSiteArgument final : AANoUndefFloating {
10293 AANoUndefCallSiteArgument(const IRPosition &IRP, Attributor &A)
10294 : AANoUndefFloating(IRP, A) {}
10295
10296 /// See AbstractAttribute::trackStatistics()
10297 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(noundef) }
10298};
10299
10300struct AANoUndefCallSiteReturned final
10301 : AACalleeToCallSite<AANoUndef, AANoUndefImpl> {
10302 AANoUndefCallSiteReturned(const IRPosition &IRP, Attributor &A)
10303 : AACalleeToCallSite<AANoUndef, AANoUndefImpl>(IRP, A) {}
10304
10305 /// See AbstractAttribute::trackStatistics()
10306 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(noundef) }
10307};
10308
10309/// ------------------------ NoFPClass Attribute -------------------------------
10310
10311struct AANoFPClassImpl : AANoFPClass {
10312 AANoFPClassImpl(const IRPosition &IRP, Attributor &A) : AANoFPClass(IRP, A) {}
10313
10314 void initialize(Attributor &A) override {
10315 const IRPosition &IRP = getIRPosition();
10316
10317 Value &V = IRP.getAssociatedValue();
10318 if (isa<UndefValue>(V)) {
10319 indicateOptimisticFixpoint();
10320 return;
10321 }
10322
10324 A.getAttrs(getIRPosition(), {Attribute::NoFPClass}, Attrs, false);
10325 for (const auto &Attr : Attrs) {
10326 addKnownBits(Attr.getNoFPClass());
10327 }
10328
10329 const DataLayout &DL = A.getDataLayout();
10330 if (getPositionKind() != IRPosition::IRP_RETURNED) {
10332 addKnownBits(~KnownFPClass.KnownFPClasses);
10333 }
10334
10335 if (Instruction *CtxI = getCtxI())
10336 followUsesInMBEC(*this, A, getState(), *CtxI);
10337 }
10338
10339 /// See followUsesInMBEC
10340 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
10341 AANoFPClass::StateType &State) {
10342 // TODO: Determine what instructions can be looked through.
10343 auto *CB = dyn_cast<CallBase>(I);
10344 if (!CB)
10345 return false;
10346
10347 if (!CB->isArgOperand(U))
10348 return false;
10349
10350 unsigned ArgNo = CB->getArgOperandNo(U);
10351 IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo);
10352 if (auto *NoFPAA = A.getAAFor<AANoFPClass>(*this, IRP, DepClassTy::NONE))
10353 State.addKnownBits(NoFPAA->getState().getKnown());
10354 return false;
10355 }
10356
10357 const std::string getAsStr(Attributor *A) const override {
10358 std::string Result = "nofpclass";
10359 raw_string_ostream OS(Result);
10360 OS << getKnownNoFPClass() << '/' << getAssumedNoFPClass();
10361 return Result;
10362 }
10363
10364 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
10365 SmallVectorImpl<Attribute> &Attrs) const override {
10366 Attrs.emplace_back(Attribute::getWithNoFPClass(Ctx, getAssumedNoFPClass()));
10367 }
10368};
10369
10370struct AANoFPClassFloating : public AANoFPClassImpl {
10371 AANoFPClassFloating(const IRPosition &IRP, Attributor &A)
10372 : AANoFPClassImpl(IRP, A) {}
10373
10374 /// See AbstractAttribute::updateImpl(...).
10375 ChangeStatus updateImpl(Attributor &A) override {
10377 bool UsedAssumedInformation = false;
10378 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
10379 AA::AnyScope, UsedAssumedInformation)) {
10380 Values.push_back({getAssociatedValue(), getCtxI()});
10381 }
10382
10383 StateType T;
10384 auto VisitValueCB = [&](Value &V, const Instruction *CtxI) -> bool {
10385 const auto *AA = A.getAAFor<AANoFPClass>(*this, IRPosition::value(V),
10386 DepClassTy::REQUIRED);
10387 if (!AA || this == AA) {
10388 T.indicatePessimisticFixpoint();
10389 } else {
10390 const AANoFPClass::StateType &S =
10391 static_cast<const AANoFPClass::StateType &>(AA->getState());
10392 T ^= S;
10393 }
10394 return T.isValidState();
10395 };
10396
10397 for (const auto &VAC : Values)
10398 if (!VisitValueCB(*VAC.getValue(), VAC.getCtxI()))
10399 return indicatePessimisticFixpoint();
10400
10401 return clampStateAndIndicateChange(getState(), T);
10402 }
10403
10404 /// See AbstractAttribute::trackStatistics()
10405 void trackStatistics() const override {
10407 }
10408};
10409
10410struct AANoFPClassReturned final
10411 : AAReturnedFromReturnedValues<AANoFPClass, AANoFPClassImpl,
10412 AANoFPClassImpl::StateType, false,
10413 Attribute::None, false> {
10414 AANoFPClassReturned(const IRPosition &IRP, Attributor &A)
10415 : AAReturnedFromReturnedValues<AANoFPClass, AANoFPClassImpl,
10416 AANoFPClassImpl::StateType, false,
10417 Attribute::None, false>(IRP, A) {}
10418
10419 /// See AbstractAttribute::trackStatistics()
10420 void trackStatistics() const override {
10422 }
10423};
10424
10425struct AANoFPClassArgument final
10426 : AAArgumentFromCallSiteArguments<AANoFPClass, AANoFPClassImpl> {
10427 AANoFPClassArgument(const IRPosition &IRP, Attributor &A)
10428 : AAArgumentFromCallSiteArguments<AANoFPClass, AANoFPClassImpl>(IRP, A) {}
10429
10430 /// See AbstractAttribute::trackStatistics()
10431 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nofpclass) }
10432};
10433
10434struct AANoFPClassCallSiteArgument final : AANoFPClassFloating {
10435 AANoFPClassCallSiteArgument(const IRPosition &IRP, Attributor &A)
10436 : AANoFPClassFloating(IRP, A) {}
10437
10438 /// See AbstractAttribute::trackStatistics()
10439 void trackStatistics() const override {
10441 }
10442};
10443
10444struct AANoFPClassCallSiteReturned final
10445 : AACalleeToCallSite<AANoFPClass, AANoFPClassImpl> {
10446 AANoFPClassCallSiteReturned(const IRPosition &IRP, Attributor &A)
10447 : AACalleeToCallSite<AANoFPClass, AANoFPClassImpl>(IRP, A) {}
10448
10449 /// See AbstractAttribute::trackStatistics()
10450 void trackStatistics() const override {
10452 }
10453};
10454
10455struct AACallEdgesImpl : public AACallEdges {
10456 AACallEdgesImpl(const IRPosition &IRP, Attributor &A) : AACallEdges(IRP, A) {}
10457
10458 const SetVector<Function *> &getOptimisticEdges() const override {
10459 return CalledFunctions;
10460 }
10461
10462 bool hasUnknownCallee() const override { return HasUnknownCallee; }
10463
10464 bool hasNonAsmUnknownCallee() const override {
10465 return HasUnknownCalleeNonAsm;
10466 }
10467
10468 const std::string getAsStr(Attributor *A) const override {
10469 return "CallEdges[" + std::to_string(HasUnknownCallee) + "," +
10470 std::to_string(CalledFunctions.size()) + "]";
10471 }
10472
10473 void trackStatistics() const override {}
10474
10475protected:
10476 void addCalledFunction(Function *Fn, ChangeStatus &Change) {
10477 if (CalledFunctions.insert(Fn)) {
10478 Change = ChangeStatus::CHANGED;
10479 LLVM_DEBUG(dbgs() << "[AACallEdges] New call edge: " << Fn->getName()
10480 << "\n");
10481 }
10482 }
10483
10484 void setHasUnknownCallee(bool NonAsm, ChangeStatus &Change) {
10485 if (!HasUnknownCallee)
10486 Change = ChangeStatus::CHANGED;
10487 if (NonAsm && !HasUnknownCalleeNonAsm)
10488 Change = ChangeStatus::CHANGED;
10489 HasUnknownCalleeNonAsm |= NonAsm;
10490 HasUnknownCallee = true;
10491 }
10492
10493private:
10494 /// Optimistic set of functions that might be called by this position.
10495 SetVector<Function *> CalledFunctions;
10496
10497 /// Is there any call with a unknown callee.
10498 bool HasUnknownCallee = false;
10499
10500 /// Is there any call with a unknown callee, excluding any inline asm.
10501 bool HasUnknownCalleeNonAsm = false;
10502};
10503
10504struct AACallEdgesCallSite : public AACallEdgesImpl {
10505 AACallEdgesCallSite(const IRPosition &IRP, Attributor &A)
10506 : AACallEdgesImpl(IRP, A) {}
10507 /// See AbstractAttribute::updateImpl(...).
10508 ChangeStatus updateImpl(Attributor &A) override {
10509 ChangeStatus Change = ChangeStatus::UNCHANGED;
10510
10511 auto VisitValue = [&](Value &V, const Instruction *CtxI) -> bool {
10512 if (Function *Fn = dyn_cast<Function>(&V)) {
10513 addCalledFunction(Fn, Change);
10514 } else {
10515 LLVM_DEBUG(dbgs() << "[AACallEdges] Unrecognized value: " << V << "\n");
10516 setHasUnknownCallee(true, Change);
10517 }
10518
10519 // Explore all values.
10520 return true;
10521 };
10522
10524 // Process any value that we might call.
10525 auto ProcessCalledOperand = [&](Value *V, Instruction *CtxI) {
10526 if (isa<Constant>(V)) {
10527 VisitValue(*V, CtxI);
10528 return;
10529 }
10530
10531 bool UsedAssumedInformation = false;
10532 Values.clear();
10533 if (!A.getAssumedSimplifiedValues(IRPosition::value(*V), *this, Values,
10534 AA::AnyScope, UsedAssumedInformation)) {
10535 Values.push_back({*V, CtxI});
10536 }
10537 for (auto &VAC : Values)
10538 VisitValue(*VAC.getValue(), VAC.getCtxI());
10539 };
10540
10541 CallBase *CB = cast<CallBase>(getCtxI());
10542
10543 if (auto *IA = dyn_cast<InlineAsm>(CB->getCalledOperand())) {
10544 if (IA->hasSideEffects() &&
10545 !hasAssumption(*CB->getCaller(), "ompx_no_call_asm") &&
10546 !hasAssumption(*CB, "ompx_no_call_asm")) {
10547 setHasUnknownCallee(false, Change);
10548 }
10549 return Change;
10550 }
10551
10552 if (CB->isIndirectCall())
10553 if (auto *IndirectCallAA = A.getAAFor<AAIndirectCallInfo>(
10554 *this, getIRPosition(), DepClassTy::OPTIONAL))
10555 if (IndirectCallAA->foreachCallee(
10556 [&](Function *Fn) { return VisitValue(*Fn, CB); }))
10557 return Change;
10558
10559 // The most simple case.
10560 ProcessCalledOperand(CB->getCalledOperand(), CB);
10561
10562 // Process callback functions.
10563 SmallVector<const Use *, 4u> CallbackUses;
10564 AbstractCallSite::getCallbackUses(*CB, CallbackUses);
10565 for (const Use *U : CallbackUses)
10566 ProcessCalledOperand(U->get(), CB);
10567
10568 return Change;
10569 }
10570};
10571
10572struct AACallEdgesFunction : public AACallEdgesImpl {
10573 AACallEdgesFunction(const IRPosition &IRP, Attributor &A)
10574 : AACallEdgesImpl(IRP, A) {}
10575
10576 /// See AbstractAttribute::updateImpl(...).
10577 ChangeStatus updateImpl(Attributor &A) override {
10578 ChangeStatus Change = ChangeStatus::UNCHANGED;
10579
10580 auto ProcessCallInst = [&](Instruction &Inst) {
10581 CallBase &CB = cast<CallBase>(Inst);
10582
10583 auto *CBEdges = A.getAAFor<AACallEdges>(
10584 *this, IRPosition::callsite_function(CB), DepClassTy::REQUIRED);
10585 if (!CBEdges)
10586 return false;
10587 if (CBEdges->hasNonAsmUnknownCallee())
10588 setHasUnknownCallee(true, Change);
10589 if (CBEdges->hasUnknownCallee())
10590 setHasUnknownCallee(false, Change);
10591
10592 for (Function *F : CBEdges->getOptimisticEdges())
10593 addCalledFunction(F, Change);
10594
10595 return true;
10596 };
10597
10598 // Visit all callable instructions.
10599 bool UsedAssumedInformation = false;
10600 if (!A.checkForAllCallLikeInstructions(ProcessCallInst, *this,
10601 UsedAssumedInformation,
10602 /* CheckBBLivenessOnly */ true)) {
10603 // If we haven't looked at all call like instructions, assume that there
10604 // are unknown callees.
10605 setHasUnknownCallee(true, Change);
10606 }
10607
10608 return Change;
10609 }
10610};
10611
10612/// -------------------AAInterFnReachability Attribute--------------------------
10613
10614struct AAInterFnReachabilityFunction
10615 : public CachedReachabilityAA<AAInterFnReachability, Function> {
10616 using Base = CachedReachabilityAA<AAInterFnReachability, Function>;
10617 AAInterFnReachabilityFunction(const IRPosition &IRP, Attributor &A)
10618 : Base(IRP, A) {}
10619
10620 bool instructionCanReach(
10621 Attributor &A, const Instruction &From, const Function &To,
10622 const AA::InstExclusionSetTy *ExclusionSet) const override {
10623 assert(From.getFunction() == getAnchorScope() && "Queried the wrong AA!");
10624 auto *NonConstThis = const_cast<AAInterFnReachabilityFunction *>(this);
10625
10626 RQITy StackRQI(A, From, To, ExclusionSet, false);
10627 typename RQITy::Reachable Result;
10628 if (!NonConstThis->checkQueryCache(A, StackRQI, Result))
10629 return NonConstThis->isReachableImpl(A, StackRQI,
10630 /*IsTemporaryRQI=*/true);
10631 return Result == RQITy::Reachable::Yes;
10632 }
10633
10634 bool isReachableImpl(Attributor &A, RQITy &RQI,
10635 bool IsTemporaryRQI) override {
10636 const Instruction *EntryI =
10637 &RQI.From->getFunction()->getEntryBlock().front();
10638 if (EntryI != RQI.From &&
10639 !instructionCanReach(A, *EntryI, *RQI.To, nullptr))
10640 return rememberResult(A, RQITy::Reachable::No, RQI, false,
10641 IsTemporaryRQI);
10642
10643 auto CheckReachableCallBase = [&](CallBase *CB) {
10644 auto *CBEdges = A.getAAFor<AACallEdges>(
10645 *this, IRPosition::callsite_function(*CB), DepClassTy::OPTIONAL);
10646 if (!CBEdges || !CBEdges->getState().isValidState())
10647 return false;
10648 // TODO Check To backwards in this case.
10649 if (CBEdges->hasUnknownCallee())
10650 return false;
10651
10652 for (Function *Fn : CBEdges->getOptimisticEdges()) {
10653 if (Fn == RQI.To)
10654 return false;
10655
10656 if (Fn->isDeclaration()) {
10657 if (Fn->hasFnAttribute(Attribute::NoCallback))
10658 continue;
10659 // TODO Check To backwards in this case.
10660 return false;
10661 }
10662
10663 if (Fn == getAnchorScope()) {
10664 if (EntryI == RQI.From)
10665 continue;
10666 return false;
10667 }
10668
10669 const AAInterFnReachability *InterFnReachability =
10670 A.getAAFor<AAInterFnReachability>(*this, IRPosition::function(*Fn),
10671 DepClassTy::OPTIONAL);
10672
10673 const Instruction &FnFirstInst = Fn->getEntryBlock().front();
10674 if (!InterFnReachability ||
10675 InterFnReachability->instructionCanReach(A, FnFirstInst, *RQI.To,
10676 RQI.ExclusionSet))
10677 return false;
10678 }
10679 return true;
10680 };
10681
10682 const auto *IntraFnReachability = A.getAAFor<AAIntraFnReachability>(
10683 *this, IRPosition::function(*RQI.From->getFunction()),
10684 DepClassTy::OPTIONAL);
10685
10686 // Determine call like instructions that we can reach from the inst.
10687 auto CheckCallBase = [&](Instruction &CBInst) {
10688 // There are usually less nodes in the call graph, check inter function
10689 // reachability first.
10690 if (CheckReachableCallBase(cast<CallBase>(&CBInst)))
10691 return true;
10692 return IntraFnReachability && !IntraFnReachability->isAssumedReachable(
10693 A, *RQI.From, CBInst, RQI.ExclusionSet);
10694 };
10695
10696 bool UsedExclusionSet = /* conservative */ true;
10697 bool UsedAssumedInformation = false;
10698 if (!A.checkForAllCallLikeInstructions(CheckCallBase, *this,
10699 UsedAssumedInformation,
10700 /* CheckBBLivenessOnly */ true))
10701 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
10702 IsTemporaryRQI);
10703
10704 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
10705 IsTemporaryRQI);
10706 }
10707
10708 void trackStatistics() const override {}
10709};
10710} // namespace
10711
10712template <typename AAType>
10713static std::optional<Constant *>
10715 const IRPosition &IRP, Type &Ty) {
10716 if (!Ty.isIntegerTy())
10717 return nullptr;
10718
10719 // This will also pass the call base context.
10720 const auto *AA = A.getAAFor<AAType>(QueryingAA, IRP, DepClassTy::NONE);
10721 if (!AA)
10722 return nullptr;
10723
10724 std::optional<Constant *> COpt = AA->getAssumedConstant(A);
10725
10726 if (!COpt.has_value()) {
10727 A.recordDependence(*AA, QueryingAA, DepClassTy::OPTIONAL);
10728 return std::nullopt;
10729 }
10730 if (auto *C = *COpt) {
10731 A.recordDependence(*AA, QueryingAA, DepClassTy::OPTIONAL);
10732 return C;
10733 }
10734 return nullptr;
10735}
10736
10738 Attributor &A, const AbstractAttribute &AA, const IRPosition &IRP,
10740 Type &Ty = *IRP.getAssociatedType();
10741 std::optional<Value *> V;
10742 for (auto &It : Values) {
10743 V = AA::combineOptionalValuesInAAValueLatice(V, It.getValue(), &Ty);
10744 if (V.has_value() && !*V)
10745 break;
10746 }
10747 if (!V.has_value())
10748 return UndefValue::get(&Ty);
10749 return *V;
10750}
10751
10752namespace {
10753struct AAPotentialValuesImpl : AAPotentialValues {
10754 using StateType = PotentialLLVMValuesState;
10755
10756 AAPotentialValuesImpl(const IRPosition &IRP, Attributor &A)
10757 : AAPotentialValues(IRP, A) {}
10758
10759 /// See AbstractAttribute::initialize(..).
10760 void initialize(Attributor &A) override {
10761 if (A.hasSimplificationCallback(getIRPosition())) {
10762 indicatePessimisticFixpoint();
10763 return;
10764 }
10765 Value *Stripped = getAssociatedValue().stripPointerCasts();
10766 if (isa<Constant>(Stripped) && !isa<ConstantExpr>(Stripped)) {
10767 addValue(A, getState(), *Stripped, getCtxI(), AA::AnyScope,
10768 getAnchorScope());
10769 indicateOptimisticFixpoint();
10770 return;
10771 }
10772 AAPotentialValues::initialize(A);
10773 }
10774
10775 /// See AbstractAttribute::getAsStr().
10776 const std::string getAsStr(Attributor *A) const override {
10777 std::string Str;
10779 OS << getState();
10780 return Str;
10781 }
10782
10783 template <typename AAType>
10784 static std::optional<Value *> askOtherAA(Attributor &A,
10785 const AbstractAttribute &AA,
10786 const IRPosition &IRP, Type &Ty) {
10787 if (isa<Constant>(IRP.getAssociatedValue()))
10788 return &IRP.getAssociatedValue();
10789 std::optional<Constant *> C = askForAssumedConstant<AAType>(A, AA, IRP, Ty);
10790 if (!C)
10791 return std::nullopt;
10792 if (*C)
10793 if (auto *CC = AA::getWithType(**C, Ty))
10794 return CC;
10795 return nullptr;
10796 }
10797
10798 virtual void addValue(Attributor &A, StateType &State, Value &V,
10799 const Instruction *CtxI, AA::ValueScope S,
10800 Function *AnchorScope) const {
10801
10802 IRPosition ValIRP = IRPosition::value(V);
10803 if (auto *CB = dyn_cast_or_null<CallBase>(CtxI)) {
10804 for (const auto &U : CB->args()) {
10805 if (U.get() != &V)
10806 continue;
10807 ValIRP = IRPosition::callsite_argument(*CB, CB->getArgOperandNo(&U));
10808 break;
10809 }
10810 }
10811
10812 Value *VPtr = &V;
10813 if (ValIRP.getAssociatedType()->isIntegerTy()) {
10814 Type &Ty = *getAssociatedType();
10815 std::optional<Value *> SimpleV =
10816 askOtherAA<AAValueConstantRange>(A, *this, ValIRP, Ty);
10817 if (SimpleV.has_value() && !*SimpleV) {
10818 auto *PotentialConstantsAA = A.getAAFor<AAPotentialConstantValues>(
10819 *this, ValIRP, DepClassTy::OPTIONAL);
10820 if (PotentialConstantsAA && PotentialConstantsAA->isValidState()) {
10821 for (const auto &It : PotentialConstantsAA->getAssumedSet())
10822 State.unionAssumed({{*ConstantInt::get(&Ty, It), nullptr}, S});
10823 if (PotentialConstantsAA->undefIsContained())
10824 State.unionAssumed({{*UndefValue::get(&Ty), nullptr}, S});
10825 return;
10826 }
10827 }
10828 if (!SimpleV.has_value())
10829 return;
10830
10831 if (*SimpleV)
10832 VPtr = *SimpleV;
10833 }
10834
10835 if (isa<ConstantInt>(VPtr))
10836 CtxI = nullptr;
10837 if (!AA::isValidInScope(*VPtr, AnchorScope))
10839
10840 State.unionAssumed({{*VPtr, CtxI}, S});
10841 }
10842
10843 /// Helper struct to tie a value+context pair together with the scope for
10844 /// which this is the simplified version.
10845 struct ItemInfo {
10848
10849 bool operator==(const ItemInfo &II) const {
10850 return II.I == I && II.S == S;
10851 };
10852 bool operator<(const ItemInfo &II) const {
10853 if (I == II.I)
10854 return S < II.S;
10855 return I < II.I;
10856 };
10857 };
10858
10859 bool recurseForValue(Attributor &A, const IRPosition &IRP, AA::ValueScope S) {
10861 for (auto CS : {AA::Intraprocedural, AA::Interprocedural}) {
10862 if (!(CS & S))
10863 continue;
10864
10865 bool UsedAssumedInformation = false;
10867 if (!A.getAssumedSimplifiedValues(IRP, this, Values, CS,
10868 UsedAssumedInformation))
10869 return false;
10870
10871 for (auto &It : Values)
10872 ValueScopeMap[It] += CS;
10873 }
10874 for (auto &It : ValueScopeMap)
10875 addValue(A, getState(), *It.first.getValue(), It.first.getCtxI(),
10876 AA::ValueScope(It.second), getAnchorScope());
10877
10878 return true;
10879 }
10880
10881 void giveUpOnIntraprocedural(Attributor &A) {
10882 auto NewS = StateType::getBestState(getState());
10883 for (const auto &It : getAssumedSet()) {
10884 if (It.second == AA::Intraprocedural)
10885 continue;
10886 addValue(A, NewS, *It.first.getValue(), It.first.getCtxI(),
10887 AA::Interprocedural, getAnchorScope());
10888 }
10889 assert(!undefIsContained() && "Undef should be an explicit value!");
10890 addValue(A, NewS, getAssociatedValue(), getCtxI(), AA::Intraprocedural,
10891 getAnchorScope());
10892 getState() = NewS;
10893 }
10894
10895 /// See AbstractState::indicatePessimisticFixpoint(...).
10896 ChangeStatus indicatePessimisticFixpoint() override {
10897 getState() = StateType::getBestState(getState());
10898 getState().unionAssumed({{getAssociatedValue(), getCtxI()}, AA::AnyScope});
10900 return ChangeStatus::CHANGED;
10901 }
10902
10903 /// See AbstractAttribute::updateImpl(...).
10904 ChangeStatus updateImpl(Attributor &A) override {
10905 return indicatePessimisticFixpoint();
10906 }
10907
10908 /// See AbstractAttribute::manifest(...).
10909 ChangeStatus manifest(Attributor &A) override {
10912 Values.clear();
10913 if (!getAssumedSimplifiedValues(A, Values, S))
10914 continue;
10915 Value &OldV = getAssociatedValue();
10916 if (isa<UndefValue>(OldV))
10917 continue;
10918 Value *NewV = getSingleValue(A, *this, getIRPosition(), Values);
10919 if (!NewV || NewV == &OldV)
10920 continue;
10921 if (getCtxI() &&
10922 !AA::isValidAtPosition({*NewV, *getCtxI()}, A.getInfoCache()))
10923 continue;
10924 if (A.changeAfterManifest(getIRPosition(), *NewV))
10925 return ChangeStatus::CHANGED;
10926 }
10928 }
10929
10930 bool getAssumedSimplifiedValues(
10932 AA::ValueScope S, bool RecurseForSelectAndPHI = false) const override {
10933 if (!isValidState())
10934 return false;
10935 bool UsedAssumedInformation = false;
10936 for (const auto &It : getAssumedSet())
10937 if (It.second & S) {
10938 if (RecurseForSelectAndPHI && (isa<PHINode>(It.first.getValue()) ||
10939 isa<SelectInst>(It.first.getValue()))) {
10940 if (A.getAssumedSimplifiedValues(
10941 IRPosition::inst(*cast<Instruction>(It.first.getValue())),
10942 this, Values, S, UsedAssumedInformation))
10943 continue;
10944 }
10945 Values.push_back(It.first);
10946 }
10947 assert(!undefIsContained() && "Undef should be an explicit value!");
10948 return true;
10949 }
10950};
10951
10952struct AAPotentialValuesFloating : AAPotentialValuesImpl {
10953 AAPotentialValuesFloating(const IRPosition &IRP, Attributor &A)
10954 : AAPotentialValuesImpl(IRP, A) {}
10955
10956 /// See AbstractAttribute::updateImpl(...).
10957 ChangeStatus updateImpl(Attributor &A) override {
10958 auto AssumedBefore = getAssumed();
10959
10960 genericValueTraversal(A, &getAssociatedValue());
10961
10962 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
10963 : ChangeStatus::CHANGED;
10964 }
10965
10966 /// Helper struct to remember which AAIsDead instances we actually used.
10967 struct LivenessInfo {
10968 const AAIsDead *LivenessAA = nullptr;
10969 bool AnyDead = false;
10970 };
10971
10972 /// Check if \p Cmp is a comparison we can simplify.
10973 ///
10974 /// We handle multiple cases, one in which at least one operand is an
10975 /// (assumed) nullptr. If so, try to simplify it using AANonNull on the other
10976 /// operand. Return true if successful, in that case Worklist will be updated.
10977 bool handleCmp(Attributor &A, Value &Cmp, Value *LHS, Value *RHS,
10978 CmpInst::Predicate Pred, ItemInfo II,
10979 SmallVectorImpl<ItemInfo> &Worklist) {
10980
10981 // Simplify the operands first.
10982 bool UsedAssumedInformation = false;
10983 SmallVector<AA::ValueAndContext> LHSValues, RHSValues;
10984 auto GetSimplifiedValues = [&](Value &V,
10986 if (!A.getAssumedSimplifiedValues(
10987 IRPosition::value(V, getCallBaseContext()), this, Values,
10988 AA::Intraprocedural, UsedAssumedInformation)) {
10989 Values.clear();
10990 Values.push_back(AA::ValueAndContext{V, II.I.getCtxI()});
10991 }
10992 return Values.empty();
10993 };
10994 if (GetSimplifiedValues(*LHS, LHSValues))
10995 return true;
10996 if (GetSimplifiedValues(*RHS, RHSValues))
10997 return true;
10998
10999 LLVMContext &Ctx = LHS->getContext();
11000
11001 InformationCache &InfoCache = A.getInfoCache();
11002 Instruction *CmpI = dyn_cast<Instruction>(&Cmp);
11003 Function *F = CmpI ? CmpI->getFunction() : nullptr;
11004 const auto *DT =
11006 : nullptr;
11007 const auto *TLI =
11008 F ? A.getInfoCache().getTargetLibraryInfoForFunction(*F) : nullptr;
11009 auto *AC =
11011 : nullptr;
11012
11013 const DataLayout &DL = A.getDataLayout();
11014 SimplifyQuery Q(DL, TLI, DT, AC, CmpI);
11015
11016 auto CheckPair = [&](Value &LHSV, Value &RHSV) {
11017 if (isa<UndefValue>(LHSV) || isa<UndefValue>(RHSV)) {
11018 addValue(A, getState(), *UndefValue::get(Cmp.getType()),
11019 /* CtxI */ nullptr, II.S, getAnchorScope());
11020 return true;
11021 }
11022
11023 // Handle the trivial case first in which we don't even need to think
11024 // about null or non-null.
11025 if (&LHSV == &RHSV &&
11027 Constant *NewV = ConstantInt::get(Type::getInt1Ty(Ctx),
11029 addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S,
11030 getAnchorScope());
11031 return true;
11032 }
11033
11034 auto *TypedLHS = AA::getWithType(LHSV, *LHS->getType());
11035 auto *TypedRHS = AA::getWithType(RHSV, *RHS->getType());
11036 if (TypedLHS && TypedRHS) {
11037 Value *NewV = simplifyCmpInst(Pred, TypedLHS, TypedRHS, Q);
11038 if (NewV && NewV != &Cmp) {
11039 addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S,
11040 getAnchorScope());
11041 return true;
11042 }
11043 }
11044
11045 // From now on we only handle equalities (==, !=).
11046 if (!CmpInst::isEquality(Pred))
11047 return false;
11048
11049 bool LHSIsNull = isa<ConstantPointerNull>(LHSV);
11050 bool RHSIsNull = isa<ConstantPointerNull>(RHSV);
11051 if (!LHSIsNull && !RHSIsNull)
11052 return false;
11053
11054 // Left is the nullptr ==/!= non-nullptr case. We'll use AANonNull on the
11055 // non-nullptr operand and if we assume it's non-null we can conclude the
11056 // result of the comparison.
11057 assert((LHSIsNull || RHSIsNull) &&
11058 "Expected nullptr versus non-nullptr comparison at this point");
11059
11060 // The index is the operand that we assume is not null.
11061 unsigned PtrIdx = LHSIsNull;
11062 bool IsKnownNonNull;
11063 bool IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>(
11064 A, this, IRPosition::value(*(PtrIdx ? &RHSV : &LHSV)),
11065 DepClassTy::REQUIRED, IsKnownNonNull);
11066 if (!IsAssumedNonNull)
11067 return false;
11068
11069 // The new value depends on the predicate, true for != and false for ==.
11070 Constant *NewV =
11071 ConstantInt::get(Type::getInt1Ty(Ctx), Pred == CmpInst::ICMP_NE);
11072 addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S,
11073 getAnchorScope());
11074 return true;
11075 };
11076
11077 for (auto &LHSValue : LHSValues)
11078 for (auto &RHSValue : RHSValues)
11079 if (!CheckPair(*LHSValue.getValue(), *RHSValue.getValue()))
11080 return false;
11081 return true;
11082 }
11083
11084 bool handleSelectInst(Attributor &A, SelectInst &SI, ItemInfo II,
11085 SmallVectorImpl<ItemInfo> &Worklist) {
11086 const Instruction *CtxI = II.I.getCtxI();
11087 bool UsedAssumedInformation = false;
11088
11089 std::optional<Constant *> C =
11090 A.getAssumedConstant(*SI.getCondition(), *this, UsedAssumedInformation);
11091 bool NoValueYet = !C.has_value();
11092 if (NoValueYet || isa_and_nonnull<UndefValue>(*C))
11093 return true;
11094 if (auto *CI = dyn_cast_or_null<ConstantInt>(*C)) {
11095 if (CI->isZero())
11096 Worklist.push_back({{*SI.getFalseValue(), CtxI}, II.S});
11097 else
11098 Worklist.push_back({{*SI.getTrueValue(), CtxI}, II.S});
11099 } else if (&SI == &getAssociatedValue()) {
11100 // We could not simplify the condition, assume both values.
11101 Worklist.push_back({{*SI.getTrueValue(), CtxI}, II.S});
11102 Worklist.push_back({{*SI.getFalseValue(), CtxI}, II.S});
11103 } else {
11104 std::optional<Value *> SimpleV = A.getAssumedSimplified(
11105 IRPosition::inst(SI), *this, UsedAssumedInformation, II.S);
11106 if (!SimpleV.has_value())
11107 return true;
11108 if (*SimpleV) {
11109 addValue(A, getState(), **SimpleV, CtxI, II.S, getAnchorScope());
11110 return true;
11111 }
11112 return false;
11113 }
11114 return true;
11115 }
11116
11117 bool handleLoadInst(Attributor &A, LoadInst &LI, ItemInfo II,
11118 SmallVectorImpl<ItemInfo> &Worklist) {
11119 SmallSetVector<Value *, 4> PotentialCopies;
11120 SmallSetVector<Instruction *, 4> PotentialValueOrigins;
11121 bool UsedAssumedInformation = false;
11122 if (!AA::getPotentiallyLoadedValues(A, LI, PotentialCopies,
11123 PotentialValueOrigins, *this,
11124 UsedAssumedInformation,
11125 /* OnlyExact */ true)) {
11126 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Failed to get potentially "
11127 "loaded values for load instruction "
11128 << LI << "\n");
11129 return false;
11130 }
11131
11132 // Do not simplify loads that are only used in llvm.assume if we cannot also
11133 // remove all stores that may feed into the load. The reason is that the
11134 // assume is probably worth something as long as the stores are around.
11135 InformationCache &InfoCache = A.getInfoCache();
11136 if (InfoCache.isOnlyUsedByAssume(LI)) {
11137 if (!llvm::all_of(PotentialValueOrigins, [&](Instruction *I) {
11138 if (!I || isa<AssumeInst>(I))
11139 return true;
11140 if (auto *SI = dyn_cast<StoreInst>(I))
11141 return A.isAssumedDead(SI->getOperandUse(0), this,
11142 /* LivenessAA */ nullptr,
11143 UsedAssumedInformation,
11144 /* CheckBBLivenessOnly */ false);
11145 return A.isAssumedDead(*I, this, /* LivenessAA */ nullptr,
11146 UsedAssumedInformation,
11147 /* CheckBBLivenessOnly */ false);
11148 })) {
11149 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Load is onl used by assumes "
11150 "and we cannot delete all the stores: "
11151 << LI << "\n");
11152 return false;
11153 }
11154 }
11155
11156 // Values have to be dynamically unique or we loose the fact that a
11157 // single llvm::Value might represent two runtime values (e.g.,
11158 // stack locations in different recursive calls).
11159 const Instruction *CtxI = II.I.getCtxI();
11160 bool ScopeIsLocal = (II.S & AA::Intraprocedural);
11161 bool AllLocal = ScopeIsLocal;
11162 bool DynamicallyUnique = llvm::all_of(PotentialCopies, [&](Value *PC) {
11163 AllLocal &= AA::isValidInScope(*PC, getAnchorScope());
11164 return AA::isDynamicallyUnique(A, *this, *PC);
11165 });
11166 if (!DynamicallyUnique) {
11167 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Not all potentially loaded "
11168 "values are dynamically unique: "
11169 << LI << "\n");
11170 return false;
11171 }
11172
11173 for (auto *PotentialCopy : PotentialCopies) {
11174 if (AllLocal) {
11175 Worklist.push_back({{*PotentialCopy, CtxI}, II.S});
11176 } else {
11177 Worklist.push_back({{*PotentialCopy, CtxI}, AA::Interprocedural});
11178 }
11179 }
11180 if (!AllLocal && ScopeIsLocal)
11181 addValue(A, getState(), LI, CtxI, AA::Intraprocedural, getAnchorScope());
11182 return true;
11183 }
11184
11185 bool handlePHINode(
11186 Attributor &A, PHINode &PHI, ItemInfo II,
11187 SmallVectorImpl<ItemInfo> &Worklist,
11189 auto GetLivenessInfo = [&](const Function &F) -> LivenessInfo & {
11190 LivenessInfo &LI = LivenessAAs[&F];
11191 if (!LI.LivenessAA)
11192 LI.LivenessAA = A.getAAFor<AAIsDead>(*this, IRPosition::function(F),
11193 DepClassTy::NONE);
11194 return LI;
11195 };
11196
11197 if (&PHI == &getAssociatedValue()) {
11198 LivenessInfo &LI = GetLivenessInfo(*PHI.getFunction());
11199 const auto *CI =
11200 A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>(
11201 *PHI.getFunction());
11202
11203 Cycle *C = nullptr;
11204 bool CyclePHI = mayBeInCycle(CI, &PHI, /* HeaderOnly */ true, &C);
11205 for (unsigned u = 0, e = PHI.getNumIncomingValues(); u < e; u++) {
11206 BasicBlock *IncomingBB = PHI.getIncomingBlock(u);
11207 if (LI.LivenessAA &&
11208 LI.LivenessAA->isEdgeDead(IncomingBB, PHI.getParent())) {
11209 LI.AnyDead = true;
11210 continue;
11211 }
11212 Value *V = PHI.getIncomingValue(u);
11213 if (V == &PHI)
11214 continue;
11215
11216 // If the incoming value is not the PHI but an instruction in the same
11217 // cycle we might have multiple versions of it flying around.
11218 if (CyclePHI && isa<Instruction>(V) &&
11219 (!C || C->contains(cast<Instruction>(V)->getParent())))
11220 return false;
11221
11222 Worklist.push_back({{*V, IncomingBB->getTerminator()}, II.S});
11223 }
11224 return true;
11225 }
11226
11227 bool UsedAssumedInformation = false;
11228 std::optional<Value *> SimpleV = A.getAssumedSimplified(
11229 IRPosition::inst(PHI), *this, UsedAssumedInformation, II.S);
11230 if (!SimpleV.has_value())
11231 return true;
11232 if (!(*SimpleV))
11233 return false;
11234 addValue(A, getState(), **SimpleV, &PHI, II.S, getAnchorScope());
11235 return true;
11236 }
11237
11238 /// Use the generic, non-optimistic InstSimplfy functionality if we managed to
11239 /// simplify any operand of the instruction \p I. Return true if successful,
11240 /// in that case Worklist will be updated.
11241 bool handleGenericInst(Attributor &A, Instruction &I, ItemInfo II,
11242 SmallVectorImpl<ItemInfo> &Worklist) {
11243 bool SomeSimplified = false;
11244 bool UsedAssumedInformation = false;
11245
11246 SmallVector<Value *, 8> NewOps(I.getNumOperands());
11247 int Idx = 0;
11248 for (Value *Op : I.operands()) {
11249 const auto &SimplifiedOp = A.getAssumedSimplified(
11250 IRPosition::value(*Op, getCallBaseContext()), *this,
11251 UsedAssumedInformation, AA::Intraprocedural);
11252 // If we are not sure about any operand we are not sure about the entire
11253 // instruction, we'll wait.
11254 if (!SimplifiedOp.has_value())
11255 return true;
11256
11257 if (*SimplifiedOp)
11258 NewOps[Idx] = *SimplifiedOp;
11259 else
11260 NewOps[Idx] = Op;
11261
11262 SomeSimplified |= (NewOps[Idx] != Op);
11263 ++Idx;
11264 }
11265
11266 // We won't bother with the InstSimplify interface if we didn't simplify any
11267 // operand ourselves.
11268 if (!SomeSimplified)
11269 return false;
11270
11271 InformationCache &InfoCache = A.getInfoCache();
11272 Function *F = I.getFunction();
11273 const auto *DT =
11275 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
11276 auto *AC = InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F);
11277
11278 const DataLayout &DL = I.getDataLayout();
11279 SimplifyQuery Q(DL, TLI, DT, AC, &I);
11280 Value *NewV = simplifyInstructionWithOperands(&I, NewOps, Q);
11281 if (!NewV || NewV == &I)
11282 return false;
11283
11284 LLVM_DEBUG(dbgs() << "Generic inst " << I << " assumed simplified to "
11285 << *NewV << "\n");
11286 Worklist.push_back({{*NewV, II.I.getCtxI()}, II.S});
11287 return true;
11288 }
11289
11291 Attributor &A, Instruction &I, ItemInfo II,
11292 SmallVectorImpl<ItemInfo> &Worklist,
11294 if (auto *CI = dyn_cast<CmpInst>(&I))
11295 return handleCmp(A, *CI, CI->getOperand(0), CI->getOperand(1),
11296 CI->getPredicate(), II, Worklist);
11297
11298 switch (I.getOpcode()) {
11299 case Instruction::Select:
11300 return handleSelectInst(A, cast<SelectInst>(I), II, Worklist);
11301 case Instruction::PHI:
11302 return handlePHINode(A, cast<PHINode>(I), II, Worklist, LivenessAAs);
11303 case Instruction::Load:
11304 return handleLoadInst(A, cast<LoadInst>(I), II, Worklist);
11305 default:
11306 return handleGenericInst(A, I, II, Worklist);
11307 };
11308 return false;
11309 }
11310
11311 void genericValueTraversal(Attributor &A, Value *InitialV) {
11313
11314 SmallSet<ItemInfo, 16> Visited;
11316 Worklist.push_back({{*InitialV, getCtxI()}, AA::AnyScope});
11317
11318 int Iteration = 0;
11319 do {
11320 ItemInfo II = Worklist.pop_back_val();
11321 Value *V = II.I.getValue();
11322 assert(V);
11323 const Instruction *CtxI = II.I.getCtxI();
11324 AA::ValueScope S = II.S;
11325
11326 // Check if we should process the current value. To prevent endless
11327 // recursion keep a record of the values we followed!
11328 if (!Visited.insert(II).second)
11329 continue;
11330
11331 // Make sure we limit the compile time for complex expressions.
11332 if (Iteration++ >= MaxPotentialValuesIterations) {
11333 LLVM_DEBUG(dbgs() << "Generic value traversal reached iteration limit: "
11334 << Iteration << "!\n");
11335 addValue(A, getState(), *V, CtxI, S, getAnchorScope());
11336 continue;
11337 }
11338
11339 // Explicitly look through calls with a "returned" attribute if we do
11340 // not have a pointer as stripPointerCasts only works on them.
11341 Value *NewV = nullptr;
11342 if (V->getType()->isPointerTy()) {
11343 NewV = AA::getWithType(*V->stripPointerCasts(), *V->getType());
11344 } else {
11345 if (auto *CB = dyn_cast<CallBase>(V))
11346 if (auto *Callee =
11347 dyn_cast_if_present<Function>(CB->getCalledOperand())) {
11348 for (Argument &Arg : Callee->args())
11349 if (Arg.hasReturnedAttr()) {
11350 NewV = CB->getArgOperand(Arg.getArgNo());
11351 break;
11352 }
11353 }
11354 }
11355 if (NewV && NewV != V) {
11356 Worklist.push_back({{*NewV, CtxI}, S});
11357 continue;
11358 }
11359
11360 if (auto *I = dyn_cast<Instruction>(V)) {
11361 if (simplifyInstruction(A, *I, II, Worklist, LivenessAAs))
11362 continue;
11363 }
11364
11365 if (V != InitialV || isa<Argument>(V))
11366 if (recurseForValue(A, IRPosition::value(*V), II.S))
11367 continue;
11368
11369 // If we haven't stripped anything we give up.
11370 if (V == InitialV && CtxI == getCtxI()) {
11371 indicatePessimisticFixpoint();
11372 return;
11373 }
11374
11375 addValue(A, getState(), *V, CtxI, S, getAnchorScope());
11376 } while (!Worklist.empty());
11377
11378 // If we actually used liveness information so we have to record a
11379 // dependence.
11380 for (auto &It : LivenessAAs)
11381 if (It.second.AnyDead)
11382 A.recordDependence(*It.second.LivenessAA, *this, DepClassTy::OPTIONAL);
11383 }
11384
11385 /// See AbstractAttribute::trackStatistics()
11386 void trackStatistics() const override {
11387 STATS_DECLTRACK_FLOATING_ATTR(potential_values)
11388 }
11389};
11390
11391struct AAPotentialValuesArgument final : AAPotentialValuesImpl {
11392 using Base = AAPotentialValuesImpl;
11393 AAPotentialValuesArgument(const IRPosition &IRP, Attributor &A)
11394 : Base(IRP, A) {}
11395
11396 /// See AbstractAttribute::initialize(..).
11397 void initialize(Attributor &A) override {
11398 auto &Arg = cast<Argument>(getAssociatedValue());
11400 indicatePessimisticFixpoint();
11401 }
11402
11403 /// See AbstractAttribute::updateImpl(...).
11404 ChangeStatus updateImpl(Attributor &A) override {
11405 auto AssumedBefore = getAssumed();
11406
11407 unsigned ArgNo = getCalleeArgNo();
11408
11409 bool UsedAssumedInformation = false;
11411 auto CallSitePred = [&](AbstractCallSite ACS) {
11412 const auto CSArgIRP = IRPosition::callsite_argument(ACS, ArgNo);
11413 if (CSArgIRP.getPositionKind() == IRP_INVALID)
11414 return false;
11415
11416 if (!A.getAssumedSimplifiedValues(CSArgIRP, this, Values,
11418 UsedAssumedInformation))
11419 return false;
11420
11421 return isValidState();
11422 };
11423
11424 if (!A.checkForAllCallSites(CallSitePred, *this,
11425 /* RequireAllCallSites */ true,
11426 UsedAssumedInformation))
11427 return indicatePessimisticFixpoint();
11428
11429 Function *Fn = getAssociatedFunction();
11430 bool AnyNonLocal = false;
11431 for (auto &It : Values) {
11432 if (isa<Constant>(It.getValue())) {
11433 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::AnyScope,
11434 getAnchorScope());
11435 continue;
11436 }
11437 if (!AA::isDynamicallyUnique(A, *this, *It.getValue()))
11438 return indicatePessimisticFixpoint();
11439
11440 if (auto *Arg = dyn_cast<Argument>(It.getValue()))
11441 if (Arg->getParent() == Fn) {
11442 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::AnyScope,
11443 getAnchorScope());
11444 continue;
11445 }
11446 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::Interprocedural,
11447 getAnchorScope());
11448 AnyNonLocal = true;
11449 }
11450 assert(!undefIsContained() && "Undef should be an explicit value!");
11451 if (AnyNonLocal)
11452 giveUpOnIntraprocedural(A);
11453
11454 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
11455 : ChangeStatus::CHANGED;
11456 }
11457
11458 /// See AbstractAttribute::trackStatistics()
11459 void trackStatistics() const override {
11460 STATS_DECLTRACK_ARG_ATTR(potential_values)
11461 }
11462};
11463
11464struct AAPotentialValuesReturned : public AAPotentialValuesFloating {
11465 using Base = AAPotentialValuesFloating;
11466 AAPotentialValuesReturned(const IRPosition &IRP, Attributor &A)
11467 : Base(IRP, A) {}
11468
11469 /// See AbstractAttribute::initialize(..).
11470 void initialize(Attributor &A) override {
11471 Function *F = getAssociatedFunction();
11472 if (!F || F->isDeclaration() || F->getReturnType()->isVoidTy()) {
11473 indicatePessimisticFixpoint();
11474 return;
11475 }
11476
11477 for (Argument &Arg : F->args())
11478 if (Arg.hasReturnedAttr()) {
11479 addValue(A, getState(), Arg, nullptr, AA::AnyScope, F);
11480 ReturnedArg = &Arg;
11481 break;
11482 }
11483 if (!A.isFunctionIPOAmendable(*F) ||
11484 A.hasSimplificationCallback(getIRPosition())) {
11485 if (!ReturnedArg)
11486 indicatePessimisticFixpoint();
11487 else
11488 indicateOptimisticFixpoint();
11489 }
11490 }
11491
11492 /// See AbstractAttribute::updateImpl(...).
11493 ChangeStatus updateImpl(Attributor &A) override {
11494 auto AssumedBefore = getAssumed();
11495 bool UsedAssumedInformation = false;
11496
11498 Function *AnchorScope = getAnchorScope();
11499 auto HandleReturnedValue = [&](Value &V, Instruction *CtxI,
11500 bool AddValues) {
11502 Values.clear();
11503 if (!A.getAssumedSimplifiedValues(IRPosition::value(V), this, Values, S,
11504 UsedAssumedInformation,
11505 /* RecurseForSelectAndPHI */ true))
11506 return false;
11507 if (!AddValues)
11508 continue;
11509 for (const AA::ValueAndContext &VAC : Values)
11510 addValue(A, getState(), *VAC.getValue(),
11511 VAC.getCtxI() ? VAC.getCtxI() : CtxI, S, AnchorScope);
11512 }
11513 return true;
11514 };
11515
11516 if (ReturnedArg) {
11517 HandleReturnedValue(*ReturnedArg, nullptr, true);
11518 } else {
11519 auto RetInstPred = [&](Instruction &RetI) {
11520 bool AddValues = true;
11521 if (isa<PHINode>(RetI.getOperand(0)) ||
11522 isa<SelectInst>(RetI.getOperand(0))) {
11523 addValue(A, getState(), *RetI.getOperand(0), &RetI, AA::AnyScope,
11524 AnchorScope);
11525 AddValues = false;
11526 }
11527 return HandleReturnedValue(*RetI.getOperand(0), &RetI, AddValues);
11528 };
11529
11530 if (!A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret},
11531 UsedAssumedInformation,
11532 /* CheckBBLivenessOnly */ true))
11533 return indicatePessimisticFixpoint();
11534 }
11535
11536 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
11537 : ChangeStatus::CHANGED;
11538 }
11539
11540 void addValue(Attributor &A, StateType &State, Value &V,
11541 const Instruction *CtxI, AA::ValueScope S,
11542 Function *AnchorScope) const override {
11543 Function *F = getAssociatedFunction();
11544 if (auto *CB = dyn_cast<CallBase>(&V))
11545 if (CB->getCalledOperand() == F)
11546 return;
11547 Base::addValue(A, State, V, CtxI, S, AnchorScope);
11548 }
11549
11550 ChangeStatus manifest(Attributor &A) override {
11551 if (ReturnedArg)
11552 return ChangeStatus::UNCHANGED;
11554 if (!getAssumedSimplifiedValues(A, Values, AA::ValueScope::Intraprocedural,
11555 /* RecurseForSelectAndPHI */ true))
11556 return ChangeStatus::UNCHANGED;
11557 Value *NewVal = getSingleValue(A, *this, getIRPosition(), Values);
11558 if (!NewVal)
11559 return ChangeStatus::UNCHANGED;
11560
11561 ChangeStatus Changed = ChangeStatus::UNCHANGED;
11562 if (auto *Arg = dyn_cast<Argument>(NewVal)) {
11563 STATS_DECLTRACK(UniqueReturnValue, FunctionReturn,
11564 "Number of function with unique return");
11565 Changed |= A.manifestAttrs(
11567 {Attribute::get(Arg->getContext(), Attribute::Returned)});
11568 STATS_DECLTRACK_ARG_ATTR(returned);
11569 }
11570
11571 auto RetInstPred = [&](Instruction &RetI) {
11572 Value *RetOp = RetI.getOperand(0);
11573 if (isa<UndefValue>(RetOp) || RetOp == NewVal)
11574 return true;
11575 if (AA::isValidAtPosition({*NewVal, RetI}, A.getInfoCache()))
11576 if (A.changeUseAfterManifest(RetI.getOperandUse(0), *NewVal))
11577 Changed = ChangeStatus::CHANGED;
11578 return true;
11579 };
11580 bool UsedAssumedInformation = false;
11581 (void)A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret},
11582 UsedAssumedInformation,
11583 /* CheckBBLivenessOnly */ true);
11584 return Changed;
11585 }
11586
11587 ChangeStatus indicatePessimisticFixpoint() override {
11589 }
11590
11591 /// See AbstractAttribute::trackStatistics()
11592 void trackStatistics() const override{
11593 STATS_DECLTRACK_FNRET_ATTR(potential_values)}
11594
11595 /// The argumented with an existing `returned` attribute.
11596 Argument *ReturnedArg = nullptr;
11597};
11598
11599struct AAPotentialValuesFunction : AAPotentialValuesImpl {
11600 AAPotentialValuesFunction(const IRPosition &IRP, Attributor &A)
11601 : AAPotentialValuesImpl(IRP, A) {}
11602
11603 /// See AbstractAttribute::updateImpl(...).
11604 ChangeStatus updateImpl(Attributor &A) override {
11605 llvm_unreachable("AAPotentialValues(Function|CallSite)::updateImpl will "
11606 "not be called");
11607 }
11608
11609 /// See AbstractAttribute::trackStatistics()
11610 void trackStatistics() const override {
11611 STATS_DECLTRACK_FN_ATTR(potential_values)
11612 }
11613};
11614
11615struct AAPotentialValuesCallSite : AAPotentialValuesFunction {
11616 AAPotentialValuesCallSite(const IRPosition &IRP, Attributor &A)
11617 : AAPotentialValuesFunction(IRP, A) {}
11618
11619 /// See AbstractAttribute::trackStatistics()
11620 void trackStatistics() const override {
11621 STATS_DECLTRACK_CS_ATTR(potential_values)
11622 }
11623};
11624
11625struct AAPotentialValuesCallSiteReturned : AAPotentialValuesImpl {
11626 AAPotentialValuesCallSiteReturned(const IRPosition &IRP, Attributor &A)
11627 : AAPotentialValuesImpl(IRP, A) {}
11628
11629 /// See AbstractAttribute::updateImpl(...).
11630 ChangeStatus updateImpl(Attributor &A) override {
11631 auto AssumedBefore = getAssumed();
11632
11633 Function *Callee = getAssociatedFunction();
11634 if (!Callee)
11635 return indicatePessimisticFixpoint();
11636
11637 bool UsedAssumedInformation = false;
11638 auto *CB = cast<CallBase>(getCtxI());
11639 if (CB->isMustTailCall() &&
11640 !A.isAssumedDead(IRPosition::inst(*CB), this, nullptr,
11641 UsedAssumedInformation))
11642 return indicatePessimisticFixpoint();
11643
11645 if (!A.getAssumedSimplifiedValues(IRPosition::returned(*Callee), this,
11646 Values, AA::Intraprocedural,
11647 UsedAssumedInformation))
11648 return indicatePessimisticFixpoint();
11649
11650 Function *Caller = CB->getCaller();
11651
11652 bool AnyNonLocal = false;
11653 for (auto &It : Values) {
11654 Value *V = It.getValue();
11655 std::optional<Value *> CallerV = A.translateArgumentToCallSiteContent(
11656 V, *CB, *this, UsedAssumedInformation);
11657 if (!CallerV.has_value()) {
11658 // Nothing to do as long as no value was determined.
11659 continue;
11660 }
11661 V = *CallerV ? *CallerV : V;
11662 if (AA::isDynamicallyUnique(A, *this, *V) &&
11663 AA::isValidInScope(*V, Caller)) {
11664 if (*CallerV) {
11666 IRPosition IRP = IRPosition::value(*V);
11667 if (auto *Arg = dyn_cast<Argument>(V))
11668 if (Arg->getParent() == CB->getCalledOperand())
11669 IRP = IRPosition::callsite_argument(*CB, Arg->getArgNo());
11670 if (recurseForValue(A, IRP, AA::AnyScope))
11671 continue;
11672 }
11673 addValue(A, getState(), *V, CB, AA::AnyScope, getAnchorScope());
11674 } else {
11675 AnyNonLocal = true;
11676 break;
11677 }
11678 }
11679 if (AnyNonLocal) {
11680 Values.clear();
11681 if (!A.getAssumedSimplifiedValues(IRPosition::returned(*Callee), this,
11682 Values, AA::Interprocedural,
11683 UsedAssumedInformation))
11684 return indicatePessimisticFixpoint();
11685 AnyNonLocal = false;
11687 for (auto &It : Values) {
11688 Value *V = It.getValue();
11689 if (!AA::isDynamicallyUnique(A, *this, *V))
11690 return indicatePessimisticFixpoint();
11691 if (AA::isValidInScope(*V, Caller)) {
11692 addValue(A, getState(), *V, CB, AA::AnyScope, getAnchorScope());
11693 } else {
11694 AnyNonLocal = true;
11695 addValue(A, getState(), *V, CB, AA::Interprocedural,
11696 getAnchorScope());
11697 }
11698 }
11699 if (AnyNonLocal)
11700 giveUpOnIntraprocedural(A);
11701 }
11702 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
11703 : ChangeStatus::CHANGED;
11704 }
11705
11706 ChangeStatus indicatePessimisticFixpoint() override {
11707 return AAPotentialValues::indicatePessimisticFixpoint();
11708 }
11709
11710 /// See AbstractAttribute::trackStatistics()
11711 void trackStatistics() const override {
11712 STATS_DECLTRACK_CSRET_ATTR(potential_values)
11713 }
11714};
11715
11716struct AAPotentialValuesCallSiteArgument : AAPotentialValuesFloating {
11717 AAPotentialValuesCallSiteArgument(const IRPosition &IRP, Attributor &A)
11718 : AAPotentialValuesFloating(IRP, A) {}
11719
11720 /// See AbstractAttribute::trackStatistics()
11721 void trackStatistics() const override {
11722 STATS_DECLTRACK_CSARG_ATTR(potential_values)
11723 }
11724};
11725} // namespace
11726
11727/// ---------------------- Assumption Propagation ------------------------------
11728namespace {
11729struct AAAssumptionInfoImpl : public AAAssumptionInfo {
11730 AAAssumptionInfoImpl(const IRPosition &IRP, Attributor &A,
11731 const DenseSet<StringRef> &Known)
11732 : AAAssumptionInfo(IRP, A, Known) {}
11733
11734 /// See AbstractAttribute::manifest(...).
11735 ChangeStatus manifest(Attributor &A) override {
11736 // Don't manifest a universal set if it somehow made it here.
11737 if (getKnown().isUniversal())
11738 return ChangeStatus::UNCHANGED;
11739
11740 const IRPosition &IRP = getIRPosition();
11741 SmallVector<StringRef, 0> Set(getAssumed().getSet().begin(),
11742 getAssumed().getSet().end());
11743 llvm::sort(Set);
11744 return A.manifestAttrs(IRP,
11747 llvm::join(Set, ",")),
11748 /*ForceReplace=*/true);
11749 }
11750
11751 bool hasAssumption(const StringRef Assumption) const override {
11752 return isValidState() && setContains(Assumption);
11753 }
11754
11755 /// See AbstractAttribute::getAsStr()
11756 const std::string getAsStr(Attributor *A) const override {
11757 const SetContents &Known = getKnown();
11758 const SetContents &Assumed = getAssumed();
11759
11760 SmallVector<StringRef, 0> Set(Known.getSet().begin(), Known.getSet().end());
11761 llvm::sort(Set);
11762 const std::string KnownStr = llvm::join(Set, ",");
11763
11764 std::string AssumedStr = "Universal";
11765 if (!Assumed.isUniversal()) {
11766 Set.assign(Assumed.getSet().begin(), Assumed.getSet().end());
11767 AssumedStr = llvm::join(Set, ",");
11768 }
11769 return "Known [" + KnownStr + "]," + " Assumed [" + AssumedStr + "]";
11770 }
11771};
11772
11773/// Propagates assumption information from parent functions to all of their
11774/// successors. An assumption can be propagated if the containing function
11775/// dominates the called function.
11776///
11777/// We start with a "known" set of assumptions already valid for the associated
11778/// function and an "assumed" set that initially contains all possible
11779/// assumptions. The assumed set is inter-procedurally updated by narrowing its
11780/// contents as concrete values are known. The concrete values are seeded by the
11781/// first nodes that are either entries into the call graph, or contains no
11782/// assumptions. Each node is updated as the intersection of the assumed state
11783/// with all of its predecessors.
11784struct AAAssumptionInfoFunction final : AAAssumptionInfoImpl {
11785 AAAssumptionInfoFunction(const IRPosition &IRP, Attributor &A)
11786 : AAAssumptionInfoImpl(IRP, A,
11787 getAssumptions(*IRP.getAssociatedFunction())) {}
11788
11789 /// See AbstractAttribute::updateImpl(...).
11790 ChangeStatus updateImpl(Attributor &A) override {
11791 bool Changed = false;
11792
11793 auto CallSitePred = [&](AbstractCallSite ACS) {
11794 const auto *AssumptionAA = A.getAAFor<AAAssumptionInfo>(
11795 *this, IRPosition::callsite_function(*ACS.getInstruction()),
11796 DepClassTy::REQUIRED);
11797 if (!AssumptionAA)
11798 return false;
11799 // Get the set of assumptions shared by all of this function's callers.
11800 Changed |= getIntersection(AssumptionAA->getAssumed());
11801 return !getAssumed().empty() || !getKnown().empty();
11802 };
11803
11804 bool UsedAssumedInformation = false;
11805 // Get the intersection of all assumptions held by this node's predecessors.
11806 // If we don't know all the call sites then this is either an entry into the
11807 // call graph or an empty node. This node is known to only contain its own
11808 // assumptions and can be propagated to its successors.
11809 if (!A.checkForAllCallSites(CallSitePred, *this, true,
11810 UsedAssumedInformation))
11811 return indicatePessimisticFixpoint();
11812
11813 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
11814 }
11815
11816 void trackStatistics() const override {}
11817};
11818
11819/// Assumption Info defined for call sites.
11820struct AAAssumptionInfoCallSite final : AAAssumptionInfoImpl {
11821
11822 AAAssumptionInfoCallSite(const IRPosition &IRP, Attributor &A)
11823 : AAAssumptionInfoImpl(IRP, A, getInitialAssumptions(IRP)) {}
11824
11825 /// See AbstractAttribute::initialize(...).
11826 void initialize(Attributor &A) override {
11827 const IRPosition &FnPos = IRPosition::function(*getAnchorScope());
11828 A.getAAFor<AAAssumptionInfo>(*this, FnPos, DepClassTy::REQUIRED);
11829 }
11830
11831 /// See AbstractAttribute::updateImpl(...).
11832 ChangeStatus updateImpl(Attributor &A) override {
11833 const IRPosition &FnPos = IRPosition::function(*getAnchorScope());
11834 auto *AssumptionAA =
11835 A.getAAFor<AAAssumptionInfo>(*this, FnPos, DepClassTy::REQUIRED);
11836 if (!AssumptionAA)
11837 return indicatePessimisticFixpoint();
11838 bool Changed = getIntersection(AssumptionAA->getAssumed());
11839 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
11840 }
11841
11842 /// See AbstractAttribute::trackStatistics()
11843 void trackStatistics() const override {}
11844
11845private:
11846 /// Helper to initialized the known set as all the assumptions this call and
11847 /// the callee contain.
11848 DenseSet<StringRef> getInitialAssumptions(const IRPosition &IRP) {
11849 const CallBase &CB = cast<CallBase>(IRP.getAssociatedValue());
11850 auto Assumptions = getAssumptions(CB);
11851 if (const Function *F = CB.getCaller())
11852 set_union(Assumptions, getAssumptions(*F));
11853 if (Function *F = IRP.getAssociatedFunction())
11854 set_union(Assumptions, getAssumptions(*F));
11855 return Assumptions;
11856 }
11857};
11858} // namespace
11859
11861 return static_cast<AACallGraphNode *>(const_cast<AACallEdges *>(
11862 A.getOrCreateAAFor<AACallEdges>(IRPosition::function(**I))));
11863}
11864
11866
11867/// ------------------------ UnderlyingObjects ---------------------------------
11868
11869namespace {
11870struct AAUnderlyingObjectsImpl
11871 : StateWrapper<BooleanState, AAUnderlyingObjects> {
11873 AAUnderlyingObjectsImpl(const IRPosition &IRP, Attributor &A) : BaseTy(IRP) {}
11874
11875 /// See AbstractAttribute::getAsStr().
11876 const std::string getAsStr(Attributor *A) const override {
11877 return std::string("UnderlyingObjects ") +
11878 (isValidState()
11879 ? (std::string("inter #") +
11880 std::to_string(InterAssumedUnderlyingObjects.size()) +
11881 " objs" + std::string(", intra #") +
11882 std::to_string(IntraAssumedUnderlyingObjects.size()) +
11883 " objs")
11884 : "<invalid>");
11885 }
11886
11887 /// See AbstractAttribute::trackStatistics()
11888 void trackStatistics() const override {}
11889
11890 /// See AbstractAttribute::updateImpl(...).
11891 ChangeStatus updateImpl(Attributor &A) override {
11892 auto &Ptr = getAssociatedValue();
11893
11894 auto DoUpdate = [&](SmallSetVector<Value *, 8> &UnderlyingObjects,
11896 bool UsedAssumedInformation = false;
11897 SmallPtrSet<Value *, 8> SeenObjects;
11899
11900 if (!A.getAssumedSimplifiedValues(IRPosition::value(Ptr), *this, Values,
11901 Scope, UsedAssumedInformation))
11902 return UnderlyingObjects.insert(&Ptr);
11903
11904 bool Changed = false;
11905
11906 for (unsigned I = 0; I < Values.size(); ++I) {
11907 auto &VAC = Values[I];
11908 auto *Obj = VAC.getValue();
11909 Value *UO = getUnderlyingObject(Obj);
11910 if (UO && UO != VAC.getValue() && SeenObjects.insert(UO).second) {
11911 const auto *OtherAA = A.getAAFor<AAUnderlyingObjects>(
11912 *this, IRPosition::value(*UO), DepClassTy::OPTIONAL);
11913 auto Pred = [&Values](Value &V) {
11914 Values.emplace_back(V, nullptr);
11915 return true;
11916 };
11917
11918 if (!OtherAA || !OtherAA->forallUnderlyingObjects(Pred, Scope))
11920 "The forall call should not return false at this position");
11921
11922 continue;
11923 }
11924
11925 if (isa<SelectInst>(Obj)) {
11926 Changed |= handleIndirect(A, *Obj, UnderlyingObjects, Scope);
11927 continue;
11928 }
11929 if (auto *PHI = dyn_cast<PHINode>(Obj)) {
11930 // Explicitly look through PHIs as we do not care about dynamically
11931 // uniqueness.
11932 for (unsigned u = 0, e = PHI->getNumIncomingValues(); u < e; u++) {
11933 Changed |= handleIndirect(A, *PHI->getIncomingValue(u),
11934 UnderlyingObjects, Scope);
11935 }
11936 continue;
11937 }
11938
11939 Changed |= UnderlyingObjects.insert(Obj);
11940 }
11941
11942 return Changed;
11943 };
11944
11945 bool Changed = false;
11946 Changed |= DoUpdate(IntraAssumedUnderlyingObjects, AA::Intraprocedural);
11947 Changed |= DoUpdate(InterAssumedUnderlyingObjects, AA::Interprocedural);
11948
11949 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
11950 }
11951
11952 bool forallUnderlyingObjects(
11953 function_ref<bool(Value &)> Pred,
11954 AA::ValueScope Scope = AA::Interprocedural) const override {
11955 if (!isValidState())
11956 return Pred(getAssociatedValue());
11957
11958 auto &AssumedUnderlyingObjects = Scope == AA::Intraprocedural
11959 ? IntraAssumedUnderlyingObjects
11960 : InterAssumedUnderlyingObjects;
11961 for (Value *Obj : AssumedUnderlyingObjects)
11962 if (!Pred(*Obj))
11963 return false;
11964
11965 return true;
11966 }
11967
11968private:
11969 /// Handle the case where the value is not the actual underlying value, such
11970 /// as a phi node or a select instruction.
11971 bool handleIndirect(Attributor &A, Value &V,
11972 SmallSetVector<Value *, 8> &UnderlyingObjects,
11973 AA::ValueScope Scope) {
11974 bool Changed = false;
11975 const auto *AA = A.getAAFor<AAUnderlyingObjects>(
11976 *this, IRPosition::value(V), DepClassTy::OPTIONAL);
11977 auto Pred = [&](Value &V) {
11978 Changed |= UnderlyingObjects.insert(&V);
11979 return true;
11980 };
11981 if (!AA || !AA->forallUnderlyingObjects(Pred, Scope))
11983 "The forall call should not return false at this position");
11984 return Changed;
11985 }
11986
11987 /// All the underlying objects collected so far via intra procedural scope.
11988 SmallSetVector<Value *, 8> IntraAssumedUnderlyingObjects;
11989 /// All the underlying objects collected so far via inter procedural scope.
11990 SmallSetVector<Value *, 8> InterAssumedUnderlyingObjects;
11991};
11992
11993struct AAUnderlyingObjectsFloating final : AAUnderlyingObjectsImpl {
11994 AAUnderlyingObjectsFloating(const IRPosition &IRP, Attributor &A)
11995 : AAUnderlyingObjectsImpl(IRP, A) {}
11996};
11997
11998struct AAUnderlyingObjectsArgument final : AAUnderlyingObjectsImpl {
11999 AAUnderlyingObjectsArgument(const IRPosition &IRP, Attributor &A)
12000 : AAUnderlyingObjectsImpl(IRP, A) {}
12001};
12002
12003struct AAUnderlyingObjectsCallSite final : AAUnderlyingObjectsImpl {
12004 AAUnderlyingObjectsCallSite(const IRPosition &IRP, Attributor &A)
12005 : AAUnderlyingObjectsImpl(IRP, A) {}
12006};
12007
12008struct AAUnderlyingObjectsCallSiteArgument final : AAUnderlyingObjectsImpl {
12009 AAUnderlyingObjectsCallSiteArgument(const IRPosition &IRP, Attributor &A)
12010 : AAUnderlyingObjectsImpl(IRP, A) {}
12011};
12012
12013struct AAUnderlyingObjectsReturned final : AAUnderlyingObjectsImpl {
12014 AAUnderlyingObjectsReturned(const IRPosition &IRP, Attributor &A)
12015 : AAUnderlyingObjectsImpl(IRP, A) {}
12016};
12017
12018struct AAUnderlyingObjectsCallSiteReturned final : AAUnderlyingObjectsImpl {
12019 AAUnderlyingObjectsCallSiteReturned(const IRPosition &IRP, Attributor &A)
12020 : AAUnderlyingObjectsImpl(IRP, A) {}
12021};
12022
12023struct AAUnderlyingObjectsFunction final : AAUnderlyingObjectsImpl {
12024 AAUnderlyingObjectsFunction(const IRPosition &IRP, Attributor &A)
12025 : AAUnderlyingObjectsImpl(IRP, A) {}
12026};
12027} // namespace
12028
12029/// ------------------------ Global Value Info -------------------------------
12030namespace {
12031struct AAGlobalValueInfoFloating : public AAGlobalValueInfo {
12032 AAGlobalValueInfoFloating(const IRPosition &IRP, Attributor &A)
12033 : AAGlobalValueInfo(IRP, A) {}
12034
12035 /// See AbstractAttribute::initialize(...).
12036 void initialize(Attributor &A) override {}
12037
12038 bool checkUse(Attributor &A, const Use &U, bool &Follow,
12040 Instruction *UInst = dyn_cast<Instruction>(U.getUser());
12041 if (!UInst) {
12042 Follow = true;
12043 return true;
12044 }
12045
12046 LLVM_DEBUG(dbgs() << "[AAGlobalValueInfo] Check use: " << *U.get() << " in "
12047 << *UInst << "\n");
12048
12049 if (auto *Cmp = dyn_cast<ICmpInst>(U.getUser())) {
12050 int Idx = &Cmp->getOperandUse(0) == &U;
12051 if (isa<Constant>(Cmp->getOperand(Idx)))
12052 return true;
12053 return U == &getAnchorValue();
12054 }
12055
12056 // Explicitly catch return instructions.
12057 if (isa<ReturnInst>(UInst)) {
12058 auto CallSitePred = [&](AbstractCallSite ACS) {
12059 Worklist.push_back(ACS.getInstruction());
12060 return true;
12061 };
12062 bool UsedAssumedInformation = false;
12063 // TODO: We should traverse the uses or add a "non-call-site" CB.
12064 if (!A.checkForAllCallSites(CallSitePred, *UInst->getFunction(),
12065 /*RequireAllCallSites=*/true, this,
12066 UsedAssumedInformation))
12067 return false;
12068 return true;
12069 }
12070
12071 // For now we only use special logic for call sites. However, the tracker
12072 // itself knows about a lot of other non-capturing cases already.
12073 auto *CB = dyn_cast<CallBase>(UInst);
12074 if (!CB)
12075 return false;
12076 // Direct calls are OK uses.
12077 if (CB->isCallee(&U))
12078 return true;
12079 // Non-argument uses are scary.
12080 if (!CB->isArgOperand(&U))
12081 return false;
12082 // TODO: Iterate callees.
12083 auto *Fn = dyn_cast<Function>(CB->getCalledOperand());
12084 if (!Fn || !A.isFunctionIPOAmendable(*Fn))
12085 return false;
12086
12087 unsigned ArgNo = CB->getArgOperandNo(&U);
12088 Worklist.push_back(Fn->getArg(ArgNo));
12089 return true;
12090 }
12091
12092 ChangeStatus updateImpl(Attributor &A) override {
12093 unsigned NumUsesBefore = Uses.size();
12094
12097 Worklist.push_back(&getAnchorValue());
12098
12099 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
12100 Uses.insert(&U);
12101 switch (DetermineUseCaptureKind(U, nullptr)) {
12102 case UseCaptureKind::NO_CAPTURE:
12103 return checkUse(A, U, Follow, Worklist);
12104 case UseCaptureKind::MAY_CAPTURE:
12105 return checkUse(A, U, Follow, Worklist);
12106 case UseCaptureKind::PASSTHROUGH:
12107 Follow = true;
12108 return true;
12109 }
12110 return true;
12111 };
12112 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) {
12113 Uses.insert(&OldU);
12114 return true;
12115 };
12116
12117 while (!Worklist.empty()) {
12118 const Value *V = Worklist.pop_back_val();
12119 if (!Visited.insert(V).second)
12120 continue;
12121 if (!A.checkForAllUses(UsePred, *this, *V,
12122 /* CheckBBLivenessOnly */ true,
12123 DepClassTy::OPTIONAL,
12124 /* IgnoreDroppableUses */ true, EquivalentUseCB)) {
12125 return indicatePessimisticFixpoint();
12126 }
12127 }
12128
12129 return Uses.size() == NumUsesBefore ? ChangeStatus::UNCHANGED
12130 : ChangeStatus::CHANGED;
12131 }
12132
12133 bool isPotentialUse(const Use &U) const override {
12134 return !isValidState() || Uses.contains(&U);
12135 }
12136
12137 /// See AbstractAttribute::manifest(...).
12138 ChangeStatus manifest(Attributor &A) override {
12139 return ChangeStatus::UNCHANGED;
12140 }
12141
12142 /// See AbstractAttribute::getAsStr().
12143 const std::string getAsStr(Attributor *A) const override {
12144 return "[" + std::to_string(Uses.size()) + " uses]";
12145 }
12146
12147 void trackStatistics() const override {
12148 STATS_DECLTRACK_FLOATING_ATTR(GlobalValuesTracked);
12149 }
12150
12151private:
12152 /// Set of (transitive) uses of this GlobalValue.
12154};
12155} // namespace
12156
12157/// ------------------------ Indirect Call Info -------------------------------
12158namespace {
12159struct AAIndirectCallInfoCallSite : public AAIndirectCallInfo {
12160 AAIndirectCallInfoCallSite(const IRPosition &IRP, Attributor &A)
12161 : AAIndirectCallInfo(IRP, A) {}
12162
12163 /// See AbstractAttribute::initialize(...).
12164 void initialize(Attributor &A) override {
12165 auto *MD = getCtxI()->getMetadata(LLVMContext::MD_callees);
12166 if (!MD && !A.isClosedWorldModule())
12167 return;
12168
12169 if (MD) {
12170 for (const auto &Op : MD->operands())
12171 if (Function *Callee = mdconst::dyn_extract_or_null<Function>(Op))
12172 PotentialCallees.insert(Callee);
12173 } else if (A.isClosedWorldModule()) {
12174 ArrayRef<Function *> IndirectlyCallableFunctions =
12175 A.getInfoCache().getIndirectlyCallableFunctions(A);
12176 PotentialCallees.insert(IndirectlyCallableFunctions.begin(),
12177 IndirectlyCallableFunctions.end());
12178 }
12179
12180 if (PotentialCallees.empty())
12181 indicateOptimisticFixpoint();
12182 }
12183
12184 ChangeStatus updateImpl(Attributor &A) override {
12185 CallBase *CB = cast<CallBase>(getCtxI());
12186 const Use &CalleeUse = CB->getCalledOperandUse();
12187 Value *FP = CB->getCalledOperand();
12188
12189 SmallSetVector<Function *, 4> AssumedCalleesNow;
12190 bool AllCalleesKnownNow = AllCalleesKnown;
12191
12192 auto CheckPotentialCalleeUse = [&](Function &PotentialCallee,
12193 bool &UsedAssumedInformation) {
12194 const auto *GIAA = A.getAAFor<AAGlobalValueInfo>(
12195 *this, IRPosition::value(PotentialCallee), DepClassTy::OPTIONAL);
12196 if (!GIAA || GIAA->isPotentialUse(CalleeUse))
12197 return true;
12198 UsedAssumedInformation = !GIAA->isAtFixpoint();
12199 return false;
12200 };
12201
12202 auto AddPotentialCallees = [&]() {
12203 for (auto *PotentialCallee : PotentialCallees) {
12204 bool UsedAssumedInformation = false;
12205 if (CheckPotentialCalleeUse(*PotentialCallee, UsedAssumedInformation))
12206 AssumedCalleesNow.insert(PotentialCallee);
12207 }
12208 };
12209
12210 // Use simplification to find potential callees, if !callees was present,
12211 // fallback to that set if necessary.
12212 bool UsedAssumedInformation = false;
12214 if (!A.getAssumedSimplifiedValues(IRPosition::value(*FP), this, Values,
12215 AA::ValueScope::AnyScope,
12216 UsedAssumedInformation)) {
12217 if (PotentialCallees.empty())
12218 return indicatePessimisticFixpoint();
12219 AddPotentialCallees();
12220 }
12221
12222 // Try to find a reason for \p Fn not to be a potential callee. If none was
12223 // found, add it to the assumed callees set.
12224 auto CheckPotentialCallee = [&](Function &Fn) {
12225 if (!PotentialCallees.empty() && !PotentialCallees.count(&Fn))
12226 return false;
12227
12228 auto &CachedResult = FilterResults[&Fn];
12229 if (CachedResult.has_value())
12230 return CachedResult.value();
12231
12232 bool UsedAssumedInformation = false;
12233 if (!CheckPotentialCalleeUse(Fn, UsedAssumedInformation)) {
12234 if (!UsedAssumedInformation)
12235 CachedResult = false;
12236 return false;
12237 }
12238
12239 int NumFnArgs = Fn.arg_size();
12240 int NumCBArgs = CB->arg_size();
12241
12242 // Check if any excess argument (which we fill up with poison) is known to
12243 // be UB on undef.
12244 for (int I = NumCBArgs; I < NumFnArgs; ++I) {
12245 bool IsKnown = false;
12246 if (AA::hasAssumedIRAttr<Attribute::NoUndef>(
12247 A, this, IRPosition::argument(*Fn.getArg(I)),
12248 DepClassTy::OPTIONAL, IsKnown)) {
12249 if (IsKnown)
12250 CachedResult = false;
12251 return false;
12252 }
12253 }
12254
12255 CachedResult = true;
12256 return true;
12257 };
12258
12259 // Check simplification result, prune known UB callees, also restrict it to
12260 // the !callees set, if present.
12261 for (auto &VAC : Values) {
12262 if (isa<UndefValue>(VAC.getValue()))
12263 continue;
12264 if (isa<ConstantPointerNull>(VAC.getValue()) &&
12265 VAC.getValue()->getType()->getPointerAddressSpace() == 0)
12266 continue;
12267 // TODO: Check for known UB, e.g., poison + noundef.
12268 if (auto *VACFn = dyn_cast<Function>(VAC.getValue())) {
12269 if (CheckPotentialCallee(*VACFn))
12270 AssumedCalleesNow.insert(VACFn);
12271 continue;
12272 }
12273 if (!PotentialCallees.empty()) {
12274 AddPotentialCallees();
12275 break;
12276 }
12277 AllCalleesKnownNow = false;
12278 }
12279
12280 if (AssumedCalleesNow == AssumedCallees &&
12281 AllCalleesKnown == AllCalleesKnownNow)
12282 return ChangeStatus::UNCHANGED;
12283
12284 std::swap(AssumedCallees, AssumedCalleesNow);
12285 AllCalleesKnown = AllCalleesKnownNow;
12286 return ChangeStatus::CHANGED;
12287 }
12288
12289 /// See AbstractAttribute::manifest(...).
12290 ChangeStatus manifest(Attributor &A) override {
12291 // If we can't specialize at all, give up now.
12292 if (!AllCalleesKnown && AssumedCallees.empty())
12293 return ChangeStatus::UNCHANGED;
12294
12295 CallBase *CB = cast<CallBase>(getCtxI());
12296 bool UsedAssumedInformation = false;
12297 if (A.isAssumedDead(*CB, this, /*LivenessAA=*/nullptr,
12298 UsedAssumedInformation))
12299 return ChangeStatus::UNCHANGED;
12300
12301 ChangeStatus Changed = ChangeStatus::UNCHANGED;
12302 Value *FP = CB->getCalledOperand();
12303 if (FP->getType()->getPointerAddressSpace())
12304 FP = new AddrSpaceCastInst(FP, PointerType::get(FP->getType(), 0),
12305 FP->getName() + ".as0", CB->getIterator());
12306
12307 bool CBIsVoid = CB->getType()->isVoidTy();
12309 FunctionType *CSFT = CB->getFunctionType();
12310 SmallVector<Value *> CSArgs(CB->arg_begin(), CB->arg_end());
12311
12312 // If we know all callees and there are none, the call site is (effectively)
12313 // dead (or UB).
12314 if (AssumedCallees.empty()) {
12315 assert(AllCalleesKnown &&
12316 "Expected all callees to be known if there are none.");
12317 A.changeToUnreachableAfterManifest(CB);
12318 return ChangeStatus::CHANGED;
12319 }
12320
12321 // Special handling for the single callee case.
12322 if (AllCalleesKnown && AssumedCallees.size() == 1) {
12323 auto *NewCallee = AssumedCallees.front();
12324 if (isLegalToPromote(*CB, NewCallee)) {
12325 promoteCall(*CB, NewCallee, nullptr);
12326 return ChangeStatus::CHANGED;
12327 }
12328 Instruction *NewCall =
12329 CallInst::Create(FunctionCallee(CSFT, NewCallee), CSArgs,
12330 CB->getName(), CB->getIterator());
12331 if (!CBIsVoid)
12332 A.changeAfterManifest(IRPosition::callsite_returned(*CB), *NewCall);
12333 A.deleteAfterManifest(*CB);
12334 return ChangeStatus::CHANGED;
12335 }
12336
12337 // For each potential value we create a conditional
12338 //
12339 // ```
12340 // if (ptr == value) value(args);
12341 // else ...
12342 // ```
12343 //
12344 bool SpecializedForAnyCallees = false;
12345 bool SpecializedForAllCallees = AllCalleesKnown;
12346 ICmpInst *LastCmp = nullptr;
12347 SmallVector<Function *, 8> SkippedAssumedCallees;
12349 for (Function *NewCallee : AssumedCallees) {
12350 if (!A.shouldSpecializeCallSiteForCallee(*this, *CB, *NewCallee)) {
12351 SkippedAssumedCallees.push_back(NewCallee);
12352 SpecializedForAllCallees = false;
12353 continue;
12354 }
12355 SpecializedForAnyCallees = true;
12356
12357 LastCmp = new ICmpInst(IP, llvm::CmpInst::ICMP_EQ, FP, NewCallee);
12358 Instruction *ThenTI =
12359 SplitBlockAndInsertIfThen(LastCmp, IP, /* Unreachable */ false);
12360 BasicBlock *CBBB = CB->getParent();
12361 A.registerManifestAddedBasicBlock(*ThenTI->getParent());
12362 A.registerManifestAddedBasicBlock(*IP->getParent());
12363 auto *SplitTI = cast<BranchInst>(LastCmp->getNextNode());
12364 BasicBlock *ElseBB;
12365 if (&*IP == CB) {
12366 ElseBB = BasicBlock::Create(ThenTI->getContext(), "",
12367 ThenTI->getFunction(), CBBB);
12368 A.registerManifestAddedBasicBlock(*ElseBB);
12369 IP = BranchInst::Create(CBBB, ElseBB)->getIterator();
12370 SplitTI->replaceUsesOfWith(CBBB, ElseBB);
12371 } else {
12372 ElseBB = IP->getParent();
12373 ThenTI->replaceUsesOfWith(ElseBB, CBBB);
12374 }
12375 CastInst *RetBC = nullptr;
12376 CallInst *NewCall = nullptr;
12377 if (isLegalToPromote(*CB, NewCallee)) {
12378 auto *CBClone = cast<CallBase>(CB->clone());
12379 CBClone->insertBefore(ThenTI);
12380 NewCall = &cast<CallInst>(promoteCall(*CBClone, NewCallee, &RetBC));
12381 } else {
12382 NewCall = CallInst::Create(FunctionCallee(CSFT, NewCallee), CSArgs,
12383 CB->getName(), ThenTI->getIterator());
12384 }
12385 NewCalls.push_back({NewCall, RetBC});
12386 }
12387
12388 auto AttachCalleeMetadata = [&](CallBase &IndirectCB) {
12389 if (!AllCalleesKnown)
12390 return ChangeStatus::UNCHANGED;
12391 MDBuilder MDB(IndirectCB.getContext());
12392 MDNode *Callees = MDB.createCallees(SkippedAssumedCallees);
12393 IndirectCB.setMetadata(LLVMContext::MD_callees, Callees);
12394 return ChangeStatus::CHANGED;
12395 };
12396
12397 if (!SpecializedForAnyCallees)
12398 return AttachCalleeMetadata(*CB);
12399
12400 // Check if we need the fallback indirect call still.
12401 if (SpecializedForAllCallees) {
12403 LastCmp->eraseFromParent();
12404 new UnreachableInst(IP->getContext(), IP);
12405 IP->eraseFromParent();
12406 } else {
12407 auto *CBClone = cast<CallInst>(CB->clone());
12408 CBClone->setName(CB->getName());
12409 CBClone->insertBefore(*IP->getParent(), IP);
12410 NewCalls.push_back({CBClone, nullptr});
12411 AttachCalleeMetadata(*CBClone);
12412 }
12413
12414 // Check if we need a PHI to merge the results.
12415 if (!CBIsVoid) {
12416 auto *PHI = PHINode::Create(CB->getType(), NewCalls.size(),
12417 CB->getName() + ".phi",
12418 CB->getParent()->getFirstInsertionPt());
12419 for (auto &It : NewCalls) {
12420 CallBase *NewCall = It.first;
12421 Instruction *CallRet = It.second ? It.second : It.first;
12422 if (CallRet->getType() == CB->getType())
12423 PHI->addIncoming(CallRet, CallRet->getParent());
12424 else if (NewCall->getType()->isVoidTy())
12425 PHI->addIncoming(PoisonValue::get(CB->getType()),
12426 NewCall->getParent());
12427 else
12428 llvm_unreachable("Call return should match or be void!");
12429 }
12430 A.changeAfterManifest(IRPosition::callsite_returned(*CB), *PHI);
12431 }
12432
12433 A.deleteAfterManifest(*CB);
12434 Changed = ChangeStatus::CHANGED;
12435
12436 return Changed;
12437 }
12438
12439 /// See AbstractAttribute::getAsStr().
12440 const std::string getAsStr(Attributor *A) const override {
12441 return std::string(AllCalleesKnown ? "eliminate" : "specialize") +
12442 " indirect call site with " + std::to_string(AssumedCallees.size()) +
12443 " functions";
12444 }
12445
12446 void trackStatistics() const override {
12447 if (AllCalleesKnown) {
12449 Eliminated, CallSites,
12450 "Number of indirect call sites eliminated via specialization")
12451 } else {
12452 STATS_DECLTRACK(Specialized, CallSites,
12453 "Number of indirect call sites specialized")
12454 }
12455 }
12456
12457 bool foreachCallee(function_ref<bool(Function *)> CB) const override {
12458 return isValidState() && AllCalleesKnown && all_of(AssumedCallees, CB);
12459 }
12460
12461private:
12462 /// Map to remember filter results.
12464
12465 /// If the !callee metadata was present, this set will contain all potential
12466 /// callees (superset).
12467 SmallSetVector<Function *, 4> PotentialCallees;
12468
12469 /// This set contains all currently assumed calllees, which might grow over
12470 /// time.
12471 SmallSetVector<Function *, 4> AssumedCallees;
12472
12473 /// Flag to indicate if all possible callees are in the AssumedCallees set or
12474 /// if there could be others.
12475 bool AllCalleesKnown = true;
12476};
12477} // namespace
12478
12479/// ------------------------ Address Space ------------------------------------
12480namespace {
12481struct AAAddressSpaceImpl : public AAAddressSpace {
12482 AAAddressSpaceImpl(const IRPosition &IRP, Attributor &A)
12483 : AAAddressSpace(IRP, A) {}
12484
12485 int32_t getAddressSpace() const override {
12486 assert(isValidState() && "the AA is invalid");
12487 return AssumedAddressSpace;
12488 }
12489
12490 /// See AbstractAttribute::initialize(...).
12491 void initialize(Attributor &A) override {
12492 assert(getAssociatedType()->isPtrOrPtrVectorTy() &&
12493 "Associated value is not a pointer");
12494 }
12495
12496 ChangeStatus updateImpl(Attributor &A) override {
12497 int32_t OldAddressSpace = AssumedAddressSpace;
12498 auto *AUO = A.getOrCreateAAFor<AAUnderlyingObjects>(getIRPosition(), this,
12499 DepClassTy::REQUIRED);
12500 auto Pred = [&](Value &Obj) {
12501 if (isa<UndefValue>(&Obj))
12502 return true;
12503 return takeAddressSpace(Obj.getType()->getPointerAddressSpace());
12504 };
12505
12506 if (!AUO->forallUnderlyingObjects(Pred))
12507 return indicatePessimisticFixpoint();
12508
12509 return OldAddressSpace == AssumedAddressSpace ? ChangeStatus::UNCHANGED
12510 : ChangeStatus::CHANGED;
12511 }
12512
12513 /// See AbstractAttribute::manifest(...).
12514 ChangeStatus manifest(Attributor &A) override {
12515 Value *AssociatedValue = &getAssociatedValue();
12516 Value *OriginalValue = peelAddrspacecast(AssociatedValue);
12517 if (getAddressSpace() == NoAddressSpace ||
12518 static_cast<uint32_t>(getAddressSpace()) ==
12519 getAssociatedType()->getPointerAddressSpace())
12520 return ChangeStatus::UNCHANGED;
12521
12522 Type *NewPtrTy = PointerType::get(getAssociatedType()->getContext(),
12523 static_cast<uint32_t>(getAddressSpace()));
12524 bool UseOriginalValue =
12525 OriginalValue->getType()->getPointerAddressSpace() ==
12526 static_cast<uint32_t>(getAddressSpace());
12527
12528 bool Changed = false;
12529
12530 auto MakeChange = [&](Instruction *I, Use &U) {
12531 Changed = true;
12532 if (UseOriginalValue) {
12533 A.changeUseAfterManifest(U, *OriginalValue);
12534 return;
12535 }
12536 Instruction *CastInst = new AddrSpaceCastInst(OriginalValue, NewPtrTy);
12537 CastInst->insertBefore(cast<Instruction>(I));
12538 A.changeUseAfterManifest(U, *CastInst);
12539 };
12540
12541 auto Pred = [&](const Use &U, bool &) {
12542 if (U.get() != AssociatedValue)
12543 return true;
12544 auto *Inst = dyn_cast<Instruction>(U.getUser());
12545 if (!Inst)
12546 return true;
12547 // This is a WA to make sure we only change uses from the corresponding
12548 // CGSCC if the AA is run on CGSCC instead of the entire module.
12549 if (!A.isRunOn(Inst->getFunction()))
12550 return true;
12551 if (isa<LoadInst>(Inst))
12552 MakeChange(Inst, const_cast<Use &>(U));
12553 if (isa<StoreInst>(Inst)) {
12554 // We only make changes if the use is the pointer operand.
12555 if (U.getOperandNo() == 1)
12556 MakeChange(Inst, const_cast<Use &>(U));
12557 }
12558 return true;
12559 };
12560
12561 // It doesn't matter if we can't check all uses as we can simply
12562 // conservatively ignore those that can not be visited.
12563 (void)A.checkForAllUses(Pred, *this, getAssociatedValue(),
12564 /* CheckBBLivenessOnly */ true);
12565
12566 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
12567 }
12568
12569 /// See AbstractAttribute::getAsStr().
12570 const std::string getAsStr(Attributor *A) const override {
12571 if (!isValidState())
12572 return "addrspace(<invalid>)";
12573 return "addrspace(" +
12574 (AssumedAddressSpace == NoAddressSpace
12575 ? "none"
12576 : std::to_string(AssumedAddressSpace)) +
12577 ")";
12578 }
12579
12580private:
12581 int32_t AssumedAddressSpace = NoAddressSpace;
12582
12583 bool takeAddressSpace(int32_t AS) {
12584 if (AssumedAddressSpace == NoAddressSpace) {
12585 AssumedAddressSpace = AS;
12586 return true;
12587 }
12588 return AssumedAddressSpace == AS;
12589 }
12590
12591 static Value *peelAddrspacecast(Value *V) {
12592 if (auto *I = dyn_cast<AddrSpaceCastInst>(V))
12593 return peelAddrspacecast(I->getPointerOperand());
12594 if (auto *C = dyn_cast<ConstantExpr>(V))
12595 if (C->getOpcode() == Instruction::AddrSpaceCast)
12596 return peelAddrspacecast(C->getOperand(0));
12597 return V;
12598 }
12599};
12600
12601struct AAAddressSpaceFloating final : AAAddressSpaceImpl {
12602 AAAddressSpaceFloating(const IRPosition &IRP, Attributor &A)
12603 : AAAddressSpaceImpl(IRP, A) {}
12604
12605 void trackStatistics() const override {
12607 }
12608};
12609
12610struct AAAddressSpaceReturned final : AAAddressSpaceImpl {
12611 AAAddressSpaceReturned(const IRPosition &IRP, Attributor &A)
12612 : AAAddressSpaceImpl(IRP, A) {}
12613
12614 /// See AbstractAttribute::initialize(...).
12615 void initialize(Attributor &A) override {
12616 // TODO: we don't rewrite function argument for now because it will need to
12617 // rewrite the function signature and all call sites.
12618 (void)indicatePessimisticFixpoint();
12619 }
12620
12621 void trackStatistics() const override {
12622 STATS_DECLTRACK_FNRET_ATTR(addrspace);
12623 }
12624};
12625
12626struct AAAddressSpaceCallSiteReturned final : AAAddressSpaceImpl {
12627 AAAddressSpaceCallSiteReturned(const IRPosition &IRP, Attributor &A)
12628 : AAAddressSpaceImpl(IRP, A) {}
12629
12630 void trackStatistics() const override {
12631 STATS_DECLTRACK_CSRET_ATTR(addrspace);
12632 }
12633};
12634
12635struct AAAddressSpaceArgument final : AAAddressSpaceImpl {
12636 AAAddressSpaceArgument(const IRPosition &IRP, Attributor &A)
12637 : AAAddressSpaceImpl(IRP, A) {}
12638
12639 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(addrspace); }
12640};
12641
12642struct AAAddressSpaceCallSiteArgument final : AAAddressSpaceImpl {
12643 AAAddressSpaceCallSiteArgument(const IRPosition &IRP, Attributor &A)
12644 : AAAddressSpaceImpl(IRP, A) {}
12645
12646 /// See AbstractAttribute::initialize(...).
12647 void initialize(Attributor &A) override {
12648 // TODO: we don't rewrite call site argument for now because it will need to
12649 // rewrite the function signature of the callee.
12650 (void)indicatePessimisticFixpoint();
12651 }
12652
12653 void trackStatistics() const override {
12654 STATS_DECLTRACK_CSARG_ATTR(addrspace);
12655 }
12656};
12657} // namespace
12658
12659/// ----------- Allocation Info ----------
12660namespace {
12661struct AAAllocationInfoImpl : public AAAllocationInfo {
12662 AAAllocationInfoImpl(const IRPosition &IRP, Attributor &A)
12663 : AAAllocationInfo(IRP, A) {}
12664
12665 std::optional<TypeSize> getAllocatedSize() const override {
12666 assert(isValidState() && "the AA is invalid");
12667 return AssumedAllocatedSize;
12668 }
12669
12670 std::optional<TypeSize> findInitialAllocationSize(Instruction *I,
12671 const DataLayout &DL) {
12672
12673 // TODO: implement case for malloc like instructions
12674 switch (I->getOpcode()) {
12675 case Instruction::Alloca: {
12676 AllocaInst *AI = cast<AllocaInst>(I);
12677 return AI->getAllocationSize(DL);
12678 }
12679 default:
12680 return std::nullopt;
12681 }
12682 }
12683
12684 ChangeStatus updateImpl(Attributor &A) override {
12685
12686 const IRPosition &IRP = getIRPosition();
12687 Instruction *I = IRP.getCtxI();
12688
12689 // TODO: update check for malloc like calls
12690 if (!isa<AllocaInst>(I))
12691 return indicatePessimisticFixpoint();
12692
12693 bool IsKnownNoCapture;
12694 if (!AA::hasAssumedIRAttr<Attribute::NoCapture>(
12695 A, this, IRP, DepClassTy::OPTIONAL, IsKnownNoCapture))
12696 return indicatePessimisticFixpoint();
12697
12698 const AAPointerInfo *PI =
12699 A.getOrCreateAAFor<AAPointerInfo>(IRP, *this, DepClassTy::REQUIRED);
12700
12701 if (!PI)
12702 return indicatePessimisticFixpoint();
12703
12704 if (!PI->getState().isValidState())
12705 return indicatePessimisticFixpoint();
12706
12707 const DataLayout &DL = A.getDataLayout();
12708 const auto AllocationSize = findInitialAllocationSize(I, DL);
12709
12710 // If allocation size is nullopt, we give up.
12711 if (!AllocationSize)
12712 return indicatePessimisticFixpoint();
12713
12714 // For zero sized allocations, we give up.
12715 // Since we can't reduce further
12716 if (*AllocationSize == 0)
12717 return indicatePessimisticFixpoint();
12718
12719 int64_t BinSize = PI->numOffsetBins();
12720
12721 // TODO: implement for multiple bins
12722 if (BinSize > 1)
12723 return indicatePessimisticFixpoint();
12724
12725 if (BinSize == 0) {
12726 auto NewAllocationSize = std::optional<TypeSize>(TypeSize(0, false));
12727 if (!changeAllocationSize(NewAllocationSize))
12728 return ChangeStatus::UNCHANGED;
12729 return ChangeStatus::CHANGED;
12730 }
12731
12732 // TODO: refactor this to be part of multiple bin case
12733 const auto &It = PI->begin();
12734
12735 // TODO: handle if Offset is not zero
12736 if (It->first.Offset != 0)
12737 return indicatePessimisticFixpoint();
12738
12739 uint64_t SizeOfBin = It->first.Offset + It->first.Size;
12740
12741 if (SizeOfBin >= *AllocationSize)
12742 return indicatePessimisticFixpoint();
12743
12744 auto NewAllocationSize =
12745 std::optional<TypeSize>(TypeSize(SizeOfBin * 8, false));
12746
12747 if (!changeAllocationSize(NewAllocationSize))
12748 return ChangeStatus::UNCHANGED;
12749
12750 return ChangeStatus::CHANGED;
12751 }
12752
12753 /// See AbstractAttribute::manifest(...).
12754 ChangeStatus manifest(Attributor &A) override {
12755
12756 assert(isValidState() &&
12757 "Manifest should only be called if the state is valid.");
12758
12759 Instruction *I = getIRPosition().getCtxI();
12760
12761 auto FixedAllocatedSizeInBits = getAllocatedSize()->getFixedValue();
12762
12763 unsigned long NumBytesToAllocate = (FixedAllocatedSizeInBits + 7) / 8;
12764
12765 switch (I->getOpcode()) {
12766 // TODO: add case for malloc like calls
12767 case Instruction::Alloca: {
12768
12769 AllocaInst *AI = cast<AllocaInst>(I);
12770
12771 Type *CharType = Type::getInt8Ty(I->getContext());
12772
12773 auto *NumBytesToValue =
12774 ConstantInt::get(I->getContext(), APInt(32, NumBytesToAllocate));
12775
12776 BasicBlock::iterator insertPt = AI->getIterator();
12777 insertPt = std::next(insertPt);
12778 AllocaInst *NewAllocaInst =
12779 new AllocaInst(CharType, AI->getAddressSpace(), NumBytesToValue,
12780 AI->getAlign(), AI->getName(), insertPt);
12781
12782 if (A.changeAfterManifest(IRPosition::inst(*AI), *NewAllocaInst))
12783 return ChangeStatus::CHANGED;
12784
12785 break;
12786 }
12787 default:
12788 break;
12789 }
12790
12791 return ChangeStatus::UNCHANGED;
12792 }
12793
12794 /// See AbstractAttribute::getAsStr().
12795 const std::string getAsStr(Attributor *A) const override {
12796 if (!isValidState())
12797 return "allocationinfo(<invalid>)";
12798 return "allocationinfo(" +
12799 (AssumedAllocatedSize == HasNoAllocationSize
12800 ? "none"
12801 : std::to_string(AssumedAllocatedSize->getFixedValue())) +
12802 ")";
12803 }
12804
12805private:
12806 std::optional<TypeSize> AssumedAllocatedSize = HasNoAllocationSize;
12807
12808 // Maintain the computed allocation size of the object.
12809 // Returns (bool) weather the size of the allocation was modified or not.
12810 bool changeAllocationSize(std::optional<TypeSize> Size) {
12811 if (AssumedAllocatedSize == HasNoAllocationSize ||
12812 AssumedAllocatedSize != Size) {
12813 AssumedAllocatedSize = Size;
12814 return true;
12815 }
12816 return false;
12817 }
12818};
12819
12820struct AAAllocationInfoFloating : AAAllocationInfoImpl {
12821 AAAllocationInfoFloating(const IRPosition &IRP, Attributor &A)
12822 : AAAllocationInfoImpl(IRP, A) {}
12823
12824 void trackStatistics() const override {
12825 STATS_DECLTRACK_FLOATING_ATTR(allocationinfo);
12826 }
12827};
12828
12829struct AAAllocationInfoReturned : AAAllocationInfoImpl {
12830 AAAllocationInfoReturned(const IRPosition &IRP, Attributor &A)
12831 : AAAllocationInfoImpl(IRP, A) {}
12832
12833 /// See AbstractAttribute::initialize(...).
12834 void initialize(Attributor &A) override {
12835 // TODO: we don't rewrite function argument for now because it will need to
12836 // rewrite the function signature and all call sites
12837 (void)indicatePessimisticFixpoint();
12838 }
12839
12840 void trackStatistics() const override {
12841 STATS_DECLTRACK_FNRET_ATTR(allocationinfo);
12842 }
12843};
12844
12845struct AAAllocationInfoCallSiteReturned : AAAllocationInfoImpl {
12846 AAAllocationInfoCallSiteReturned(const IRPosition &IRP, Attributor &A)
12847 : AAAllocationInfoImpl(IRP, A) {}
12848
12849 void trackStatistics() const override {
12850 STATS_DECLTRACK_CSRET_ATTR(allocationinfo);
12851 }
12852};
12853
12854struct AAAllocationInfoArgument : AAAllocationInfoImpl {
12855 AAAllocationInfoArgument(const IRPosition &IRP, Attributor &A)
12856 : AAAllocationInfoImpl(IRP, A) {}
12857
12858 void trackStatistics() const override {
12859 STATS_DECLTRACK_ARG_ATTR(allocationinfo);
12860 }
12861};
12862
12863struct AAAllocationInfoCallSiteArgument : AAAllocationInfoImpl {
12864 AAAllocationInfoCallSiteArgument(const IRPosition &IRP, Attributor &A)
12865 : AAAllocationInfoImpl(IRP, A) {}
12866
12867 /// See AbstractAttribute::initialize(...).
12868 void initialize(Attributor &A) override {
12869
12870 (void)indicatePessimisticFixpoint();
12871 }
12872
12873 void trackStatistics() const override {
12874 STATS_DECLTRACK_CSARG_ATTR(allocationinfo);
12875 }
12876};
12877} // namespace
12878
12879const char AANoUnwind::ID = 0;
12880const char AANoSync::ID = 0;
12881const char AANoFree::ID = 0;
12882const char AANonNull::ID = 0;
12883const char AAMustProgress::ID = 0;
12884const char AANoRecurse::ID = 0;
12885const char AANonConvergent::ID = 0;
12886const char AAWillReturn::ID = 0;
12887const char AAUndefinedBehavior::ID = 0;
12888const char AANoAlias::ID = 0;
12889const char AAIntraFnReachability::ID = 0;
12890const char AANoReturn::ID = 0;
12891const char AAIsDead::ID = 0;
12892const char AADereferenceable::ID = 0;
12893const char AAAlign::ID = 0;
12894const char AAInstanceInfo::ID = 0;
12895const char AANoCapture::ID = 0;
12896const char AAValueSimplify::ID = 0;
12897const char AAHeapToStack::ID = 0;
12898const char AAPrivatizablePtr::ID = 0;
12899const char AAMemoryBehavior::ID = 0;
12900const char AAMemoryLocation::ID = 0;
12901const char AAValueConstantRange::ID = 0;
12902const char AAPotentialConstantValues::ID = 0;
12903const char AAPotentialValues::ID = 0;
12904const char AANoUndef::ID = 0;
12905const char AANoFPClass::ID = 0;
12906const char AACallEdges::ID = 0;
12907const char AAInterFnReachability::ID = 0;
12908const char AAPointerInfo::ID = 0;
12909const char AAAssumptionInfo::ID = 0;
12910const char AAUnderlyingObjects::ID = 0;
12911const char AAAddressSpace::ID = 0;
12912const char AAAllocationInfo::ID = 0;
12913const char AAIndirectCallInfo::ID = 0;
12914const char AAGlobalValueInfo::ID = 0;
12915const char AADenormalFPMath::ID = 0;
12916
12917// Macro magic to create the static generator function for attributes that
12918// follow the naming scheme.
12919
12920#define SWITCH_PK_INV(CLASS, PK, POS_NAME) \
12921 case IRPosition::PK: \
12922 llvm_unreachable("Cannot create " #CLASS " for a " POS_NAME " position!");
12923
12924#define SWITCH_PK_CREATE(CLASS, IRP, PK, SUFFIX) \
12925 case IRPosition::PK: \
12926 AA = new (A.Allocator) CLASS##SUFFIX(IRP, A); \
12927 ++NumAAs; \
12928 break;
12929
12930#define CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
12931 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
12932 CLASS *AA = nullptr; \
12933 switch (IRP.getPositionKind()) { \
12934 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
12935 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
12936 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
12937 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
12938 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
12939 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
12940 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
12941 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
12942 } \
12943 return *AA; \
12944 }
12945
12946#define CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
12947 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
12948 CLASS *AA = nullptr; \
12949 switch (IRP.getPositionKind()) { \
12950 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
12951 SWITCH_PK_INV(CLASS, IRP_FUNCTION, "function") \
12952 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
12953 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
12954 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
12955 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
12956 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
12957 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
12958 } \
12959 return *AA; \
12960 }
12961
12962#define CREATE_ABSTRACT_ATTRIBUTE_FOR_ONE_POSITION(POS, SUFFIX, CLASS) \
12963 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
12964 CLASS *AA = nullptr; \
12965 switch (IRP.getPositionKind()) { \
12966 SWITCH_PK_CREATE(CLASS, IRP, POS, SUFFIX) \
12967 default: \
12968 llvm_unreachable("Cannot create " #CLASS " for position otherthan " #POS \
12969 " position!"); \
12970 } \
12971 return *AA; \
12972 }
12973
12974#define CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
12975 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
12976 CLASS *AA = nullptr; \
12977 switch (IRP.getPositionKind()) { \
12978 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
12979 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
12980 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
12981 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
12982 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
12983 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
12984 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
12985 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
12986 } \
12987 return *AA; \
12988 }
12989
12990#define CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
12991 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
12992 CLASS *AA = nullptr; \
12993 switch (IRP.getPositionKind()) { \
12994 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
12995 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
12996 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
12997 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
12998 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
12999 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
13000 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
13001 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
13002 } \
13003 return *AA; \
13004 }
13005
13006#define CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13007 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13008 CLASS *AA = nullptr; \
13009 switch (IRP.getPositionKind()) { \
13010 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13011 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
13012 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
13013 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
13014 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
13015 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
13016 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
13017 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
13018 } \
13019 return *AA; \
13020 }
13021
13031
13047
13052
13057
13064
13066
13067#undef CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION
13068#undef CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION
13069#undef CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION
13070#undef CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION
13071#undef CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION
13072#undef CREATE_ABSTRACT_ATTRIBUTE_FOR_ONE_POSITION
13073#undef SWITCH_PK_CREATE
13074#undef SWITCH_PK_INV
#define Success
amdgpu AMDGPU Register Bank Select
Rewrite undef for PHI
This file implements a class to represent arbitrary precision integral constant values and operations...
ReachingDefAnalysis InstSet & ToRemove
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file contains the simple types necessary to represent the attributes associated with functions a...
#define STATS_DECLTRACK(NAME, TYPE, MSG)
static std::optional< Constant * > askForAssumedConstant(Attributor &A, const AbstractAttribute &QueryingAA, const IRPosition &IRP, Type &Ty)
static cl::opt< unsigned, true > MaxPotentialValues("attributor-max-potential-values", cl::Hidden, cl::desc("Maximum number of potential values to be " "tracked for each position."), cl::location(llvm::PotentialConstantIntValuesState::MaxPotentialValues), cl::init(7))
static const Value * getPointerOperand(const Instruction *I, bool AllowVolatile)
Get pointer operand of memory accessing instruction.
static void clampReturnedValueStates(Attributor &A, const AAType &QueryingAA, StateType &S, const IRPosition::CallBaseContext *CBContext=nullptr)
Clamp the information known for all returned values of a function (identified by QueryingAA) into S.
#define STATS_DECLTRACK_FN_ATTR(NAME)
#define CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
static cl::opt< int > MaxPotentialValuesIterations("attributor-max-potential-values-iterations", cl::Hidden, cl::desc("Maximum number of iterations we keep dismantling potential values."), cl::init(64))
#define STATS_DECLTRACK_CS_ATTR(NAME)
#define PIPE_OPERATOR(CLASS)
#define DefineKeys(ToTy)
static bool mayBeInCycle(const CycleInfo *CI, const Instruction *I, bool HeaderOnly, Cycle **CPtr=nullptr)
#define STATS_DECLTRACK_ARG_ATTR(NAME)
static const Value * stripAndAccumulateOffsets(Attributor &A, const AbstractAttribute &QueryingAA, const Value *Val, const DataLayout &DL, APInt &Offset, bool GetMinOffset, bool AllowNonInbounds, bool UseAssumed=false)
#define STATS_DECLTRACK_CSRET_ATTR(NAME)
static cl::opt< bool > ManifestInternal("attributor-manifest-internal", cl::Hidden, cl::desc("Manifest Attributor internal string attributes."), cl::init(false))
static Value * constructPointer(Value *Ptr, int64_t Offset, IRBuilder< NoFolder > &IRB)
Helper function to create a pointer based on Ptr, and advanced by Offset bytes.
#define CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
#define BUILD_STAT_NAME(NAME, TYPE)
static bool isDenselyPacked(Type *Ty, const DataLayout &DL)
Checks if a type could have padding bytes.
#define CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
static const Value * getMinimalBaseOfPointer(Attributor &A, const AbstractAttribute &QueryingAA, const Value *Ptr, int64_t &BytesOffset, const DataLayout &DL, bool AllowNonInbounds=false)
#define STATS_DECLTRACK_FNRET_ATTR(NAME)
#define STATS_DECLTRACK_CSARG_ATTR(NAME)
#define CREATE_ABSTRACT_ATTRIBUTE_FOR_ONE_POSITION(POS, SUFFIX, CLASS)
#define CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
static cl::opt< int > MaxHeapToStackSize("max-heap-to-stack-size", cl::init(128), cl::Hidden)
#define CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
#define STATS_DECLTRACK_FLOATING_ATTR(NAME)
#define STATS_DECL(NAME, TYPE, MSG)
basic Basic Alias true
BlockVerifier::State From
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static bool isReachableImpl(SmallVectorImpl< BasicBlock * > &Worklist, const StopSetT &StopSet, const SmallPtrSetImpl< BasicBlock * > *ExclusionSet, const DominatorTree *DT, const LoopInfo *LI)
Definition: CFG.cpp:134
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...
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
Given that RA is a live propagate it s liveness to any other values it uses(according to Uses). void DeadArgumentEliminationPass
Performs the initial survey of the specified function
Given that RA is a live value
#define LLVM_DEBUG(X)
Definition: Debug.h:101
This file defines DenseMapInfo traits for DenseMap.
T Content
uint64_t Size
Rewrite Partial Register Uses
#define Check(C,...)
Hexagon Common GEP
IRTranslator LLVM IR MI
static LoopDeletionResult merge(LoopDeletionResult A, LoopDeletionResult B)
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
This file implements a map that provides insertion order iteration.
#define T
#define T1
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
uint64_t IntrinsicInst * II
if(VerifyEach)
static StringRef getName(Value *V)
Basic Register Allocator
static cl::opt< RegAllocEvictionAdvisorAnalysis::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysis::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysis::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysis::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysis::AdvisorMode::Development, "development", "for training")))
This builds on the llvm/ADT/GraphTraits.h file to find the strongly connected components (SCCs) of a ...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool IsDead
This file contains some templates that are useful if you are working with the STL at all.
raw_pwrite_stream & OS
This file defines generic set operations that may be used on set's of different types,...
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition: Statistic.h:167
This file contains some functions that are useful when dealing with strings.
static SymbolRef::Type getType(const Symbol *Sym)
Definition: TapiFile.cpp:40
static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, ArrayRef< StringLiteral > StandardNames)
Initialize the set of available library functions based on the specified target triple.
@ Floating
This pass exposes codegen information to IR-level passes.
static unsigned getBitWidth(Type *Ty, const DataLayout &DL)
Returns the bitwidth of the given scalar or pointer type.
Value * RHS
Value * LHS
static unsigned getSize(unsigned Kind)
AACallGraphNode * operator*() const
A manager for alias analyses.
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:1522
AbstractCallSite.
CallBase * getInstruction() const
Return the underlying instruction.
bool isCallbackCall() const
Return true if this ACS represents a callback call.
bool isDirectCall() const
Return true if this ACS represents a direct call.
static void getCallbackUses(const CallBase &CB, SmallVectorImpl< const Use * > &CallbackUses)
Add operand uses of CB that represent callback uses into CallbackUses.
int getCallArgOperandNo(Argument &Arg) const
Return the operand index of the underlying instruction associated with Arg.
This class represents a conversion between pointers from one address space to another.
an instruction to allocate memory on the stack
Definition: Instructions.h:61
Align getAlign() const
Return the alignment of the memory that is being allocated by the instruction.
Definition: Instructions.h:122
unsigned getAddressSpace() const
Return the address space for the allocation.
Definition: Instructions.h:102
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:31
bool hasPointeeInMemoryValueAttr() const
Return true if this argument has the byval, sret, inalloca, preallocated, or byref attribute.
Definition: Function.cpp:179
bool hasReturnedAttr() const
Return true if this argument has the returned attribute.
Definition: Function.cpp:304
bool hasByValAttr() const
Return true if this argument has the byval attribute.
Definition: Function.cpp:141
const Function * getParent() const
Definition: Argument.h:43
unsigned getArgNo() const
Return the index of this formal argument in its containing function.
Definition: Argument.h:49
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
iterator end() const
Definition: ArrayRef.h:154
iterator begin() const
Definition: ArrayRef.h:153
A function analysis which provides an AssumptionCache.
A cache of @llvm.assume calls within a function.
static Attribute get(LLVMContext &Context, AttrKind Kind, uint64_t Val=0)
Return a uniquified Attribute object.
Definition: Attributes.cpp:94
static Attribute getWithDereferenceableBytes(LLVMContext &Context, uint64_t Bytes)
Definition: Attributes.cpp:242
FPClassTest getNoFPClass() const
Return the FPClassTest for nofpclass.
Definition: Attributes.cpp:489
Attribute::AttrKind getKindAsEnum() const
Return the attribute's kind as an enum (Attribute::AttrKind).
Definition: Attributes.cpp:362
MemoryEffects getMemoryEffects() const
Returns memory effects.
Definition: Attributes.cpp:483
static Attribute getWithDereferenceableOrNullBytes(LLVMContext &Context, uint64_t Bytes)
Definition: Attributes.cpp:248
static Attribute getWithNoFPClass(LLVMContext &Context, FPClassTest Mask)
Definition: Attributes.cpp:284
AttrKind
This enumeration lists the attributes that can be associated with parameters, function results,...
Definition: Attributes.h:86
static bool isEnumAttrKind(AttrKind Kind)
Definition: Attributes.h:99
static Attribute getWithMemoryEffects(LLVMContext &Context, MemoryEffects ME)
Definition: Attributes.cpp:279
static Attribute getWithAlignment(LLVMContext &Context, Align Alignment)
Return a uniquified Attribute object that has the specific alignment set.
Definition: Attributes.cpp:232
LLVM Basic Block Representation.
Definition: BasicBlock.h:61
const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
Definition: BasicBlock.cpp:414
const Instruction & front() const
Definition: BasicBlock.h:461
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition: BasicBlock.h:202
const Function * getParent() const
Return the enclosing method, or null if none.
Definition: BasicBlock.h:209
InstListType::iterator iterator
Instruction iterators...
Definition: BasicBlock.h:167
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
Definition: BasicBlock.h:229
BinaryOps getOpcode() const
Definition: InstrTypes.h:442
Conditional or Unconditional Branch instruction.
unsigned getNumSuccessors() const
static BranchInst * Create(BasicBlock *IfTrue, InsertPosition InsertBefore=nullptr)
BasicBlock * getSuccessor(unsigned i) const
Value * getCondition() const
Allocate memory in an ever growing pool, as if by bump-pointer.
Definition: Allocator.h:66
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Definition: InstrTypes.h:1236
User::op_iterator arg_begin()
Return the iterator pointing to the beginning of the argument list.
Definition: InstrTypes.h:1385
bool isMustTailCall() const
Tests if this call site must be tail call optimized.
bool isIndirectCall() const
Return true if the callsite is an indirect call.
bool isCallee(Value::const_user_iterator UI) const
Determine whether the passed iterator points to the callee operand's Use.
Definition: InstrTypes.h:1476
Value * getCalledOperand() const
Definition: InstrTypes.h:1458
const Use & getCalledOperandUse() const
Definition: InstrTypes.h:1460
const Use & getArgOperandUse(unsigned i) const
Wrappers for getting the Use of a call argument.
Definition: InstrTypes.h:1421
Value * getArgOperand(unsigned i) const
Definition: InstrTypes.h:1410
User::op_iterator arg_end()
Return the iterator pointing to the end of the argument list.
Definition: InstrTypes.h:1391
bool isBundleOperand(unsigned Idx) const
Return true if the operand at index Idx is a bundle operand.
Definition: InstrTypes.h:2076
bool isConvergent() const
Determine if the invoke is convergent.
Definition: InstrTypes.h:2027
FunctionType * getFunctionType() const
Definition: InstrTypes.h:1323
Intrinsic::ID getIntrinsicID() const
Returns the intrinsic ID of the intrinsic called or Intrinsic::not_intrinsic if the called function i...
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
Definition: InstrTypes.h:1401
unsigned getArgOperandNo(const Use *U) const
Given a use for a arg operand, get the arg operand number that corresponds to it.
Definition: InstrTypes.h:1441
unsigned arg_size() const
Definition: InstrTypes.h:1408
bool isArgOperand(const Use *U) const
Definition: InstrTypes.h:1430
Function * getCaller()
Helper to get the caller (the parent function).
This class represents a function call, abstracting a target machine's calling convention.
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
This is the base class for all instructions that perform data casts.
Definition: InstrTypes.h:530
Instruction::CastOps getOpcode() const
Return the opcode of this CastInst.
Definition: InstrTypes.h:694
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:701
This class is the base class for the comparison instructions.
Definition: InstrTypes.h:747
bool isEquality() const
Determine if this is an equals/not equals predicate.
Definition: InstrTypes.h:997
bool isFalseWhenEqual() const
This is just a convenience.
Definition: InstrTypes.h:1062
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition: InstrTypes.h:757
@ ICMP_EQ
equal
Definition: InstrTypes.h:778
@ ICMP_NE
not equal
Definition: InstrTypes.h:779
bool isTrueWhenEqual() const
This is just a convenience.
Definition: InstrTypes.h:1056
Predicate getPredicate() const
Return the predicate for this instruction.
Definition: InstrTypes.h:847
static ConstantAsMetadata * get(Constant *C)
Definition: Metadata.h:528
A constant value that is initialized with an expression using other constant values.
Definition: Constants.h:1084
static Constant * getExtractElement(Constant *Vec, Constant *Idx, Type *OnlyIfReducedTy=nullptr)
Definition: Constants.cpp:2516
This is the shared class of boolean and integer constants.
Definition: Constants.h:81
static ConstantInt * getTrue(LLVMContext &Context)
Definition: Constants.cpp:850
This class represents a range of values.
Definition: ConstantRange.h:47
const APInt & getLower() const
Return the lower value for this range.
bool isFullSet() const
Return true if this set contains all of the elements possible for this data-type.
bool isEmptySet() const
Return true if this set contains no members.
APInt getSignedMin() const
Return the smallest signed value contained in the ConstantRange.
bool isSingleElement() const
Return true if this set contains exactly one member.
static 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.
APInt getSignedMax() const
Return the largest signed value contained in the ConstantRange.
This is an important base class in LLVM.
Definition: Constant.h:42
Analysis pass which computes a CycleInfo.
Definition: CycleAnalysis.h:47
This class represents an Operation in the Expression.
A parsed version of the target data layout string in and methods for querying it.
Definition: DataLayout.h:110
A debug info location.
Definition: DebugLoc.h:33
iterator find(const_arg_type_t< KeyT > Val)
Definition: DenseMap.h:155
unsigned size() const
Definition: DenseMap.h:99
iterator begin()
Definition: DenseMap.h:75
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:151
iterator end()
Definition: DenseMap.h:84
bool contains(const_arg_type_t< KeyT > Val) const
Return true if the specified key is in the map, false otherwise.
Definition: DenseMap.h:145
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition: DenseMap.h:220
Implements a dense probed hash-table based set.
Definition: DenseSet.h:271
Analysis pass which computes a DominatorTree.
Definition: Dominators.h:279
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition: Dominators.h:162
bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
Definition: Dominators.cpp:122
An instruction for ordering other memory operations.
Definition: Instructions.h:420
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
Definition: DerivedTypes.h:168
const BasicBlock & getEntryBlock() const
Definition: Function.h:800
iterator_range< arg_iterator > args()
Definition: Function.h:855
const Function & getFunction() const
Definition: Function.h:163
size_t arg_size() const
Definition: Function.h:864
Argument * getArg(unsigned i) const
Definition: Function.h:849
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition: Function.cpp:719
CycleT * getCycle(const BlockT *Block) const
Find the innermost cycle containing a given block.
A possibly irreducible generalization of a Loop.
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
Definition: Globals.cpp:290
bool hasLocalLinkage() const
Definition: GlobalValue.h:528
This instruction compares its operands according to the predicate given to the constructor.
static 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:1981
ConstantInt * getInt64(uint64_t C)
Get a constant 64-bit value.
Definition: IRBuilder.h:488
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition: IRBuilder.h:2671
Instruction * clone() const
Create a copy of 'this' instruction that is identical in all ways except the following:
bool isLifetimeStartOrEnd() const LLVM_READONLY
Return true if the instruction is a llvm.lifetime.start or llvm.lifetime.end marker.
bool mayReadOrWriteMemory() const
Return true if this instruction may read or write memory.
Definition: Instruction.h:754
bool mayWriteToMemory() const LLVM_READONLY
Return true if this instruction may modify memory.
void insertBefore(Instruction *InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified instruction.
Definition: Instruction.cpp:97
InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
Definition: Instruction.cpp:92
const Function * getFunction() const
Return the function this instruction belongs to.
Definition: Instruction.cpp:70
BasicBlock * getSuccessor(unsigned Idx) const LLVM_READONLY
Return the specified successor. This instruction must be a terminator.
bool mayHaveSideEffects() const LLVM_READONLY
Return true if the instruction may have side effects.
bool isTerminator() const
Definition: Instruction.h:277
bool mayReadFromMemory() const LLVM_READONLY
Return true if this instruction may read memory.
const Instruction * getNextNonDebugInstruction(bool SkipPseudoOp=false) const
Return a pointer to the next non-debug instruction in the same basic block as 'this',...
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
Definition: Instruction.h:274
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
Definition: Instruction.h:463
const DataLayout & getDataLayout() const
Get the data layout of the module this instruction belongs to.
Definition: Instruction.cpp:74
A wrapper class for inspecting calls to intrinsic functions.
Definition: IntrinsicInst.h:48
Invoke instruction.
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:67
Analysis to compute lazy value information.
This pass computes, caches, and vends lazy value constraint information.
Definition: LazyValueInfo.h:34
ConstantRange getConstantRange(Value *V, Instruction *CxtI, bool UndefAllowed)
Return the ConstantRange constraint that is known to hold for the specified value at the specified in...
An instruction for reading from memory.
Definition: Instructions.h:174
Analysis pass that exposes the LoopInfo for a function.
Definition: LoopInfo.h:571
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
Metadata node.
Definition: Metadata.h:1067
const MDOperand & getOperand(unsigned I) const
Definition: Metadata.h:1428
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition: Metadata.h:1541
unsigned getNumOperands() const
Return number of MDNode operands.
Definition: Metadata.h:1434
This class implements a map that also provides access to all stored values in a deterministic order.
Definition: MapVector.h:36
bool empty() const
Definition: MapVector.h:79
static MemoryEffectsBase readOnly()
Create MemoryEffectsBase that can read any memory.
Definition: ModRef.h:122
bool doesNotAccessMemory() const
Whether this function accesses no memory.
Definition: ModRef.h:192
static MemoryEffectsBase argMemOnly(ModRefInfo MR=ModRefInfo::ModRef)
Create MemoryEffectsBase that can only access argument memory.
Definition: ModRef.h:132
static MemoryEffectsBase inaccessibleMemOnly(ModRefInfo MR=ModRefInfo::ModRef)
Create MemoryEffectsBase that can only access inaccessible memory.
Definition: ModRef.h:138
bool onlyAccessesInaccessibleMem() const
Whether this function only (at most) accesses inaccessible memory.
Definition: ModRef.h:211
ModRefInfo getModRef(Location Loc) const
Get ModRefInfo for the given Location.
Definition: ModRef.h:165
bool onlyAccessesArgPointees() const
Whether this function only (at most) accesses argument memory.
Definition: ModRef.h:201
bool onlyReadsMemory() const
Whether this function only (at most) reads memory.
Definition: ModRef.h:195
static MemoryEffectsBase writeOnly()
Create MemoryEffectsBase that can write any memory.
Definition: ModRef.h:127
static MemoryEffectsBase inaccessibleOrArgMemOnly(ModRefInfo MR=ModRefInfo::ModRef)
Create MemoryEffectsBase that can only access inaccessible or argument memory.
Definition: ModRef.h:145
static MemoryEffectsBase none()
Create MemoryEffectsBase that cannot read or write any memory.
Definition: ModRef.h:117
bool onlyAccessesInaccessibleOrArgMem() const
Whether this function only (at most) accesses argument and inaccessible memory.
Definition: ModRef.h:217
static MemoryEffectsBase unknown()
Create MemoryEffectsBase that can read and write any memory.
Definition: ModRef.h:112
static std::optional< MemoryLocation > getOrNone(const Instruction *Inst)
Root of the metadata hierarchy.
Definition: Metadata.h:62
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
Evaluate the size and offset of an object pointed to by a Value*.
static SizeOffsetValue unknown()
Diagnostic information for missed-optimization remarks.
Diagnostic information for applied optimization remarks.
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
static PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
Definition: Constants.cpp:1852
Return a value (possibly void), from a function.
Value * getReturnValue() const
Convenience accessor. Returns null if there is no return value.
This class represents an analyzed expression in the program.
Analysis pass that exposes the ScalarEvolution for a function.
The main scalar evolution driver.
const SCEV * getSCEVAtScope(const SCEV *S, const Loop *L)
Return a SCEV expression for the specified value at the specified scope in the program.
const SCEV * getSCEV(Value *V)
Return a SCEV expression for the full generality of the specified expression.
unsigned getSmallConstantMaxTripCount(const Loop *L)
Returns the upper bound of the loop trip count as a normal unsigned value.
ConstantRange getUnsignedRange(const SCEV *S)
Determine the unsigned range for a particular SCEV.
This class represents the LLVM 'select' instruction.
A vector that has set insertion semantics.
Definition: SetVector.h:57
size_type size() const
Determine the number of elements in the SetVector.
Definition: SetVector.h:98
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition: SetVector.h:162
bool erase(PtrType Ptr)
Remove pointer from the set.
Definition: SmallPtrSet.h:361
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
Definition: SmallPtrSet.h:412
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
Definition: SmallPtrSet.h:344
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
Definition: SmallPtrSet.h:479
A SetVector that performs no allocations if smaller than a certain size.
Definition: SetVector.h:370
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
Definition: SmallSet.h:135
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:179
bool empty() const
Definition: SmallVector.h:94
size_t size() const
Definition: SmallVector.h:91
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:586
reference emplace_back(ArgTypes &&... Args)
Definition: SmallVector.h:950
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
Definition: SmallVector.h:696
void push_back(const T &Elt)
Definition: SmallVector.h:426
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1209
An instruction for storing to memory.
Definition: Instructions.h:290
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
Used to lazily calculate structure layout information for a target machine, based on the DataLayout s...
Definition: DataLayout.h:622
TypeSize getElementOffset(unsigned Idx) const
Definition: DataLayout.h:651
TypeSize getElementOffsetInBits(unsigned Idx) const
Definition: DataLayout.h:656
Class to represent struct types.
Definition: DerivedTypes.h:216
unsigned getNumElements() const
Random access to the elements.
Definition: DerivedTypes.h:341
Type * getElementType(unsigned N) const
Definition: DerivedTypes.h:342
Multiway switch.
Analysis pass providing the TargetTransformInfo.
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
bool areTypesABICompatible(const Function *Caller, const Function *Callee, const ArrayRef< Type * > &Types) const
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
unsigned getIntegerBitWidth() const
bool isPointerTy() const
True if this is an instance of PointerType.
Definition: Type.h:255
static IntegerType * getInt1Ty(LLVMContext &C)
unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
Definition: Type.h:302
static IntegerType * getInt8Ty(LLVMContext &C)
bool isPtrOrPtrVectorTy() const
Return true if this is a pointer type or a vector of pointer types.
Definition: Type.h:262
static IntegerType * getInt32Ty(LLVMContext &C)
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition: Type.h:228
bool isVoidTy() const
Return true if this is 'void'.
Definition: Type.h:140
'undef' values are things that do not have specified contents.
Definition: Constants.h:1385
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
Definition: Constants.cpp:1833
This function has undefined behavior.
A Use represents the edge between a Value definition and its users.
Definition: Use.h:43
User * getUser() const
Returns the User that contains this Use.
Definition: Use.h:72
bool replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
Definition: User.cpp:21
const Use & getOperandUse(unsigned i) const
Definition: User.h:182
Value * getOperand(unsigned i) const
Definition: User.h:169
unsigned getNumOperands() const
Definition: User.h:191
bool isDroppable() const
A droppable user is a user for which uses can be dropped without affecting correctness and should be ...
Definition: User.cpp:115
ValueT lookup(const KeyT &Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
Definition: ValueMap.h:164
LLVM Value Representation.
Definition: Value.h:74
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:807
const Value * stripAndAccumulateConstantOffsets(const DataLayout &DL, APInt &Offset, bool AllowNonInbounds, bool AllowInvariantGroup=false, function_ref< bool(Value &Value, APInt &Offset)> ExternalAnalysis=nullptr) const
Accumulate the constant offset this value has compared to a base pointer.
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition: Value.cpp:534
iterator_range< user_iterator > users()
Definition: Value.h:421
LLVMContext & getContext() const
All values hold a context through their type.
Definition: Value.cpp:1075
iterator_range< use_iterator > uses()
Definition: Value.h:376
StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:309
std::pair< iterator, bool > insert(const ValueT &V)
Definition: DenseSet.h:206
constexpr ScalarTy getFixedValue() const
Definition: TypeSize.h:202
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
Definition: TypeSize.h:171
An efficient, type-erasing, non-owning reference to a callable.
const ParentTy * getParent() const
Definition: ilist_node.h:32
self_iterator getIterator()
Definition: ilist_node.h:132
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
Definition: ilist_node.h:353
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:661
Enumerate the SCCs of a directed graph in reverse topological order of the SCC DAG.
Definition: SCCIterator.h:49
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool isAssumedReadNone(Attributor &A, const IRPosition &IRP, const AbstractAttribute &QueryingAA, bool &IsKnown)
Return true if IRP is readnone.
Definition: Attributor.cpp:654
bool isAssumedReadOnly(Attributor &A, const IRPosition &IRP, const AbstractAttribute &QueryingAA, bool &IsKnown)
Return true if IRP is readonly.
Definition: Attributor.cpp:649
raw_ostream & operator<<(raw_ostream &OS, const RangeTy &R)
Definition: Attributor.h:314
std::optional< Value * > combineOptionalValuesInAAValueLatice(const std::optional< Value * > &A, const std::optional< Value * > &B, Type *Ty)
Return the combination of A and B such that the result is a possible value of both.
Definition: Attributor.cpp:340
bool isValidAtPosition(const ValueAndContext &VAC, InformationCache &InfoCache)
Return true if the value of VAC is a valid at the position of VAC, that is a constant,...
Definition: Attributor.cpp:291
bool isAssumedThreadLocalObject(Attributor &A, Value &Obj, const AbstractAttribute &QueryingAA)
Return true if Obj is assumed to be a thread local object.
Definition: Attributor.cpp:836
bool isDynamicallyUnique(Attributor &A, const AbstractAttribute &QueryingAA, const Value &V, bool ForAnalysisOnly=true)
Return true if V is dynamically unique, that is, there are no two "instances" of V at runtime with di...
Definition: Attributor.cpp:232
bool getPotentialCopiesOfStoredValue(Attributor &A, StoreInst &SI, SmallSetVector< Value *, 4 > &PotentialCopies, const AbstractAttribute &QueryingAA, bool &UsedAssumedInformation, bool OnlyExact=false)
Collect all potential values of the one stored by SI into PotentialCopies.
Definition: Attributor.cpp:600
bool isGPU(const Module &M)
Return true iff M target a GPU (and we can use GPU AS reasoning).
Definition: Attributor.cpp:201
ValueScope
Flags to distinguish intra-procedural queries from potentially inter-procedural queries.
Definition: Attributor.h:180
@ Intraprocedural
Definition: Attributor.h:181
@ Interprocedural
Definition: Attributor.h:182
bool isValidInScope(const Value &V, const Function *Scope)
Return true if V is a valid value in Scope, that is a constant or an instruction/argument of Scope.
Definition: Attributor.cpp:281
bool isPotentiallyReachable(Attributor &A, const Instruction &FromI, const Instruction &ToI, const AbstractAttribute &QueryingAA, const AA::InstExclusionSetTy *ExclusionSet=nullptr, std::function< bool(const Function &F)> GoBackwardsCB=nullptr)
Return true if ToI is potentially reachable from FromI without running into any instruction in Exclus...
Definition: Attributor.cpp:817
bool isNoSyncInst(Attributor &A, const Instruction &I, const AbstractAttribute &QueryingAA)
Return true if I is a nosync instruction.
Definition: Attributor.cpp:206
bool getPotentiallyLoadedValues(Attributor &A, LoadInst &LI, SmallSetVector< Value *, 4 > &PotentialValues, SmallSetVector< Instruction *, 4 > &PotentialValueOrigins, const AbstractAttribute &QueryingAA, bool &UsedAssumedInformation, bool OnlyExact=false)
Collect all potential values LI could read into PotentialValues.
Definition: Attributor.cpp:590
Value * getWithType(Value &V, Type &Ty)
Try to convert V to type Ty without introducing new instructions.
Definition: Attributor.cpp:317
constexpr char Attrs[]
Key for Kernel::Metadata::mAttrs.
AddressSpace getAddressSpace(T *V)
Definition: AVR.h:65
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
@ Unsupported
This operation is completely unsupported on the target.
@ Undef
Value of the register doesn't matter.
Offsets
Offsets in bytes from the start of the input buffer.
Definition: SIInstrInfo.h:1581
@ SingleThread
Synchronized with respect to signal handlers executing in the same thread.
Definition: LLVMContext.h:54
@ CE
Windows NT (Windows on ARM)
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:443
LocationClass< Ty > location(Ty &L)
Definition: CommandLine.h:463
unsigned combineHashValue(unsigned a, unsigned b)
Simplistic combination of 32-bit hash values into 32-bit hash values.
Definition: DenseMapInfo.h:39
ElementType
The element type of an SRV or UAV resource.
Definition: DXILABI.h:75
constexpr double e
Definition: MathExtras.h:47
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
Definition: Path.cpp:227
const_iterator end(StringRef path)
Get end iterator over path.
Definition: Path.cpp:236
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
pred_iterator pred_end(BasicBlock *BB)
Definition: CFG.h:114
@ Offset
Definition: DWP.cpp:480
@ Length
Definition: DWP.cpp:480
bool operator<(int64_t V1, const APSInt &V2)
Definition: APSInt.h:361
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt gcd(const DynamicAPInt &A, const DynamicAPInt &B)
Definition: DynamicAPInt.h:388
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:1722
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.
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:1680
unsigned getPointerAddressSpace(const Type *T)
Definition: SPIRVUtils.h:126
auto successors(const MachineBasicBlock *BB)
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:1440
raw_fd_ostream & outs()
This returns a reference to a raw_fd_ostream for standard output.
bool operator!=(uint64_t V1, const APInt &V2)
Definition: APInt.h:2062
UseCaptureKind DetermineUseCaptureKind(const Use &U, llvm::function_ref< bool(Value *, const DataLayout &)> IsDereferenceableOrNull)
Determine what kind of capture behaviour U may exhibit.
Value * getAllocAlignment(const CallBase *V, const TargetLibraryInfo *TLI)
Gets the alignment argument for an aligned_alloc-like function, using either built-in knowledge based...
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.
const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=6)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
scc_iterator< T > scc_begin(const T &G)
Construct the begin iterator for a deduced graph type T.
Definition: SCCIterator.h:233
PotentialValuesState< std::pair< AA::ValueAndContext, AA::ValueScope > > PotentialLLVMValuesState
Definition: Attributor.h:5214
bool isNoAliasCall(const Value *V)
Return true if this pointer is returned by a noalias function.
raw_ostream & WriteGraph(raw_ostream &O, const GraphType &G, bool ShortNames=false, const Twine &Title="")
Definition: GraphWriter.h:359
auto unique(Range &&R, Predicate P)
Definition: STLExtras.h:2013
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
ConstantRange getConstantRangeFromMetadata(const MDNode &RangeMD)
Parse out a conservative ConstantRange from !range metadata.
@ NONE
Definition: Attributor.h:6417
const Value * getPointerOperand(const Value *V)
A helper function that returns the pointer operand of a load, store or GEP instruction.
Value * simplifyInstruction(Instruction *I, const SimplifyQuery &Q)
See if we can compute a simplified version of this instruction.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1729
pred_iterator pred_begin(BasicBlock *BB)
Definition: CFG.h:110
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:340
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition: MathExtras.h:291
void sort(IteratorTy Start, IteratorTy End)
Definition: STLExtras.h:1647
MemoryEffectsBase< IRMemLocation > MemoryEffects
Summary of how a function affects memory in the program.
Definition: ModRef.h:268
bool NullPointerIsDefined(const Function *F, unsigned AS=0)
Check whether null pointer dereferencing is considered undefined behavior for a given function or an ...
Definition: Function.cpp:2102
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
bool isPointerTy(const Type *T)
Definition: SPIRVUtils.h:120
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:419
bool isSafeToSpeculativelyExecute(const Instruction *I, const Instruction *CtxI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr, const TargetLibraryInfo *TLI=nullptr, bool UseVariableInfo=true)
Return true if the instruction does not have any effects besides calculating the result and does not ...
bool set_union(S1Ty &S1, const S2Ty &S2)
set_union(A, B) - Compute A := A u B, return whether A changed.
Definition: SetOperations.h:43
void RemapInstruction(Instruction *I, ValueToValueMapTy &VM, RemapFlags Flags=RF_None, ValueMapTypeRemapper *TypeMapper=nullptr, ValueMaterializer *Materializer=nullptr)
Convert the instruction operands from referencing the current values into those specified by VM.
Definition: ValueMapper.h:263
CallBase & promoteCall(CallBase &CB, Function *Callee, CastInst **RetBitCast=nullptr)
Promote the given indirect call site to unconditionally call Callee.
bool hasAssumption(const Function &F, const KnownAssumptionString &AssumptionStr)
Return true if F has the assumption AssumptionStr attached.
Definition: Assumptions.cpp:70
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.
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.
ChangeStatus clampStateAndIndicateChange< DerefState >(DerefState &S, const DerefState &R)
Value * simplifyCmpInst(unsigned Predicate, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for a CmpInst, fold the result or return null.
PotentialValuesState< APInt > PotentialConstantIntValuesState
Definition: Attributor.h:5212
DWARFExpression::Operation Op
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.
Value * getFreedOperand(const CallBase *CB, const TargetLibraryInfo *TLI)
If this if a call to a free function, return the freed operand.
ChangeStatus clampStateAndIndicateChange(StateType &S, const StateType &R)
Helper function to clamp a state S of type StateType with the information in R and indicate/return if...
Definition: Attributor.h:3455
constexpr unsigned BitWidth
Definition: BitmaskEnum.h:191
ChangeStatus
{
Definition: Attributor.h:484
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.
DenseSet< StringRef > getAssumptions(const Function &F)
Return the set of all assumptions for the function F.
Definition: Assumptions.cpp:86
Align assumeAligned(uint64_t Value)
Treats the value 0 as a 1, so Align is always at least 1.
Definition: Alignment.h:111
Instruction * SplitBlockAndInsertIfThen(Value *Cond, BasicBlock::iterator SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, BasicBlock *ThenBlock=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...
@ OPTIONAL
The target may be valid if the source is not.
@ NONE
Do not track a dependence between source and target.
@ REQUIRED
The target cannot be valid if the source is not.
bool mayContainIrreducibleControl(const Function &F, const LoopInfo *LI)
T bit_floor(T Value)
Returns the largest integral power of two no greater than Value if Value is nonzero.
Definition: bit.h:327
KnownFPClass computeKnownFPClass(const Value *V, const APInt &DemandedElts, FPClassTest InterestedClasses, unsigned Depth, const SimplifyQuery &SQ)
Determine which floating-point classes are valid for V, and return them in KnownFPClass bit sets.
bool isIdentifiedObject(const Value *V)
Return true if this pointer refers to a distinct and identifiable object.
constexpr StringRef AssumptionAttrKey
The key we use for assumption attributes.
Definition: Assumptions.h:28
Implement std::hash so that hash_code can be used in STL containers.
Definition: BitVector.h:858
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition: BitVector.h:860
A type to track pointer/struct usage and accesses for AAPointerInfo.
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
bool forallInterferingAccesses(Instruction &I, function_ref< bool(const AAPointerInfo::Access &, bool)> CB, AA::RangeTy &Range) const
See AAPointerInfo::forallInterferingAccesses.
State(State &&SIS)=default
const AAPointerInfo::Access & getAccess(unsigned Index) const
bool forallInterferingAccesses(AA::RangeTy Range, function_ref< bool(const AAPointerInfo::Access &, bool)> CB) const
See AAPointerInfo::forallInterferingAccesses.
SmallVector< AAPointerInfo::Access > AccessList
bool isAtFixpoint() const override
See AbstractState::isAtFixpoint().
static State getWorstState(const State &SIS)
Return the worst possible representable state.
AAPointerInfo::OffsetBinsTy OffsetBins
ChangeStatus indicateOptimisticFixpoint() override
See AbstractState::indicateOptimisticFixpoint().
State & operator=(const State &R)
ChangeStatus indicatePessimisticFixpoint() override
See AbstractState::indicatePessimisticFixpoint().
static State getBestState(const State &SIS)
Return the best possible representable state.
bool isValidState() const override
See AbstractState::isValidState().
----------------—AAIntraFnReachability Attribute-----------------------—
ReachabilityQueryInfo(const ReachabilityQueryInfo &RQI)
unsigned Hash
Precomputed hash for this RQI.
ReachabilityQueryInfo(const Instruction *From, const ToTy *To)
ReachabilityQueryInfo(Attributor &A, const Instruction &From, const ToTy &To, const AA::InstExclusionSetTy *ES, bool MakeUnique)
Constructor replacement to ensure unique and stable sets are used for the cache.
An abstract interface for address space information.
Definition: Attributor.h:6228
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:6267
An abstract interface for all align attributes.
Definition: Attributor.h:4263
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:4294
Align getKnownAlign() const
Return known alignment.
Definition: Attributor.h:4277
static const char ID
Definition: Attributor.h:6302
An abstract attribute for getting assumption information.
Definition: Attributor.h:6154
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:6182
An abstract state for querying live call edges.
Definition: Attributor.h:5478
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:5521
An abstract Attribute for specializing "dynamic" components of "denormal-fp-math" and "denormal-fp-ma...
Definition: Attributor.h:6388
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:6410
An abstract interface for all dereferenceable attribute.
Definition: Attributor.h:4209
uint32_t getKnownDereferenceableBytes() const
Return known dereferenceable bytes.
Definition: Attributor.h:4233
uint32_t getAssumedDereferenceableBytes() const
Return assumed dereferenceable bytes.
Definition: Attributor.h:4228
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:4254
An abstract interface for llvm::GlobalValue information interference.
Definition: Attributor.h:6307
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:6341
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:4556
An abstract interface for indirect call information interference.
Definition: Attributor.h:6346
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:6382
An abstract interface to track if a value leaves it's defining function instance.
Definition: Attributor.h:4301
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:4334
An abstract Attribute for computing reachability between functions.
Definition: Attributor.h:5674
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:5709
bool canReach(Attributor &A, const Function &Fn) const
If the function represented by this possition can reach Fn.
Definition: Attributor.h:5680
virtual bool instructionCanReach(Attributor &A, const Instruction &Inst, const Function &Fn, const AA::InstExclusionSetTy *ExclusionSet=nullptr) const =0
Can Inst reach Fn.
An abstract interface to determine reachability of point A to B.
Definition: Attributor.h:3807
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:3835
virtual bool isAssumedReachable(Attributor &A, const Instruction &From, const Instruction &To, const AA::InstExclusionSetTy *ExclusionSet=nullptr) const =0
Returns true if 'From' instruction is assumed to reach, 'To' instruction.
An abstract interface for liveness abstract attribute.
Definition: Attributor.h:3967
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:4057
An abstract interface for memory access kind related attributes (readnone/readonly/writeonly).
Definition: Attributor.h:4621
bool isAssumedReadOnly() const
Return true if we assume that the underlying value is not accessed (=written) in its respective scope...
Definition: Attributor.h:4660
bool isKnownReadNone() const
Return true if we know that the underlying value is not read or accessed in its respective scope.
Definition: Attributor.h:4648
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:4687
bool isAssumedReadNone() const
Return true if we assume that the underlying value is not read or accessed in its respective scope.
Definition: Attributor.h:4652
An abstract interface for all memory location attributes (readnone/argmemonly/inaccessiblememonly/ina...
Definition: Attributor.h:4696
static std::string getMemoryLocationsAsStr(MemoryLocationsKind MLK)
Return the locations encoded by MLK as a readable string.
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:4872
StateType::base_t MemoryLocationsKind
Definition: Attributor.h:4697
An abstract interface for all nonnull attributes.
Definition: Attributor.h:3583
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:3618
An abstract interface for all noalias attributes.
Definition: Attributor.h:3842
static bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
See IRAttribute::isImpliedByIR.
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:3881
An abstract interface for all nocapture attributes.
Definition: Attributor.h:4342
@ NO_CAPTURE_MAYBE_RETURNED
If we do not capture the value in memory or through integers we can only communicate it back as a der...
Definition: Attributor.h:4372
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:4415
bool isAssumedNoCaptureMaybeReturned() const
Return true if we assume that the underlying value is not captured in its respective scope but we all...
Definition: Attributor.h:4396
static bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
See IRAttribute::isImpliedByIR.
static void determineFunctionCaptureCapabilities(const IRPosition &IRP, const Function &F, BitIntegerState &State)
Update State according to the capture capabilities of F for position IRP.
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:5432
An AbstractAttribute for nofree.
Definition: Attributor.h:3888
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:3931
An abstract attribute for norecurse.
Definition: Attributor.h:3676
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:3700
An AbstractAttribute for noreturn.
Definition: Attributor.h:3938
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:3962
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:3576
static bool isAlignedBarrier(const CallBase &CB, bool ExecutedAligned)
Helper function to determine if CB is an aligned (GPU) barrier.
static bool isNonRelaxedAtomic(const Instruction *I)
Helper function used to determine whether an instruction is non-relaxed atomic.
static bool isNoSyncIntrinsic(const Instruction *I)
Helper function specific for intrinsics which are potentially volatile.
An abstract interface for all noundef attributes.
Definition: Attributor.h:5346
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:5381
static bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
See IRAttribute::isImpliedByIR.
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:3493
An abstract Attribute for determining the necessity of the convergent attribute.
Definition: Attributor.h:5714
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:5742
bool isAssumedNotConvergent() const
Return true if "non-convergent" is assumed.
Definition: Attributor.h:5724
An abstract interface for all nonnull attributes.
Definition: Attributor.h:3625
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:3669
static bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
See AbstractAttribute::isImpliedByIR(...).
An access description.
Definition: Attributor.h:5932
A container for a list of ranges.
Definition: Attributor.h:5781
static void set_difference(const RangeList &L, const RangeList &R, RangeList &D)
Copy ranges from L that are not in R, into D.
Definition: Attributor.h:5817
An abstract interface for struct information.
Definition: Attributor.h:5746
virtual const_bin_iterator begin() const =0
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:6146
virtual int64_t numOffsetBins() const =0
An abstract interface for potential values analysis.
Definition: Attributor.h:5236
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:5295
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:5332
static Value * getSingleValue(Attributor &A, const AbstractAttribute &AA, const IRPosition &IRP, SmallVectorImpl< AA::ValueAndContext > &Values)
Extract the single value in Values if any.
An abstract interface for privatizability.
Definition: Attributor.h:4570
virtual std::optional< Type * > getPrivatizableType() const =0
Return the type we can choose for a private copy of the underlying value.
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:4612
An abstract attribute for undefined behavior.
Definition: Attributor.h:3769
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:3802
An abstract attribute for getting all assumption underlying objects.
Definition: Attributor.h:6186
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:6216
An abstract interface for range value analysis.
Definition: Attributor.h:4877
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:4940
An abstract interface for value simplify abstract attribute.
Definition: Attributor.h:4494
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:4516
An abstract attribute for willreturn.
Definition: Attributor.h:3707
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:3764
Helper to represent an access offset and size, with logic to deal with uncertainty and check for over...
Definition: Attributor.h:237
static constexpr int64_t Unknown
Definition: Attributor.h:311
static RangeTy getUnknown()
Definition: Attributor.h:243
Base struct for all "concrete attribute" deductions.
Definition: Attributor.h:3275
void print(raw_ostream &OS) const
Helper functions, for debug purposes only.
Definition: Attributor.h:3359
virtual StateType & getState()=0
Return the internal abstract state for inspection.
An interface to query the internal state of an abstract attribute.
Definition: Attributor.h:2595
virtual ChangeStatus indicatePessimisticFixpoint()=0
Indicate that the abstract state should converge to the pessimistic state.
virtual bool isValidState() const =0
Return if this abstract state is in a valid state.
virtual ChangeStatus indicateOptimisticFixpoint()=0
Indicate that the abstract state should converge to the optimistic state.
Helper for AA::PointerInfo::Access DenseMap/Set usage ignoring everythign but the instruction.
static unsigned getHashValue(const Access &A)
static Access getTombstoneKey()
static bool isEqual(const Access &LHS, const Access &RHS)
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
uint64_t value() const
This is a hole in the type system and should not be abused.
Definition: Alignment.h:85
Helper struct used in the communication between an abstract attribute (AA) that wants to change the s...
Definition: Attributor.h:2203
std::function< void(const ArgumentReplacementInfo &, AbstractCallSite, SmallVectorImpl< Value * > &)> ACSRepairCBTy
Abstract call site (ACS) repair callback type.
Definition: Attributor.h:2226
const Argument & getReplacedArg() const
Definition: Attributor.h:2233
std::function< void(const ArgumentReplacementInfo &, Function &, Function::arg_iterator)> CalleeRepairCBTy
Callee repair callback type.
Definition: Attributor.h:2212
The fixpoint analysis framework that orchestrates the attribute deduction.
Definition: Attributor.h:1508
std::function< std::optional< Value * >(const IRPosition &, const AbstractAttribute *, bool &)> SimplifictionCallbackTy
Register CB as a simplification callback.
Definition: Attributor.h:2008
Specialization of the integer state for a bit-wise encoding.
Definition: Attributor.h:2736
BitIntegerState & removeAssumedBits(base_t BitsEncoding)
Remove the bits in BitsEncoding from the "assumed bits" if not known.
Definition: Attributor.h:2761
BitIntegerState & addKnownBits(base_t Bits)
Add the bits in BitsEncoding to the "known bits".
Definition: Attributor.h:2753
Simple wrapper for a single bit (boolean) state.
Definition: Attributor.h:2879
Represent subnormal handling kind for floating point instruction inputs and outputs.
static constexpr DenormalMode getDefault()
Return the assumed default mode for a function without denormal-fp-math.
static constexpr DenormalMode getInvalid()
static unsigned getHashValue(const Access &A)
static bool isEqual(const Access &LHS, const Access &RHS)
static bool isEqual(const AA::RangeTy &A, const AA::RangeTy B)
static unsigned getHashValue(const AA::RangeTy &Range)
static ReachabilityQueryInfo< ToTy > * getEmptyKey()
static ReachabilityQueryInfo< ToTy > * getTombstoneKey()
static bool isEqual(const ReachabilityQueryInfo< ToTy > *LHS, const ReachabilityQueryInfo< ToTy > *RHS)
static unsigned getHashValue(const ReachabilityQueryInfo< ToTy > *RQI)
An information struct used to provide DenseMap with the various necessary components for a given valu...
Definition: DenseMapInfo.h:52
State for dereferenceable attribute.
Definition: Attributor.h:4063
IncIntegerState DerefBytesState
State representing for dereferenceable bytes.
Definition: Attributor.h:4079
ChangeStatus manifest(Attributor &A) override
See AbstractAttribute::manifest(...).
Definition: Attributor.h:3212
Helper to describe and deal with positions in the LLVM-IR.
Definition: Attributor.h:581
Function * getAssociatedFunction() const
Return the associated function, if any.
Definition: Attributor.h:712
static const IRPosition callsite_returned(const CallBase &CB)
Create a position describing the returned value of CB.
Definition: Attributor.h:649
static const IRPosition returned(const Function &F, const CallBaseContext *CBContext=nullptr)
Create a position describing the returned value of F.
Definition: Attributor.h:631
Argument * getAssociatedArgument() const
Return the associated argument, if any.
Definition: Attributor.cpp:996
static const IRPosition value(const Value &V, const CallBaseContext *CBContext=nullptr)
Create a position describing the value of V.
Definition: Attributor.h:605
int getCalleeArgNo() const
Return the callee argument number of the associated value if it is an argument or call site argument,...
Definition: Attributor.h:799
static const IRPosition inst(const Instruction &I, const CallBaseContext *CBContext=nullptr)
Create a position describing the instruction I.
Definition: Attributor.h:617
static const IRPosition callsite_argument(const CallBase &CB, unsigned ArgNo)
Create a position describing the argument of CB at position ArgNo.
Definition: Attributor.h:654
@ IRP_ARGUMENT
An attribute for a function argument.
Definition: Attributor.h:595
@ IRP_RETURNED
An attribute for the function return value.
Definition: Attributor.h:591
@ IRP_CALL_SITE
An attribute for a call site (function scope).
Definition: Attributor.h:594
@ IRP_CALL_SITE_RETURNED
An attribute for a call site return value.
Definition: Attributor.h:592
@ IRP_FUNCTION
An attribute for a function (scope).
Definition: Attributor.h:593
@ IRP_CALL_SITE_ARGUMENT
An attribute for a call site argument.
Definition: Attributor.h:596
@ IRP_INVALID
An invalid position.
Definition: Attributor.h:588
Instruction * getCtxI() const
Return the context instruction, if any.
Definition: Attributor.h:765
static const IRPosition argument(const Argument &Arg, const CallBaseContext *CBContext=nullptr)
Create a position describing the argument Arg.
Definition: Attributor.h:638
Type * getAssociatedType() const
Return the type this abstract attribute is associated with.
Definition: Attributor.h:788
static const IRPosition function(const Function &F, const CallBaseContext *CBContext=nullptr)
Create a position describing the function scope of F.
Definition: Attributor.h:624
const CallBaseContext * getCallBaseContext() const
Get the call base context from the position.
Definition: Attributor.h:927
Value & getAssociatedValue() const
Return the value this abstract attribute is associated with.
Definition: Attributor.h:779
Value & getAnchorValue() const
Return the value this abstract attribute is anchored with.
Definition: Attributor.h:698
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:808
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:677
Kind getPositionKind() const
Return the associated position kind.
Definition: Attributor.h:877
bool isArgumentPosition() const
Return true if the position is an argument or call site argument.
Definition: Attributor.h:909
static const IRPosition callsite_function(const CallBase &CB)
Create a position describing the function scope of CB.
Definition: Attributor.h:644
Function * getAnchorScope() const
Return the Function surrounding the anchor value.
Definition: Attributor.h:753
Incoming for lane maks phi as machine instruction, incoming register Reg and incoming block Block are...
Data structure to hold cached (LLVM-IR) information.
Definition: Attributor.h:1198
bool isOnlyUsedByAssume(const Instruction &I) const
Definition: Attributor.h:1292
AP::Result * getAnalysisResultForFunction(const Function &F, bool CachedOnly=false)
Return the analysis result from a pass AP for function F.
Definition: Attributor.h:1302
State for an integer range.
Definition: Attributor.h:2921
ConstantRange getKnown() const
Return the known state encoding.
Definition: Attributor.h:2977
ConstantRange getAssumed() const
Return the assumed state encoding.
Definition: Attributor.h:2980
bool isValidState() const override
See AbstractState::isValidState() NOTE: For now we simply pretend that the worst possible state is in...
Definition: Attributor.h:2654
bool isAtFixpoint() const override
See AbstractState::isAtFixpoint()
Definition: Attributor.h:2657
ChangeStatus indicateOptimisticFixpoint() override
See AbstractState::indicateOptimisticFixpoint(...)
Definition: Attributor.h:2660
base_t getAssumed() const
Return the assumed state encoding.
Definition: Attributor.h:2675
static constexpr base_t getWorstState()
Return the worst possible representable state.
Definition: Attributor.h:2647
ChangeStatus indicatePessimisticFixpoint() override
See AbstractState::indicatePessimisticFixpoint(...)
Definition: Attributor.h:2666
Helper that allows to insert a new assumption string in the known assumption set by creating a (stati...
Definition: Assumptions.h:36
FPClassTest KnownFPClasses
Floating-point classes the value could be one of.
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Definition: Alignment.h:117
A "must be executed context" for a given program point PP is the set of instructions,...
Definition: MustExecute.h:386
iterator & end()
Return an universal end iterator.
Definition: MustExecute.h:434
bool findInContextOf(const Instruction *I, const Instruction *PP)
Helper to look for I in the context of PP.
Definition: MustExecute.h:470
iterator & begin(const Instruction *PP)
Return an iterator to explore the context around PP.
Definition: MustExecute.h:420
bool checkForAllContext(const Instruction *PP, function_ref< bool(const Instruction *)> Pred)
}
Definition: MustExecute.h:456
Various options to control the behavior of getObjectSize.
A class for a set state.
Definition: Attributor.h:4951
static unsigned MaxPotentialValues
Maximum number of potential values to be tracked.
Definition: Attributor.h:5004
void unionAssumed(const MemberTy &C)
Union assumed set with the passed value.
Definition: Attributor.h:5021
static PotentialValuesState getBestState()
Return empty set as the best state of potential values.
Definition: Attributor.h:5007
const SetTy & getAssumedSet() const
Return this set.
Definition: Attributor.h:4981
Represent one information held inside an operand bundle of an llvm.assume.
A MapVector that performs no allocations if smaller than a certain size.
Definition: MapVector.h:254
Helper to tie a abstract state implementation to an abstract attribute.
Definition: Attributor.h:3164
StateType & getState() override
See AbstractAttribute::getState(...).
Definition: Attributor.h:3172
bool unionAssumed(std::optional< Value * > Other)
Merge Other into the currently assumed simplified value.