LLVM 24.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"
18#include "llvm/ADT/DenseMap.h"
20#include "llvm/ADT/MapVector.h"
22#include "llvm/ADT/STLExtras.h"
24#include "llvm/ADT/SetVector.h"
27#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"
76#include <cassert>
77#include <numeric>
78#include <optional>
79#include <string>
80
81using namespace llvm;
82
83#define DEBUG_TYPE "attributor"
84
86 "attributor-manifest-internal", cl::Hidden,
87 cl::desc("Manifest Attributor internal string attributes."),
88 cl::init(false));
89
90static cl::opt<int> MaxHeapToStackSize("max-heap-to-stack-size", cl::init(128),
92
93template <>
95
97
99 "attributor-max-potential-values", cl::Hidden,
100 cl::desc("Maximum number of potential values to be "
101 "tracked for each position."),
103 cl::init(7));
104
106 "attributor-max-potential-values-iterations", cl::Hidden,
107 cl::desc(
108 "Maximum number of iterations we keep dismantling potential values."),
109 cl::init(64));
110
111STATISTIC(NumAAs, "Number of abstract attributes created");
112STATISTIC(NumIndirectCallsPromoted, "Number of indirect calls promoted");
113
114// Some helper macros to deal with statistics tracking.
115//
116// Usage:
117// For simple IR attribute tracking overload trackStatistics in the abstract
118// attribute and choose the right STATS_DECLTRACK_********* macro,
119// e.g.,:
120// void trackStatistics() const override {
121// STATS_DECLTRACK_ARG_ATTR(returned)
122// }
123// If there is a single "increment" side one can use the macro
124// STATS_DECLTRACK with a custom message. If there are multiple increment
125// sides, STATS_DECL and STATS_TRACK can also be used separately.
126//
127#define BUILD_STAT_MSG_IR_ATTR(TYPE, NAME) \
128 ("Number of " #TYPE " marked '" #NAME "'")
129#define BUILD_STAT_NAME(NAME, TYPE) NumIR##TYPE##_##NAME
130#define STATS_DECL_(NAME, MSG) STATISTIC(NAME, MSG);
131#define STATS_DECL(NAME, TYPE, MSG) \
132 STATS_DECL_(BUILD_STAT_NAME(NAME, TYPE), MSG);
133#define STATS_TRACK(NAME, TYPE) ++(BUILD_STAT_NAME(NAME, TYPE));
134#define STATS_DECLTRACK(NAME, TYPE, MSG) \
135 {STATS_DECL(NAME, TYPE, MSG) STATS_TRACK(NAME, TYPE)}
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
202
203#undef PIPE_OPERATOR
204
205template <>
207 const DerefState &R) {
208 ChangeStatus CS0 =
209 clampStateAndIndicateChange(S.DerefBytesState, R.DerefBytesState);
210 ChangeStatus CS1 = clampStateAndIndicateChange(S.GlobalState, R.GlobalState);
211 return CS0 | CS1;
212}
213
214} // namespace llvm
215
216static bool mayBeInCycle(const CycleInfo *CI, const Instruction *I,
217 bool HeaderOnly, CycleRef *CPtr = nullptr) {
218 if (!CI)
219 return true;
220 auto *BB = I->getParent();
221 CycleRef C = CI->getCycle(BB);
222 if (!C)
223 return false;
224 if (CPtr)
225 *CPtr = C;
226 return !HeaderOnly || BB == CI->getHeader(C);
227}
228
229/// Checks if a type could have padding bytes.
230static bool isDenselyPacked(Type *Ty, const DataLayout &DL) {
231 // There is no size information, so be conservative.
232 if (!Ty->isSized())
233 return false;
234
235 // If the alloc size is not equal to the storage size, then there are padding
236 // bytes. For x86_fp80 on x86-64, size: 80 alloc size: 128.
237 if (DL.getTypeSizeInBits(Ty) != DL.getTypeAllocSizeInBits(Ty))
238 return false;
239
240 // FIXME: This isn't the right way to check for padding in vectors with
241 // non-byte-size elements.
242 if (VectorType *SeqTy = dyn_cast<VectorType>(Ty))
243 return isDenselyPacked(SeqTy->getElementType(), DL);
244
245 // For array types, check for padding within members.
246 if (ArrayType *SeqTy = dyn_cast<ArrayType>(Ty))
247 return isDenselyPacked(SeqTy->getElementType(), DL);
248
249 if (!isa<StructType>(Ty))
250 return true;
251
252 // Check for padding within and between elements of a struct.
253 StructType *StructTy = cast<StructType>(Ty);
254 const StructLayout *Layout = DL.getStructLayout(StructTy);
255 uint64_t StartPos = 0;
256 for (unsigned I = 0, E = StructTy->getNumElements(); I < E; ++I) {
257 Type *ElTy = StructTy->getElementType(I);
258 if (!isDenselyPacked(ElTy, DL))
259 return false;
260 if (StartPos != Layout->getElementOffsetInBits(I))
261 return false;
262 StartPos += DL.getTypeAllocSizeInBits(ElTy);
263 }
264
265 // Check for tail padding.
266 return StartPos == Layout->getSizeInBits();
267}
268
269/// Get pointer operand of memory accessing instruction. If \p I is
270/// not a memory accessing instruction, return nullptr. If \p AllowVolatile,
271/// is set to false and the instruction is volatile, return nullptr.
273 bool AllowVolatile) {
274 if (!AllowVolatile && I->isVolatile())
275 return nullptr;
276
277 if (auto *LI = dyn_cast<LoadInst>(I)) {
278 return LI->getPointerOperand();
279 }
280
281 if (auto *SI = dyn_cast<StoreInst>(I)) {
282 return SI->getPointerOperand();
283 }
284
285 if (auto *CXI = dyn_cast<AtomicCmpXchgInst>(I)) {
286 return CXI->getPointerOperand();
287 }
288
289 if (auto *RMWI = dyn_cast<AtomicRMWInst>(I)) {
290 return RMWI->getPointerOperand();
291 }
292
293 return nullptr;
294}
295
296/// Helper function to create a pointer based on \p Ptr, and advanced by \p
297/// Offset bytes.
298static Value *constructPointer(Value *Ptr, int64_t Offset,
299 IRBuilder<NoFolder> &IRB) {
300 LLVM_DEBUG(dbgs() << "Construct pointer: " << *Ptr << " + " << Offset
301 << "-bytes\n");
302
303 if (Offset)
304 Ptr = IRB.CreatePtrAdd(Ptr, IRB.getInt64(Offset),
305 Ptr->getName() + ".b" + Twine(Offset));
306 return Ptr;
307}
308
309static const Value *
311 const Value *Val, const DataLayout &DL, APInt &Offset,
312 bool GetMinOffset, bool AllowNonInbounds,
313 bool UseAssumed = false) {
314
315 auto AttributorAnalysis = [&](Value &V, APInt &ROffset) -> bool {
316 const IRPosition &Pos = IRPosition::value(V);
317 // Only track dependence if we are going to use the assumed info.
318 const AAValueConstantRange *ValueConstantRangeAA =
319 A.getAAFor<AAValueConstantRange>(QueryingAA, Pos,
320 UseAssumed ? DepClassTy::OPTIONAL
322 if (!ValueConstantRangeAA)
323 return false;
324 ConstantRange Range = UseAssumed ? ValueConstantRangeAA->getAssumed()
325 : ValueConstantRangeAA->getKnown();
326 if (Range.isFullSet())
327 return false;
328
329 // We can only use the lower part of the range because the upper part can
330 // be higher than what the value can really be.
331 if (GetMinOffset)
332 ROffset = Range.getSignedMin();
333 else
334 ROffset = Range.getSignedMax();
335 return true;
336 };
337
338 return Val->stripAndAccumulateConstantOffsets(DL, Offset, AllowNonInbounds,
339 /* AllowInvariant */ true,
340 AttributorAnalysis);
341}
342
343static const Value *
345 const Value *Ptr, int64_t &BytesOffset,
346 const DataLayout &DL, bool AllowNonInbounds = false) {
347 APInt OffsetAPInt(DL.getIndexTypeSizeInBits(Ptr->getType()), 0);
348 const Value *Base =
349 stripAndAccumulateOffsets(A, QueryingAA, Ptr, DL, OffsetAPInt,
350 /* GetMinOffset */ true, AllowNonInbounds);
351
352 BytesOffset = OffsetAPInt.getSExtValue();
353 return Base;
354}
355
356/// Clamp the information known for all returned values of a function
357/// (identified by \p QueryingAA) into \p S.
358template <typename AAType, typename StateType = typename AAType::StateType,
359 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind,
360 bool RecurseForSelectAndPHI = true>
362 Attributor &A, const AAType &QueryingAA, StateType &S,
363 const IRPosition::CallBaseContext *CBContext = nullptr) {
364 LLVM_DEBUG(dbgs() << "[Attributor] Clamp return value states for "
365 << QueryingAA << " into " << S << "\n");
366
367 assert((QueryingAA.getIRPosition().getPositionKind() ==
369 QueryingAA.getIRPosition().getPositionKind() ==
371 "Can only clamp returned value states for a function returned or call "
372 "site returned position!");
373
374 // Use an optional state as there might not be any return values and we want
375 // to join (IntegerState::operator&) the state of all there are.
376 std::optional<StateType> T;
377
378 // Callback for each possibly returned value.
379 auto CheckReturnValue = [&](Value &RV) -> bool {
380 const IRPosition &RVPos = IRPosition::value(RV, CBContext);
381 // If possible, use the hasAssumedIRAttr interface.
382 if (Attribute::isEnumAttrKind(IRAttributeKind)) {
383 bool IsKnown;
385 A, &QueryingAA, RVPos, DepClassTy::REQUIRED, IsKnown);
386 }
387
388 const AAType *AA =
389 A.getAAFor<AAType>(QueryingAA, RVPos, DepClassTy::REQUIRED);
390 if (!AA)
391 return false;
392 LLVM_DEBUG(dbgs() << "[Attributor] RV: " << RV
393 << " AA: " << AA->getAsStr(&A) << " @ " << RVPos << "\n");
394 const StateType &AAS = AA->getState();
395 if (!T)
396 T = StateType::getBestState(AAS);
397 *T &= AAS;
398 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS << " RV State: " << T
399 << "\n");
400 return T->isValidState();
401 };
402
403 if (!A.checkForAllReturnedValues(CheckReturnValue, QueryingAA,
405 RecurseForSelectAndPHI))
406 S.indicatePessimisticFixpoint();
407 else if (T)
408 S ^= *T;
409}
410
411namespace {
412/// Helper class for generic deduction: return value -> returned position.
413template <typename AAType, typename BaseType,
414 typename StateType = typename BaseType::StateType,
415 bool PropagateCallBaseContext = false,
416 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind,
417 bool RecurseForSelectAndPHI = true>
418struct AAReturnedFromReturnedValues : public BaseType {
419 AAReturnedFromReturnedValues(const IRPosition &IRP, Attributor &A)
420 : BaseType(IRP, A) {}
421
422 /// See AbstractAttribute::updateImpl(...).
423 ChangeStatus updateImpl(Attributor &A) override {
424 StateType S(StateType::getBestState(this->getState()));
425 clampReturnedValueStates<AAType, StateType, IRAttributeKind,
426 RecurseForSelectAndPHI>(
427 A, *this, S,
428 PropagateCallBaseContext ? this->getCallBaseContext() : nullptr);
429 // TODO: If we know we visited all returned values, thus no are assumed
430 // dead, we can take the known information from the state T.
431 return clampStateAndIndicateChange<StateType>(this->getState(), S);
432 }
433};
434
435/// Clamp the information known at all call sites for a given argument
436/// (identified by \p QueryingAA) into \p S.
437template <typename AAType, typename StateType = typename AAType::StateType,
438 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind>
439static void clampCallSiteArgumentStates(Attributor &A, const AAType &QueryingAA,
440 StateType &S) {
441 LLVM_DEBUG(dbgs() << "[Attributor] Clamp call site argument states for "
442 << QueryingAA << " into " << S << "\n");
443
444 assert(QueryingAA.getIRPosition().getPositionKind() ==
446 "Can only clamp call site argument states for an argument position!");
447
448 // Use an optional state as there might not be any return values and we want
449 // to join (IntegerState::operator&) the state of all there are.
450 std::optional<StateType> T;
451
452 // The argument number which is also the call site argument number.
453 unsigned ArgNo = QueryingAA.getIRPosition().getCallSiteArgNo();
454
455 auto CallSiteCheck = [&](AbstractCallSite ACS) {
456 const IRPosition &ACSArgPos = IRPosition::callsite_argument(ACS, ArgNo);
457 // Check if a coresponding argument was found or if it is on not associated
458 // (which can happen for callback calls).
459 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
460 return false;
461
462 // If possible, use the hasAssumedIRAttr interface.
463 if (Attribute::isEnumAttrKind(IRAttributeKind)) {
464 bool IsKnown;
466 A, &QueryingAA, ACSArgPos, DepClassTy::REQUIRED, IsKnown);
467 }
468
469 const AAType *AA =
470 A.getAAFor<AAType>(QueryingAA, ACSArgPos, DepClassTy::REQUIRED);
471 if (!AA)
472 return false;
473 LLVM_DEBUG(dbgs() << "[Attributor] ACS: " << *ACS.getInstruction()
474 << " AA: " << AA->getAsStr(&A) << " @" << ACSArgPos
475 << "\n");
476 const StateType &AAS = AA->getState();
477 if (!T)
478 T = StateType::getBestState(AAS);
479 *T &= AAS;
480 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS << " CSA State: " << T
481 << "\n");
482 return T->isValidState();
483 };
484
485 bool UsedAssumedInformation = false;
486 if (!A.checkForAllCallSites(CallSiteCheck, QueryingAA, true,
487 UsedAssumedInformation))
488 S.indicatePessimisticFixpoint();
489 else if (T)
490 S ^= *T;
491}
492
493/// This function is the bridge between argument position and the call base
494/// context.
495template <typename AAType, typename BaseType,
496 typename StateType = typename AAType::StateType,
497 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind>
498bool getArgumentStateFromCallBaseContext(Attributor &A,
499 BaseType &QueryingAttribute,
500 IRPosition &Pos, StateType &State) {
502 "Expected an 'argument' position !");
503 const CallBase *CBContext = Pos.getCallBaseContext();
504 if (!CBContext)
505 return false;
506
507 int ArgNo = Pos.getCallSiteArgNo();
508 assert(ArgNo >= 0 && "Invalid Arg No!");
509 const IRPosition CBArgPos = IRPosition::callsite_argument(*CBContext, ArgNo);
510
511 // If possible, use the hasAssumedIRAttr interface.
512 if (Attribute::isEnumAttrKind(IRAttributeKind)) {
513 bool IsKnown;
515 A, &QueryingAttribute, CBArgPos, DepClassTy::REQUIRED, IsKnown);
516 }
517
518 const auto *AA =
519 A.getAAFor<AAType>(QueryingAttribute, CBArgPos, DepClassTy::REQUIRED);
520 if (!AA)
521 return false;
522 const StateType &CBArgumentState =
523 static_cast<const StateType &>(AA->getState());
524
525 LLVM_DEBUG(dbgs() << "[Attributor] Briding Call site context to argument"
526 << "Position:" << Pos << "CB Arg state:" << CBArgumentState
527 << "\n");
528
529 // NOTE: If we want to do call site grouping it should happen here.
530 State ^= CBArgumentState;
531 return true;
532}
533
534/// Helper class for generic deduction: call site argument -> argument position.
535template <typename AAType, typename BaseType,
536 typename StateType = typename AAType::StateType,
537 bool BridgeCallBaseContext = false,
538 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind>
539struct AAArgumentFromCallSiteArguments : public BaseType {
540 AAArgumentFromCallSiteArguments(const IRPosition &IRP, Attributor &A)
541 : BaseType(IRP, A) {}
542
543 /// See AbstractAttribute::updateImpl(...).
544 ChangeStatus updateImpl(Attributor &A) override {
545 StateType S = StateType::getBestState(this->getState());
546
547 if (BridgeCallBaseContext) {
548 bool Success =
549 getArgumentStateFromCallBaseContext<AAType, BaseType, StateType,
550 IRAttributeKind>(
551 A, *this, this->getIRPosition(), S);
552 if (Success)
553 return clampStateAndIndicateChange<StateType>(this->getState(), S);
554 }
555 clampCallSiteArgumentStates<AAType, StateType, IRAttributeKind>(A, *this,
556 S);
557
558 // TODO: If we know we visited all incoming values, thus no are assumed
559 // dead, we can take the known information from the state T.
560 return clampStateAndIndicateChange<StateType>(this->getState(), S);
561 }
562};
563
564/// Helper class for generic replication: function returned -> cs returned.
565template <typename AAType, typename BaseType,
566 typename StateType = typename BaseType::StateType,
567 bool IntroduceCallBaseContext = false,
568 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind>
569struct AACalleeToCallSite : public BaseType {
570 AACalleeToCallSite(const IRPosition &IRP, Attributor &A) : BaseType(IRP, A) {}
571
572 /// See AbstractAttribute::updateImpl(...).
573 ChangeStatus updateImpl(Attributor &A) override {
574 auto IRPKind = this->getIRPosition().getPositionKind();
576 IRPKind == IRPosition::IRP_CALL_SITE) &&
577 "Can only wrap function returned positions for call site "
578 "returned positions!");
579 auto &S = this->getState();
580
581 CallBase &CB = cast<CallBase>(this->getAnchorValue());
582 if (IntroduceCallBaseContext)
583 LLVM_DEBUG(dbgs() << "[Attributor] Introducing call base context:" << CB
584 << "\n");
585
586 ChangeStatus Changed = ChangeStatus::UNCHANGED;
587 auto CalleePred = [&](ArrayRef<const Function *> Callees) {
588 for (const Function *Callee : Callees) {
589 IRPosition FnPos =
591 ? IRPosition::returned(*Callee,
592 IntroduceCallBaseContext ? &CB : nullptr)
593 : IRPosition::function(
594 *Callee, IntroduceCallBaseContext ? &CB : nullptr);
595 // If possible, use the hasAssumedIRAttr interface.
596 if (Attribute::isEnumAttrKind(IRAttributeKind)) {
597 bool IsKnown;
599 A, this, FnPos, DepClassTy::REQUIRED, IsKnown))
600 return false;
601 continue;
602 }
603
604 const AAType *AA =
605 A.getAAFor<AAType>(*this, FnPos, DepClassTy::REQUIRED);
606 if (!AA)
607 return false;
608 Changed |= clampStateAndIndicateChange(S, AA->getState());
609 if (S.isAtFixpoint())
610 return S.isValidState();
611 }
612 return true;
613 };
614 if (!A.checkForAllCallees(CalleePred, *this, CB))
615 return S.indicatePessimisticFixpoint();
616 return Changed;
617 }
618};
619
620/// Helper function to accumulate uses.
621template <class AAType, typename StateType = typename AAType::StateType>
622static void followUsesInContext(AAType &AA, Attributor &A,
624 const Instruction *CtxI,
626 StateType &State) {
627 auto EIt = Explorer.begin(CtxI), EEnd = Explorer.end(CtxI);
628 for (unsigned u = 0; u < Uses.size(); ++u) {
629 const Use *U = Uses[u];
630 if (const Instruction *UserI = dyn_cast<Instruction>(U->getUser())) {
631 bool Found = Explorer.findInContextOf(UserI, EIt, EEnd);
632 if (Found && AA.followUseInMBEC(A, U, UserI, State))
633 Uses.insert_range(llvm::make_pointer_range(UserI->uses()));
634 }
635 }
636}
637
638/// Use the must-be-executed-context around \p I to add information into \p S.
639/// The AAType class is required to have `followUseInMBEC` method with the
640/// following signature and behaviour:
641///
642/// bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I)
643/// U - Underlying use.
644/// I - The user of the \p U.
645/// Returns true if the value should be tracked transitively.
646///
647template <class AAType, typename StateType = typename AAType::StateType>
648static void followUsesInMBEC(AAType &AA, Attributor &A, StateType &S,
649 Instruction &CtxI) {
650 const Value &Val = AA.getIRPosition().getAssociatedValue();
651 if (isa<ConstantData>(Val))
652 return;
653
655 A.getInfoCache().getMustBeExecutedContextExplorer();
656 if (!Explorer)
657 return;
658
659 // Container for (transitive) uses of the associated value.
661 for (const Use &U : Val.uses())
662 Uses.insert(&U);
663
664 followUsesInContext<AAType>(AA, A, *Explorer, &CtxI, Uses, S);
665
666 if (S.isAtFixpoint())
667 return;
668
670 auto Pred = [&](const Instruction *I) {
671 if (const CondBrInst *Br = dyn_cast<CondBrInst>(I))
672 BrInsts.push_back(Br);
673 return true;
674 };
675
676 // Here, accumulate conditional branch instructions in the context. We
677 // explore the child paths and collect the known states. The disjunction of
678 // those states can be merged to its own state. Let ParentState_i be a state
679 // to indicate the known information for an i-th branch instruction in the
680 // context. ChildStates are created for its successors respectively.
681 //
682 // ParentS_1 = ChildS_{1, 1} /\ ChildS_{1, 2} /\ ... /\ ChildS_{1, n_1}
683 // ParentS_2 = ChildS_{2, 1} /\ ChildS_{2, 2} /\ ... /\ ChildS_{2, n_2}
684 // ...
685 // ParentS_m = ChildS_{m, 1} /\ ChildS_{m, 2} /\ ... /\ ChildS_{m, n_m}
686 //
687 // Known State |= ParentS_1 \/ ParentS_2 \/... \/ ParentS_m
688 //
689 // FIXME: Currently, recursive branches are not handled. For example, we
690 // can't deduce that ptr must be dereferenced in below function.
691 //
692 // void f(int a, int c, int *ptr) {
693 // if(a)
694 // if (b) {
695 // *ptr = 0;
696 // } else {
697 // *ptr = 1;
698 // }
699 // else {
700 // if (b) {
701 // *ptr = 0;
702 // } else {
703 // *ptr = 1;
704 // }
705 // }
706 // }
707
708 Explorer->checkForAllContext(&CtxI, Pred);
709 for (const CondBrInst *Br : BrInsts) {
710 StateType ParentState;
711
712 // The known state of the parent state is a conjunction of children's
713 // known states so it is initialized with a best state.
714 ParentState.indicateOptimisticFixpoint();
715
716 for (const BasicBlock *BB : Br->successors()) {
717 StateType ChildState;
718
719 size_t BeforeSize = Uses.size();
720 followUsesInContext(AA, A, *Explorer, &BB->front(), Uses, ChildState);
721
722 // Erase uses which only appear in the child.
723 for (auto It = Uses.begin() + BeforeSize; It != Uses.end();)
724 It = Uses.erase(It);
725
726 ParentState &= ChildState;
727 }
728
729 // Use only known state.
730 S += ParentState;
731 }
732}
733} // namespace
734
735/// ------------------------ PointerInfo ---------------------------------------
736
737namespace llvm {
738namespace AA {
739namespace PointerInfo {
740
741struct State;
742
743} // namespace PointerInfo
744} // namespace AA
745
746/// Helper for AA::PointerInfo::Access DenseMap/Set usage.
747template <>
750 static unsigned getHashValue(const Access &A);
751 static bool isEqual(const Access &LHS, const Access &RHS);
752};
753
754/// Helper that allows RangeTy as a key in a DenseMap.
755template <> struct DenseMapInfo<AA::RangeTy> {
761
762 static bool isEqual(const AA::RangeTy &A, const AA::RangeTy B) {
763 return A == B;
764 }
765};
766
767} // namespace llvm
768
769/// A type to track pointer/struct usage and accesses for AAPointerInfo.
771 /// Return the best possible representable state.
772 static State getBestState(const State &SIS) { return State(); }
773
774 /// Return the worst possible representable state.
775 static State getWorstState(const State &SIS) {
776 State R;
777 R.indicatePessimisticFixpoint();
778 return R;
779 }
780
781 State() = default;
782 State(State &&SIS) = default;
783
784 const State &getAssumed() const { return *this; }
785
786 /// See AbstractState::isValidState().
787 bool isValidState() const override { return BS.isValidState(); }
788
789 /// See AbstractState::isAtFixpoint().
790 bool isAtFixpoint() const override { return BS.isAtFixpoint(); }
791
792 /// See AbstractState::indicateOptimisticFixpoint().
794 BS.indicateOptimisticFixpoint();
796 }
797
798 /// See AbstractState::indicatePessimisticFixpoint().
800 BS.indicatePessimisticFixpoint();
802 }
803
804 State &operator=(const State &R) {
805 if (this == &R)
806 return *this;
807 BS = R.BS;
808 AccessList = R.AccessList;
809 OffsetBins = R.OffsetBins;
810 RemoteIMap = R.RemoteIMap;
811 ReturnedOffsets = R.ReturnedOffsets;
812 return *this;
813 }
814
816 if (this == &R)
817 return *this;
818 std::swap(BS, R.BS);
819 std::swap(AccessList, R.AccessList);
820 std::swap(OffsetBins, R.OffsetBins);
821 std::swap(RemoteIMap, R.RemoteIMap);
822 std::swap(ReturnedOffsets, R.ReturnedOffsets);
823 return *this;
824 }
825
826 /// Add a new Access to the state at offset \p Offset and with size \p Size.
827 /// The access is associated with \p I, writes \p Content (if anything), and
828 /// is of kind \p Kind. If an Access already exists for the same \p I and same
829 /// \p RemoteI, the two are combined, potentially losing information about
830 /// offset and size. The resulting access must now be moved from its original
831 /// OffsetBin to the bin for its new offset.
832 ///
833 /// \Returns CHANGED, if the state changed, UNCHANGED otherwise.
835 Instruction &I, std::optional<Value *> Content,
837 Instruction *RemoteI = nullptr);
838
841 int64_t numOffsetBins() const { return OffsetBins.size(); }
842
843 const AAPointerInfo::Access &getAccess(unsigned Index) const {
844 return AccessList[Index];
845 }
846
847protected:
848 // Every memory instruction results in an Access object. We maintain a list of
849 // all Access objects that we own, along with the following maps:
850 //
851 // - OffsetBins: RangeTy -> { Access }
852 // - RemoteIMap: RemoteI x LocalI -> Access
853 //
854 // A RemoteI is any instruction that accesses memory. RemoteI is different
855 // from LocalI if and only if LocalI is a call; then RemoteI is some
856 // instruction in the callgraph starting from LocalI. Multiple paths in the
857 // callgraph from LocalI to RemoteI may produce multiple accesses, but these
858 // are all combined into a single Access object. This may result in loss of
859 // information in RangeTy in the Access object.
863
864 /// Flag to determine if the underlying pointer is reaching a return statement
865 /// in the associated function or not. Returns in other functions cause
866 /// invalidation.
868
869 /// See AAPointerInfo::forallInterferingAccesses.
870 template <typename F>
872 if (!isValidState() || !ReturnedOffsets.isUnassigned())
873 return false;
874
875 for (const auto &It : OffsetBins) {
876 AA::RangeTy ItRange = It.getFirst();
877 if (!Range.mayOverlap(ItRange))
878 continue;
879 bool IsExact = Range == ItRange && !Range.offsetOrSizeAreUnknown();
880 for (auto Index : It.getSecond()) {
881 auto &Access = AccessList[Index];
882 if (!CB(Access, IsExact))
883 return false;
884 }
885 }
886 return true;
887 }
888
889 /// See AAPointerInfo::forallInterferingAccesses.
890 template <typename F>
892 AA::RangeTy &Range) const {
893 if (!isValidState() || !ReturnedOffsets.isUnassigned())
894 return false;
895
896 auto LocalList = RemoteIMap.find(&I);
897 if (LocalList == RemoteIMap.end()) {
898 return true;
899 }
900
901 for (unsigned Index : LocalList->getSecond()) {
902 for (auto &R : AccessList[Index]) {
903 Range &= R;
904 if (Range.offsetAndSizeAreUnknown())
905 break;
906 }
907 }
909 }
910
911private:
912 /// State to track fixpoint and validity.
913 BooleanState BS;
914};
915
918 std::optional<Value *> Content, AAPointerInfo::AccessKind Kind, Type *Ty,
919 Instruction *RemoteI) {
920 RemoteI = RemoteI ? RemoteI : &I;
921
922 // Check if we have an access for this instruction, if not, simply add it.
923 auto &LocalList = RemoteIMap[RemoteI];
924 bool AccExists = false;
925 unsigned AccIndex = AccessList.size();
926 for (auto Index : LocalList) {
927 auto &A = AccessList[Index];
928 if (A.getLocalInst() == &I) {
929 AccExists = true;
930 AccIndex = Index;
931 break;
932 }
933 }
934
935 auto AddToBins = [&](const AAPointerInfo::RangeList &ToAdd) {
936 LLVM_DEBUG(if (ToAdd.size()) dbgs()
937 << "[AAPointerInfo] Inserting access in new offset bins\n";);
938
939 for (auto Key : ToAdd) {
940 LLVM_DEBUG(dbgs() << " key " << Key << "\n");
941 OffsetBins[Key].insert(AccIndex);
942 }
943 };
944
945 if (!AccExists) {
946 AccessList.emplace_back(&I, RemoteI, Ranges, Content, Kind, Ty);
947 assert((AccessList.size() == AccIndex + 1) &&
948 "New Access should have been at AccIndex");
949 LocalList.push_back(AccIndex);
950 AddToBins(AccessList[AccIndex].getRanges());
952 }
953
954 // Combine the new Access with the existing Access, and then update the
955 // mapping in the offset bins.
956 AAPointerInfo::Access Acc(&I, RemoteI, Ranges, Content, Kind, Ty);
957 auto &Current = AccessList[AccIndex];
958 auto Before = Current;
959 Current &= Acc;
960 if (Current == Before)
962
963 auto &ExistingRanges = Before.getRanges();
964 auto &NewRanges = Current.getRanges();
965
966 // Ranges that are in the old access but not the new access need to be removed
967 // from the offset bins.
969 AAPointerInfo::RangeList::set_difference(ExistingRanges, NewRanges, ToRemove);
970 LLVM_DEBUG(if (ToRemove.size()) dbgs()
971 << "[AAPointerInfo] Removing access from old offset bins\n";);
972
973 for (auto Key : ToRemove) {
974 LLVM_DEBUG(dbgs() << " key " << Key << "\n");
975 assert(OffsetBins.count(Key) && "Existing Access must be in some bin.");
976 auto &Bin = OffsetBins[Key];
977 assert(Bin.count(AccIndex) &&
978 "Expected bin to actually contain the Access.");
979 Bin.erase(AccIndex);
980 }
981
982 // Ranges that are in the new access but not the old access need to be added
983 // to the offset bins.
985 AAPointerInfo::RangeList::set_difference(NewRanges, ExistingRanges, ToAdd);
986 AddToBins(ToAdd);
988}
989
990namespace {
991
992#ifndef NDEBUG
994 const AAPointerInfo::OffsetInfo &OI) {
995 OS << llvm::interleaved_array(OI);
996 return OS;
997}
998#endif // NDEBUG
999
1000struct AAPointerInfoImpl
1001 : public StateWrapper<AA::PointerInfo::State, AAPointerInfo> {
1003 AAPointerInfoImpl(const IRPosition &IRP, Attributor &A) : BaseTy(IRP) {}
1004
1005 /// See AbstractAttribute::getAsStr().
1006 const std::string getAsStr(Attributor *A) const override {
1007 return std::string("PointerInfo ") +
1008 (isValidState() ? (std::string("#") +
1009 std::to_string(OffsetBins.size()) + " bins")
1010 : "<invalid>") +
1011 (reachesReturn()
1012 ? (" (returned:" +
1013 join(map_range(ReturnedOffsets,
1014 [](int64_t O) { return std::to_string(O); }),
1015 ", ") +
1016 ")")
1017 : "");
1018 }
1019
1020 /// See AbstractAttribute::manifest(...).
1021 ChangeStatus manifest(Attributor &A) override {
1022 return AAPointerInfo::manifest(A);
1023 }
1024
1025 const_bin_iterator begin() const override { return State::begin(); }
1026 const_bin_iterator end() const override { return State::end(); }
1027 int64_t numOffsetBins() const override { return State::numOffsetBins(); }
1028 bool reachesReturn() const override {
1029 return !ReturnedOffsets.isUnassigned();
1030 }
1031 void addReturnedOffsetsTo(OffsetInfo &OI) const override {
1032 if (ReturnedOffsets.isUnknown()) {
1033 OI.setUnknown();
1034 return;
1035 }
1036
1037 OffsetInfo MergedOI;
1038 for (auto Offset : ReturnedOffsets) {
1039 OffsetInfo TmpOI = OI;
1040 TmpOI.addToAll(Offset);
1041 MergedOI.merge(TmpOI);
1042 }
1043 OI = std::move(MergedOI);
1044 }
1045
1046 ChangeStatus setReachesReturn(const OffsetInfo &ReachedReturnedOffsets) {
1047 if (ReturnedOffsets.isUnknown())
1048 return ChangeStatus::UNCHANGED;
1049 if (ReachedReturnedOffsets.isUnknown()) {
1050 ReturnedOffsets.setUnknown();
1051 return ChangeStatus::CHANGED;
1052 }
1053 if (ReturnedOffsets.merge(ReachedReturnedOffsets))
1054 return ChangeStatus::CHANGED;
1055 return ChangeStatus::UNCHANGED;
1056 }
1057
1058 bool forallInterferingAccesses(
1059 AA::RangeTy Range,
1060 function_ref<bool(const AAPointerInfo::Access &, bool)> CB)
1061 const override {
1062 return State::forallInterferingAccesses(Range, CB);
1063 }
1064
1065 bool forallInterferingAccesses(
1066 Attributor &A, const AbstractAttribute &QueryingAA, Instruction &I,
1067 bool FindInterferingWrites, bool FindInterferingReads,
1068 function_ref<bool(const Access &, bool)> UserCB, bool &HasBeenWrittenTo,
1069 AA::RangeTy &Range,
1070 function_ref<bool(const Access &)> SkipCB) const override {
1071 HasBeenWrittenTo = false;
1072
1073 SmallPtrSet<const Access *, 8> DominatingWrites;
1074 SmallVector<std::pair<const Access *, bool>, 8> InterferingAccesses;
1075
1076 Function &Scope = *I.getFunction();
1077 bool IsKnownNoSync;
1078 bool IsAssumedNoSync = AA::hasAssumedIRAttr<Attribute::NoSync>(
1079 A, &QueryingAA, IRPosition::function(Scope), DepClassTy::OPTIONAL,
1080 IsKnownNoSync);
1081 const auto *ExecDomainAA = A.lookupAAFor<AAExecutionDomain>(
1082 IRPosition::function(Scope), &QueryingAA, DepClassTy::NONE);
1083 bool AllInSameNoSyncFn = IsAssumedNoSync;
1084 bool InstIsExecutedByInitialThreadOnly =
1085 ExecDomainAA && ExecDomainAA->isExecutedByInitialThreadOnly(I);
1086
1087 // If the function is not ending in aligned barriers, we need the stores to
1088 // be in aligned barriers. The load being in one is not sufficient since the
1089 // store might be executed by a thread that disappears after, causing the
1090 // aligned barrier guarding the load to unblock and the load to read a value
1091 // that has no CFG path to the load.
1092 bool InstIsExecutedInAlignedRegion =
1093 FindInterferingReads && ExecDomainAA &&
1094 ExecDomainAA->isExecutedInAlignedRegion(A, I);
1095
1096 if (InstIsExecutedInAlignedRegion || InstIsExecutedByInitialThreadOnly)
1097 A.recordDependence(*ExecDomainAA, QueryingAA, DepClassTy::OPTIONAL);
1098
1099 InformationCache &InfoCache = A.getInfoCache();
1100 bool IsThreadLocalObj =
1101 AA::isAssumedThreadLocalObject(A, getAssociatedValue(), *this);
1102
1103 // Helper to determine if we need to consider threading, which we cannot
1104 // right now. However, if the function is (assumed) nosync or the thread
1105 // executing all instructions is the main thread only we can ignore
1106 // threading. Also, thread-local objects do not require threading reasoning.
1107 // Finally, we can ignore threading if either access is executed in an
1108 // aligned region.
1109 auto CanIgnoreThreadingForInst = [&](const Instruction &I) -> bool {
1110 if (IsThreadLocalObj || AllInSameNoSyncFn)
1111 return true;
1112 const auto *FnExecDomainAA =
1113 I.getFunction() == &Scope
1114 ? ExecDomainAA
1115 : A.lookupAAFor<AAExecutionDomain>(
1116 IRPosition::function(*I.getFunction()), &QueryingAA,
1117 DepClassTy::NONE);
1118 if (!FnExecDomainAA)
1119 return false;
1120 if (InstIsExecutedInAlignedRegion ||
1121 (FindInterferingWrites &&
1122 FnExecDomainAA->isExecutedInAlignedRegion(A, I))) {
1123 A.recordDependence(*FnExecDomainAA, QueryingAA, DepClassTy::OPTIONAL);
1124 return true;
1125 }
1126 if (InstIsExecutedByInitialThreadOnly &&
1127 FnExecDomainAA->isExecutedByInitialThreadOnly(I)) {
1128 A.recordDependence(*FnExecDomainAA, QueryingAA, DepClassTy::OPTIONAL);
1129 return true;
1130 }
1131 return false;
1132 };
1133
1134 // Helper to determine if the access is executed by the same thread as the
1135 // given instruction, for now it is sufficient to avoid any potential
1136 // threading effects as we cannot deal with them anyway.
1137 auto CanIgnoreThreading = [&](const Access &Acc) -> bool {
1138 return CanIgnoreThreadingForInst(*Acc.getRemoteInst()) ||
1139 (Acc.getRemoteInst() != Acc.getLocalInst() &&
1140 CanIgnoreThreadingForInst(*Acc.getLocalInst()));
1141 };
1142
1143 // TODO: Use inter-procedural reachability and dominance.
1144 bool IsKnownNoRecurse;
1146 A, this, IRPosition::function(Scope), DepClassTy::OPTIONAL,
1147 IsKnownNoRecurse);
1148
1149 // TODO: Use reaching kernels from AAKernelInfo (or move it to
1150 // AAExecutionDomain) such that we allow scopes other than kernels as long
1151 // as the reaching kernels are disjoint.
1152 bool InstInKernel = A.getInfoCache().isKernel(Scope);
1153 bool ObjHasKernelLifetime = false;
1154 const bool UseDominanceReasoning =
1155 FindInterferingWrites && IsKnownNoRecurse;
1156 const DominatorTree *DT =
1157 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(Scope);
1158
1159 // Helper to check if a value has "kernel lifetime", that is it will not
1160 // outlive a GPU kernel. This is true for shared, constant, and local
1161 // globals on AMD and NVIDIA GPUs.
1162 auto HasKernelLifetime = [&](Value *V, Module &M) {
1163 if (!AA::isGPU(M))
1164 return false;
1165 unsigned VAS = V->getType()->getPointerAddressSpace();
1166 return AA::isGPUSharedAddressSpace(M, VAS) ||
1169 };
1170
1171 // The IsLiveInCalleeCB will be used by the AA::isPotentiallyReachable query
1172 // to determine if we should look at reachability from the callee. For
1173 // certain pointers we know the lifetime and we do not have to step into the
1174 // callee to determine reachability as the pointer would be dead in the
1175 // callee. See the conditional initialization below.
1176 std::function<bool(const Function &)> IsLiveInCalleeCB;
1177
1178 if (auto *AI = dyn_cast<AllocaInst>(&getAssociatedValue())) {
1179 // If the alloca containing function is not recursive the alloca
1180 // must be dead in the callee.
1181 const Function *AIFn = AI->getFunction();
1182 ObjHasKernelLifetime = A.getInfoCache().isKernel(*AIFn);
1183 bool IsKnownNoRecurse;
1185 A, this, IRPosition::function(*AIFn), DepClassTy::OPTIONAL,
1186 IsKnownNoRecurse)) {
1187 IsLiveInCalleeCB = [AIFn](const Function &Fn) { return AIFn != &Fn; };
1188 }
1189 } else if (auto *GV = dyn_cast<GlobalValue>(&getAssociatedValue())) {
1190 // If the global has kernel lifetime we can stop if we reach a kernel
1191 // as it is "dead" in the (unknown) callees.
1192 ObjHasKernelLifetime = HasKernelLifetime(GV, *GV->getParent());
1193 if (ObjHasKernelLifetime)
1194 IsLiveInCalleeCB = [&A](const Function &Fn) {
1195 return !A.getInfoCache().isKernel(Fn);
1196 };
1197 }
1198
1199 // Set of accesses/instructions that will overwrite the result and are
1200 // therefore blockers in the reachability traversal.
1201 AA::InstExclusionSetTy ExclusionSet;
1202
1203 auto AccessCB = [&](const Access &Acc, bool Exact) {
1204 Function *AccScope = Acc.getRemoteInst()->getFunction();
1205 bool AccInSameScope = AccScope == &Scope;
1206
1207 // If the object has kernel lifetime we can ignore accesses only reachable
1208 // by other kernels. For now we only skip accesses *in* other kernels.
1209 if (InstInKernel && ObjHasKernelLifetime && !AccInSameScope &&
1210 A.getInfoCache().isKernel(*AccScope))
1211 return true;
1212
1213 if (Exact && Acc.isMustAccess() && Acc.getRemoteInst() != &I) {
1214 if (Acc.isWrite() || (isa<LoadInst>(I) && Acc.isWriteOrAssumption()))
1215 ExclusionSet.insert(Acc.getRemoteInst());
1216 }
1217
1218 if ((!FindInterferingWrites || !Acc.isWriteOrAssumption()) &&
1219 (!FindInterferingReads || !Acc.isRead()))
1220 return true;
1221
1222 bool Dominates = FindInterferingWrites && DT && Exact &&
1223 Acc.isMustAccess() && AccInSameScope &&
1224 DT->dominates(Acc.getRemoteInst(), &I);
1225 if (Dominates)
1226 DominatingWrites.insert(&Acc);
1227
1228 // Track if all interesting accesses are in the same `nosync` function as
1229 // the given instruction.
1230 AllInSameNoSyncFn &= Acc.getRemoteInst()->getFunction() == &Scope;
1231
1232 InterferingAccesses.push_back({&Acc, Exact});
1233 return true;
1234 };
1235 if (!State::forallInterferingAccesses(I, AccessCB, Range))
1236 return false;
1237
1238 HasBeenWrittenTo = !DominatingWrites.empty();
1239
1240 // Dominating writes form a chain, find the least/lowest member.
1241 Instruction *LeastDominatingWriteInst = nullptr;
1242 for (const Access *Acc : DominatingWrites) {
1243 if (!LeastDominatingWriteInst) {
1244 LeastDominatingWriteInst = Acc->getRemoteInst();
1245 } else if (DT->dominates(LeastDominatingWriteInst,
1246 Acc->getRemoteInst())) {
1247 LeastDominatingWriteInst = Acc->getRemoteInst();
1248 }
1249 }
1250
1251 // Helper to determine if we can skip a specific write access.
1252 auto CanSkipAccess = [&](const Access &Acc, bool Exact) {
1253 if (SkipCB && SkipCB(Acc))
1254 return true;
1255 if (!CanIgnoreThreading(Acc))
1256 return false;
1257
1258 // Check read (RAW) dependences and write (WAR) dependences as necessary.
1259 // If we successfully excluded all effects we are interested in, the
1260 // access can be skipped.
1261 bool ReadChecked = !FindInterferingReads;
1262 bool WriteChecked = !FindInterferingWrites;
1263
1264 // If the instruction cannot reach the access, the former does not
1265 // interfere with what the access reads.
1266 if (!ReadChecked) {
1267 if (!AA::isPotentiallyReachable(A, I, *Acc.getRemoteInst(), QueryingAA,
1268 &ExclusionSet, IsLiveInCalleeCB))
1269 ReadChecked = true;
1270 }
1271 // If the instruction cannot be reach from the access, the latter does not
1272 // interfere with what the instruction reads.
1273 if (!WriteChecked) {
1274 if (!AA::isPotentiallyReachable(A, *Acc.getRemoteInst(), I, QueryingAA,
1275 &ExclusionSet, IsLiveInCalleeCB))
1276 WriteChecked = true;
1277 }
1278
1279 // If we still might be affected by the write of the access but there are
1280 // dominating writes in the function of the instruction
1281 // (HasBeenWrittenTo), we can try to reason that the access is overwritten
1282 // by them. This would have happend above if they are all in the same
1283 // function, so we only check the inter-procedural case. Effectively, we
1284 // want to show that there is no call after the dominting write that might
1285 // reach the access, and when it returns reach the instruction with the
1286 // updated value. To this end, we iterate all call sites, check if they
1287 // might reach the instruction without going through another access
1288 // (ExclusionSet) and at the same time might reach the access. However,
1289 // that is all part of AAInterFnReachability.
1290 if (!WriteChecked && HasBeenWrittenTo &&
1291 Acc.getRemoteInst()->getFunction() != &Scope) {
1292
1293 const auto *FnReachabilityAA = A.getAAFor<AAInterFnReachability>(
1294 QueryingAA, IRPosition::function(Scope), DepClassTy::OPTIONAL);
1295 if (FnReachabilityAA) {
1296 // Without going backwards in the call tree, can we reach the access
1297 // from the least dominating write. Do not allow to pass the
1298 // instruction itself either.
1299 bool Inserted = ExclusionSet.insert(&I).second;
1300
1301 if (!FnReachabilityAA->instructionCanReach(
1302 A, *LeastDominatingWriteInst,
1303 *Acc.getRemoteInst()->getFunction(), &ExclusionSet))
1304 WriteChecked = true;
1305
1306 if (Inserted)
1307 ExclusionSet.erase(&I);
1308 }
1309 }
1310
1311 if (ReadChecked && WriteChecked)
1312 return true;
1313
1314 if (!DT || !UseDominanceReasoning)
1315 return false;
1316 if (!DominatingWrites.count(&Acc))
1317 return false;
1318 return LeastDominatingWriteInst != Acc.getRemoteInst();
1319 };
1320
1321 // Run the user callback on all accesses we cannot skip and return if
1322 // that succeeded for all or not.
1323 for (auto &It : InterferingAccesses) {
1324 if ((!AllInSameNoSyncFn && !IsThreadLocalObj && !ExecDomainAA) ||
1325 !CanSkipAccess(*It.first, It.second)) {
1326 if (!UserCB(*It.first, It.second))
1327 return false;
1328 }
1329 }
1330 return true;
1331 }
1332
1333 ChangeStatus translateAndAddStateFromCallee(Attributor &A,
1334 const AAPointerInfo &OtherAA,
1335 CallBase &CB) {
1336 using namespace AA::PointerInfo;
1337 if (!OtherAA.getState().isValidState() || !isValidState())
1338 return indicatePessimisticFixpoint();
1339
1340 ChangeStatus Changed = ChangeStatus::UNCHANGED;
1341 const auto &OtherAAImpl = static_cast<const AAPointerInfoImpl &>(OtherAA);
1342 bool IsByval = OtherAAImpl.getAssociatedArgument()->hasByValAttr();
1343 Changed |= setReachesReturn(OtherAAImpl.ReturnedOffsets);
1344
1345 // Combine the accesses bin by bin.
1346 const auto &State = OtherAAImpl.getState();
1347 for (const auto &It : State) {
1348 for (auto Index : It.getSecond()) {
1349 const auto &RAcc = State.getAccess(Index);
1350 if (IsByval && !RAcc.isRead())
1351 continue;
1352 bool UsedAssumedInformation = false;
1353 AccessKind AK = RAcc.getKind();
1354 auto Content = A.translateArgumentToCallSiteContent(
1355 RAcc.getContent(), CB, *this, UsedAssumedInformation);
1356 AK = AccessKind(AK & (IsByval ? AccessKind::AK_R : AccessKind::AK_RW));
1357 AK = AccessKind(AK | (RAcc.isMayAccess() ? AK_MAY : AK_MUST));
1358
1359 Changed |= addAccess(A, RAcc.getRanges(), CB, Content, AK,
1360 RAcc.getType(), RAcc.getRemoteInst());
1361 }
1362 }
1363 return Changed;
1364 }
1365
1366 ChangeStatus translateAndAddState(Attributor &A, const AAPointerInfo &OtherAA,
1367 const OffsetInfo &Offsets, CallBase &CB,
1368 bool IsMustAcc) {
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
1375 // Combine the accesses bin by bin.
1376 ChangeStatus Changed = ChangeStatus::UNCHANGED;
1377 const auto &State = OtherAAImpl.getState();
1378 for (const auto &It : State) {
1379 for (auto Index : It.getSecond()) {
1380 const auto &RAcc = State.getAccess(Index);
1381 if (!IsMustAcc && RAcc.isAssumption())
1382 continue;
1383 for (auto Offset : Offsets) {
1384 auto NewRanges = Offset == AA::RangeTy::Unknown
1386 : RAcc.getRanges();
1387 if (!NewRanges.isUnknown()) {
1388 NewRanges.addToAllOffsets(Offset);
1389 }
1390 AccessKind AK = RAcc.getKind();
1391 if (!IsMustAcc)
1392 AK = AccessKind((AK & ~AK_MUST) | AK_MAY);
1393 Changed |= addAccess(A, NewRanges, CB, RAcc.getContent(), AK,
1394 RAcc.getType(), RAcc.getRemoteInst());
1395 }
1396 }
1397 }
1398 return Changed;
1399 }
1400
1401 /// Statistic tracking for all AAPointerInfo implementations.
1402 /// See AbstractAttribute::trackStatistics().
1403 void trackPointerInfoStatistics(const IRPosition &IRP) const {}
1404
1405 /// Dump the state into \p O.
1406 void dumpState(raw_ostream &O) {
1407 for (auto &It : OffsetBins) {
1408 O << "[" << It.first.Offset << "-" << It.first.Offset + It.first.Size
1409 << "] : " << It.getSecond().size() << "\n";
1410 for (auto AccIndex : It.getSecond()) {
1411 auto &Acc = AccessList[AccIndex];
1412 O << " - " << Acc.getKind() << " - " << *Acc.getLocalInst() << "\n";
1413 if (Acc.getLocalInst() != Acc.getRemoteInst())
1414 O << " --> " << *Acc.getRemoteInst()
1415 << "\n";
1416 if (!Acc.isWrittenValueYetUndetermined()) {
1417 if (isa_and_nonnull<Function>(Acc.getWrittenValue()))
1418 O << " - c: func " << Acc.getWrittenValue()->getName()
1419 << "\n";
1420 else if (Acc.getWrittenValue())
1421 O << " - c: " << *Acc.getWrittenValue() << "\n";
1422 else
1423 O << " - c: <unknown>\n";
1424 }
1425 }
1426 }
1427 }
1428};
1429
1430struct AAPointerInfoFloating : public AAPointerInfoImpl {
1432 AAPointerInfoFloating(const IRPosition &IRP, Attributor &A)
1433 : AAPointerInfoImpl(IRP, A) {}
1434
1435 /// Deal with an access and signal if it was handled successfully.
1436 bool handleAccess(Attributor &A, Instruction &I,
1437 std::optional<Value *> Content, AccessKind Kind,
1438 OffsetInfo::VecTy &Offsets, ChangeStatus &Changed,
1439 Type &Ty) {
1440 using namespace AA::PointerInfo;
1442 const DataLayout &DL = A.getDataLayout();
1443 TypeSize AccessSize = DL.getTypeStoreSize(&Ty);
1444 if (!AccessSize.isScalable())
1445 Size = AccessSize.getFixedValue();
1446
1447 // Make a strictly ascending list of offsets as required by addAccess()
1448 SmallVector<int64_t> OffsetsSorted(Offsets.begin(), Offsets.end());
1449 llvm::sort(OffsetsSorted);
1450
1452 if (!VT || VT->getElementCount().isScalable() ||
1453 !Content.value_or(nullptr) || !isa<Constant>(*Content) ||
1454 (*Content)->getType() != VT ||
1455 DL.getTypeStoreSize(VT->getElementType()).isScalable()) {
1456 Changed =
1457 Changed | addAccess(A, {OffsetsSorted, Size}, I, Content, Kind, &Ty);
1458 } else {
1459 // Handle vector stores with constant content element-wise.
1460 // TODO: We could look for the elements or create instructions
1461 // representing them.
1462 // TODO: We need to push the Content into the range abstraction
1463 // (AA::RangeTy) to allow different content values for different
1464 // ranges. ranges. Hence, support vectors storing different values.
1465 Type *ElementType = VT->getElementType();
1466 int64_t ElementSize = DL.getTypeStoreSize(ElementType).getFixedValue();
1467 auto *ConstContent = cast<Constant>(*Content);
1468 Type *Int32Ty = Type::getInt32Ty(ElementType->getContext());
1469 SmallVector<int64_t> ElementOffsets(OffsetsSorted.begin(),
1470 OffsetsSorted.end());
1471
1472 for (int i = 0, e = VT->getElementCount().getFixedValue(); i != e; ++i) {
1473 Value *ElementContent = ConstantExpr::getExtractElement(
1474 ConstContent, ConstantInt::get(Int32Ty, i));
1475
1476 // Add the element access.
1477 Changed = Changed | addAccess(A, {ElementOffsets, ElementSize}, I,
1478 ElementContent, Kind, ElementType);
1479
1480 // Advance the offsets for the next element.
1481 for (auto &ElementOffset : ElementOffsets)
1482 ElementOffset += ElementSize;
1483 }
1484 }
1485 return true;
1486 };
1487
1488 /// See AbstractAttribute::updateImpl(...).
1489 ChangeStatus updateImpl(Attributor &A) override;
1490
1491 /// If the indices to \p GEP can be traced to constants, incorporate all
1492 /// of these into \p UsrOI.
1493 ///
1494 /// \return true iff \p UsrOI is updated.
1495 bool collectConstantsForGEP(Attributor &A, const DataLayout &DL,
1496 OffsetInfo &UsrOI, const OffsetInfo &PtrOI,
1497 const GEPOperator *GEP);
1498
1499 /// See AbstractAttribute::trackStatistics()
1500 void trackStatistics() const override {
1501 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
1502 }
1503};
1504
1505bool AAPointerInfoFloating::collectConstantsForGEP(Attributor &A,
1506 const DataLayout &DL,
1507 OffsetInfo &UsrOI,
1508 const OffsetInfo &PtrOI,
1509 const GEPOperator *GEP) {
1510 unsigned BitWidth = DL.getIndexTypeSizeInBits(GEP->getType());
1511 SmallMapVector<Value *, APInt, 4> VariableOffsets;
1512 APInt ConstantOffset(BitWidth, 0);
1513
1514 assert(!UsrOI.isUnknown() && !PtrOI.isUnknown() &&
1515 "Don't look for constant values if the offset has already been "
1516 "determined to be unknown.");
1517
1518 if (!GEP->collectOffset(DL, BitWidth, VariableOffsets, ConstantOffset)) {
1519 UsrOI.setUnknown();
1520 return true;
1521 }
1522
1523 LLVM_DEBUG(dbgs() << "[AAPointerInfo] GEP offset is "
1524 << (VariableOffsets.empty() ? "" : "not") << " constant "
1525 << *GEP << "\n");
1526
1527 auto Union = PtrOI;
1528 Union.addToAll(ConstantOffset.getSExtValue());
1529
1530 // Each VI in VariableOffsets has a set of potential constant values. Every
1531 // combination of elements, picked one each from these sets, is separately
1532 // added to the original set of offsets, thus resulting in more offsets.
1533 for (const auto &VI : VariableOffsets) {
1534 auto *PotentialConstantsAA = A.getAAFor<AAPotentialConstantValues>(
1535 *this, IRPosition::value(*VI.first), DepClassTy::OPTIONAL);
1536 if (!PotentialConstantsAA || !PotentialConstantsAA->isValidState()) {
1537 UsrOI.setUnknown();
1538 return true;
1539 }
1540
1541 // UndefValue is treated as a zero, which leaves Union as is.
1542 if (PotentialConstantsAA->undefIsContained())
1543 continue;
1544
1545 // We need at least one constant in every set to compute an actual offset.
1546 // Otherwise, we end up pessimizing AAPointerInfo by respecting offsets that
1547 // don't actually exist. In other words, the absence of constant values
1548 // implies that the operation can be assumed dead for now.
1549 auto &AssumedSet = PotentialConstantsAA->getAssumedSet();
1550 if (AssumedSet.empty())
1551 return false;
1552
1553 OffsetInfo Product;
1554 for (const auto &ConstOffset : AssumedSet) {
1555 auto CopyPerOffset = Union;
1556 CopyPerOffset.addToAll(ConstOffset.getSExtValue() *
1557 VI.second.getZExtValue());
1558 Product.merge(CopyPerOffset);
1559 }
1560 Union = Product;
1561 }
1562
1563 UsrOI = std::move(Union);
1564 return true;
1565}
1566
1567ChangeStatus AAPointerInfoFloating::updateImpl(Attributor &A) {
1568 using namespace AA::PointerInfo;
1570 const DataLayout &DL = A.getDataLayout();
1571 Value &AssociatedValue = getAssociatedValue();
1572
1573 DenseMap<Value *, OffsetInfo> OffsetInfoMap;
1574 OffsetInfoMap[&AssociatedValue].insert(0);
1575
1576 auto HandlePassthroughUser = [&](Value *Usr, Value *CurPtr, bool &Follow) {
1577 // One does not simply walk into a map and assign a reference to a possibly
1578 // new location. That can cause an invalidation before the assignment
1579 // happens, like so:
1580 //
1581 // OffsetInfoMap[Usr] = OffsetInfoMap[CurPtr]; /* bad idea! */
1582 //
1583 // The RHS is a reference that may be invalidated by an insertion caused by
1584 // the LHS. So we ensure that the side-effect of the LHS happens first.
1585
1586 assert(OffsetInfoMap.contains(CurPtr) &&
1587 "CurPtr does not exist in the map!");
1588
1589 auto &UsrOI = OffsetInfoMap[Usr];
1590 auto &PtrOI = OffsetInfoMap[CurPtr];
1591 assert(!PtrOI.isUnassigned() &&
1592 "Cannot pass through if the input Ptr was not visited!");
1593 UsrOI.merge(PtrOI);
1594 Follow = true;
1595 return true;
1596 };
1597
1598 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
1599 Value *CurPtr = U.get();
1600 User *Usr = U.getUser();
1601 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Analyze " << *CurPtr << " in " << *Usr
1602 << "\n");
1603 assert(OffsetInfoMap.count(CurPtr) &&
1604 "The current pointer offset should have been seeded!");
1605 assert(!OffsetInfoMap[CurPtr].isUnassigned() &&
1606 "Current pointer should be assigned");
1607
1608 // Only address space casts are followed; other casts of a pointer (e.g.,
1609 // ptrtoint, ptrtoaddr, or a bitcast to a byte type) do not produce a
1610 // pointer that can be tracked.
1612 return HandlePassthroughUser(Usr, CurPtr, Follow);
1613
1614 if (auto *GEP = dyn_cast<GEPOperator>(Usr)) {
1615 // Note the order here, the Usr access might change the map, CurPtr is
1616 // already in it though.
1617 auto &UsrOI = OffsetInfoMap[Usr];
1618 auto &PtrOI = OffsetInfoMap[CurPtr];
1619
1620 if (UsrOI.isUnknown())
1621 return true;
1622
1623 if (PtrOI.isUnknown()) {
1624 Follow = true;
1625 UsrOI.setUnknown();
1626 return true;
1627 }
1628
1629 Follow = collectConstantsForGEP(A, DL, UsrOI, PtrOI, GEP);
1630 return true;
1631 }
1632 if (isa<SelectInst>(Usr))
1633 return HandlePassthroughUser(Usr, CurPtr, Follow);
1634 // Returns are allowed if they are in the associated functions. Users can
1635 // then check the call site return. Returns from other functions can't be
1636 // tracked and are cause for invalidation.
1637 if (auto *RI = dyn_cast<ReturnInst>(Usr)) {
1638 if (RI->getFunction() == getAssociatedFunction()) {
1639 auto &PtrOI = OffsetInfoMap[CurPtr];
1640 Changed |= setReachesReturn(PtrOI);
1641 return true;
1642 }
1643 return false;
1644 }
1645
1646 // For PHIs we need to take care of the recurrence explicitly as the value
1647 // might change while we iterate through a loop. For now, we give up if
1648 // the PHI is not invariant.
1649 if (auto *PHI = dyn_cast<PHINode>(Usr)) {
1650 // Note the order here, the Usr access might change the map, CurPtr is
1651 // already in it though.
1652 auto [PhiIt, IsFirstPHIUser] = OffsetInfoMap.try_emplace(PHI);
1653 auto &UsrOI = PhiIt->second;
1654 auto &PtrOI = OffsetInfoMap[CurPtr];
1655
1656 // Check if the PHI operand has already an unknown offset as we can't
1657 // improve on that anymore.
1658 if (PtrOI.isUnknown()) {
1659 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI operand offset unknown "
1660 << *CurPtr << " in " << *PHI << "\n");
1661 Follow = !UsrOI.isUnknown();
1662 UsrOI.setUnknown();
1663 return true;
1664 }
1665
1666 // Check if the PHI is invariant (so far).
1667 if (UsrOI == PtrOI) {
1668 assert(!PtrOI.isUnassigned() &&
1669 "Cannot assign if the current Ptr was not visited!");
1670 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI is invariant (so far)");
1671 return true;
1672 }
1673
1674 // Check if the PHI operand can be traced back to AssociatedValue.
1675 APInt Offset(
1676 DL.getIndexSizeInBits(CurPtr->getType()->getPointerAddressSpace()),
1677 0);
1678 Value *CurPtrBase = CurPtr->stripAndAccumulateConstantOffsets(
1679 DL, Offset, /* AllowNonInbounds */ true);
1680 auto It = OffsetInfoMap.find(CurPtrBase);
1681 if (It == OffsetInfoMap.end()) {
1682 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI operand is too complex "
1683 << *CurPtr << " in " << *PHI
1684 << " (base: " << *CurPtrBase << ")\n");
1685 UsrOI.setUnknown();
1686 Follow = true;
1687 return true;
1688 }
1689
1690 // Check if the PHI operand is not dependent on the PHI itself. Every
1691 // recurrence is a cyclic net of PHIs in the data flow, and has an
1692 // equivalent Cycle in the control flow. One of those PHIs must be in the
1693 // header of that control flow Cycle. This is independent of the choice of
1694 // Cycles reported by CycleInfo. It is sufficient to check the PHIs in
1695 // every Cycle header; if such a node is marked unknown, this will
1696 // eventually propagate through the whole net of PHIs in the recurrence.
1697 const auto *CI =
1698 A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>(
1699 *PHI->getFunction());
1700 if (mayBeInCycle(CI, cast<Instruction>(Usr), /* HeaderOnly */ true)) {
1701 auto BaseOI = It->getSecond();
1702 BaseOI.addToAll(Offset.getZExtValue());
1703 if (IsFirstPHIUser || BaseOI == UsrOI) {
1704 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI is invariant " << *CurPtr
1705 << " in " << *Usr << "\n");
1706 return HandlePassthroughUser(Usr, CurPtr, Follow);
1707 }
1708
1709 LLVM_DEBUG(
1710 dbgs() << "[AAPointerInfo] PHI operand pointer offset mismatch "
1711 << *CurPtr << " in " << *PHI << "\n");
1712 UsrOI.setUnknown();
1713 Follow = true;
1714 return true;
1715 }
1716
1717 UsrOI.merge(PtrOI);
1718 Follow = true;
1719 return true;
1720 }
1721
1722 if (auto *LoadI = dyn_cast<LoadInst>(Usr)) {
1723 // If the access is to a pointer that may or may not be the associated
1724 // value, e.g. due to a PHI, we cannot assume it will be read.
1725 AccessKind AK = AccessKind::AK_R;
1726 if (getUnderlyingObject(CurPtr) == &AssociatedValue)
1727 AK = AccessKind(AK | AccessKind::AK_MUST);
1728 else
1729 AK = AccessKind(AK | AccessKind::AK_MAY);
1730 if (!handleAccess(A, *LoadI, /* Content */ nullptr, AK,
1731 OffsetInfoMap[CurPtr].Offsets, Changed,
1732 *LoadI->getType()))
1733 return false;
1734
1735 auto IsAssumption = [](Instruction &I) {
1736 if (auto *II = dyn_cast<IntrinsicInst>(&I))
1737 return II->isAssumeLikeIntrinsic();
1738 return false;
1739 };
1740
1741 auto IsImpactedInRange = [&](Instruction *FromI, Instruction *ToI) {
1742 // Check if the assumption and the load are executed together without
1743 // memory modification.
1744 do {
1745 if (FromI->mayWriteToMemory() && !IsAssumption(*FromI))
1746 return true;
1747 FromI = FromI->getNextNode();
1748 } while (FromI && FromI != ToI);
1749 return false;
1750 };
1751
1752 BasicBlock *BB = LoadI->getParent();
1753 auto IsValidAssume = [&](IntrinsicInst &IntrI) {
1754 if (IntrI.getIntrinsicID() != Intrinsic::assume)
1755 return false;
1756 BasicBlock *IntrBB = IntrI.getParent();
1757 if (IntrI.getParent() == BB) {
1758 if (IsImpactedInRange(LoadI->getNextNode(), &IntrI))
1759 return false;
1760 } else {
1761 auto PredIt = pred_begin(IntrBB);
1762 if (PredIt == pred_end(IntrBB))
1763 return false;
1764 if ((*PredIt) != BB)
1765 return false;
1766 if (++PredIt != pred_end(IntrBB))
1767 return false;
1768 for (auto *SuccBB : successors(BB)) {
1769 if (SuccBB == IntrBB)
1770 continue;
1771 if (isa<UnreachableInst>(SuccBB->getTerminator()))
1772 continue;
1773 return false;
1774 }
1775 if (IsImpactedInRange(LoadI->getNextNode(), BB->getTerminator()))
1776 return false;
1777 if (IsImpactedInRange(&IntrBB->front(), &IntrI))
1778 return false;
1779 }
1780 return true;
1781 };
1782
1783 std::pair<Value *, IntrinsicInst *> Assumption;
1784 for (const Use &LoadU : LoadI->uses()) {
1785 if (auto *CmpI = dyn_cast<CmpInst>(LoadU.getUser())) {
1786 if (!CmpI->isEquality() || !CmpI->isTrueWhenEqual())
1787 continue;
1788 for (const Use &CmpU : CmpI->uses()) {
1789 if (auto *IntrI = dyn_cast<IntrinsicInst>(CmpU.getUser())) {
1790 if (!IsValidAssume(*IntrI))
1791 continue;
1792 int Idx = CmpI->getOperandUse(0) == LoadU;
1793 Assumption = {CmpI->getOperand(Idx), IntrI};
1794 break;
1795 }
1796 }
1797 }
1798 if (Assumption.first)
1799 break;
1800 }
1801
1802 // Check if we found an assumption associated with this load.
1803 if (!Assumption.first || !Assumption.second)
1804 return true;
1805
1806 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Assumption found "
1807 << *Assumption.second << ": " << *LoadI
1808 << " == " << *Assumption.first << "\n");
1809 bool UsedAssumedInformation = false;
1810 std::optional<Value *> Content = nullptr;
1811 if (Assumption.first)
1812 Content =
1813 A.getAssumedSimplified(*Assumption.first, *this,
1814 UsedAssumedInformation, AA::Interprocedural);
1815 return handleAccess(
1816 A, *Assumption.second, Content, AccessKind::AK_ASSUMPTION,
1817 OffsetInfoMap[CurPtr].Offsets, Changed, *LoadI->getType());
1818 }
1819
1820 auto HandleStoreLike = [&](Instruction &I, Value *ValueOp, Type &ValueTy,
1821 ArrayRef<Value *> OtherOps, AccessKind AK) {
1822 for (auto *OtherOp : OtherOps) {
1823 if (OtherOp == CurPtr) {
1824 LLVM_DEBUG(
1825 dbgs()
1826 << "[AAPointerInfo] Escaping use in store like instruction " << I
1827 << "\n");
1828 return false;
1829 }
1830 }
1831
1832 // If the access is to a pointer that may or may not be the associated
1833 // value, e.g. due to a PHI, we cannot assume it will be written.
1834 if (getUnderlyingObject(CurPtr) == &AssociatedValue)
1835 AK = AccessKind(AK | AccessKind::AK_MUST);
1836 else
1837 AK = AccessKind(AK | AccessKind::AK_MAY);
1838 bool UsedAssumedInformation = false;
1839 std::optional<Value *> Content = nullptr;
1840 if (ValueOp)
1841 Content = A.getAssumedSimplified(
1842 *ValueOp, *this, UsedAssumedInformation, AA::Interprocedural);
1843 return handleAccess(A, I, Content, AK, OffsetInfoMap[CurPtr].Offsets,
1844 Changed, ValueTy);
1845 };
1846
1847 if (auto *StoreI = dyn_cast<StoreInst>(Usr))
1848 return HandleStoreLike(*StoreI, StoreI->getValueOperand(),
1849 *StoreI->getValueOperand()->getType(),
1850 {StoreI->getValueOperand()}, AccessKind::AK_W);
1851 if (auto *RMWI = dyn_cast<AtomicRMWInst>(Usr))
1852 return HandleStoreLike(*RMWI, nullptr, *RMWI->getValOperand()->getType(),
1853 {RMWI->getValOperand()}, AccessKind::AK_RW);
1854 if (auto *CXI = dyn_cast<AtomicCmpXchgInst>(Usr))
1855 return HandleStoreLike(
1856 *CXI, nullptr, *CXI->getNewValOperand()->getType(),
1857 {CXI->getCompareOperand(), CXI->getNewValOperand()},
1858 AccessKind::AK_RW);
1859
1860 if (auto *CB = dyn_cast<CallBase>(Usr)) {
1861 if (CB->isLifetimeStartOrEnd())
1862 return true;
1863 const auto *TLI =
1864 A.getInfoCache().getTargetLibraryInfoForFunction(*CB->getFunction());
1865 if (getFreedOperand(CB, TLI) == U)
1866 return true;
1867 if (CB->isArgOperand(&U)) {
1868 unsigned ArgNo = CB->getArgOperandNo(&U);
1869 const auto *CSArgPI = A.getAAFor<AAPointerInfo>(
1870 *this, IRPosition::callsite_argument(*CB, ArgNo),
1872 if (!CSArgPI)
1873 return false;
1874 bool IsArgMustAcc = (getUnderlyingObject(CurPtr) == &AssociatedValue);
1875 Changed = translateAndAddState(A, *CSArgPI, OffsetInfoMap[CurPtr], *CB,
1876 IsArgMustAcc) |
1877 Changed;
1878 if (!CSArgPI->reachesReturn())
1879 return isValidState();
1880
1882 if (!Callee || Callee->arg_size() <= ArgNo)
1883 return false;
1884 bool UsedAssumedInformation = false;
1885 auto ReturnedValue = A.getAssumedSimplified(
1886 IRPosition::returned(*Callee), *this, UsedAssumedInformation,
1888 auto *ReturnedArg =
1889 dyn_cast_or_null<Argument>(ReturnedValue.value_or(nullptr));
1890 auto *Arg = Callee->getArg(ArgNo);
1891 if (ReturnedArg && Arg != ReturnedArg)
1892 return true;
1893 bool IsRetMustAcc = IsArgMustAcc && (ReturnedArg == Arg);
1894 const auto *CSRetPI = A.getAAFor<AAPointerInfo>(
1896 if (!CSRetPI)
1897 return false;
1898 OffsetInfo OI = OffsetInfoMap[CurPtr];
1899 CSArgPI->addReturnedOffsetsTo(OI);
1900 Changed =
1901 translateAndAddState(A, *CSRetPI, OI, *CB, IsRetMustAcc) | Changed;
1902 return isValidState();
1903 }
1904 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Call user not handled " << *CB
1905 << "\n");
1906 return false;
1907 }
1908
1909 LLVM_DEBUG(dbgs() << "[AAPointerInfo] User not handled " << *Usr << "\n");
1910 return false;
1911 };
1912 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) {
1913 assert(OffsetInfoMap.count(OldU) && "Old use should be known already!");
1914 assert(!OffsetInfoMap[OldU].isUnassigned() && "Old use should be assinged");
1915 if (OffsetInfoMap.count(NewU)) {
1916 LLVM_DEBUG({
1917 if (!(OffsetInfoMap[NewU] == OffsetInfoMap[OldU])) {
1918 dbgs() << "[AAPointerInfo] Equivalent use callback failed: "
1919 << OffsetInfoMap[NewU] << " vs " << OffsetInfoMap[OldU]
1920 << "\n";
1921 }
1922 });
1923 return OffsetInfoMap[NewU] == OffsetInfoMap[OldU];
1924 }
1925 bool Unused;
1926 return HandlePassthroughUser(NewU.get(), OldU.get(), Unused);
1927 };
1928 if (!A.checkForAllUses(UsePred, *this, AssociatedValue,
1929 /* CheckBBLivenessOnly */ true, DepClassTy::OPTIONAL,
1930 /* IgnoreDroppableUses */ true, EquivalentUseCB)) {
1931 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Check for all uses failed, abort!\n");
1932 return indicatePessimisticFixpoint();
1933 }
1934
1935 LLVM_DEBUG({
1936 dbgs() << "Accesses by bin after update:\n";
1937 dumpState(dbgs());
1938 });
1939
1940 return Changed;
1941}
1942
1943struct AAPointerInfoReturned final : AAPointerInfoImpl {
1944 AAPointerInfoReturned(const IRPosition &IRP, Attributor &A)
1945 : AAPointerInfoImpl(IRP, A) {}
1946
1947 /// See AbstractAttribute::updateImpl(...).
1948 ChangeStatus updateImpl(Attributor &A) override {
1949 return indicatePessimisticFixpoint();
1950 }
1951
1952 /// See AbstractAttribute::trackStatistics()
1953 void trackStatistics() const override {
1954 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
1955 }
1956};
1957
1958struct AAPointerInfoArgument final : AAPointerInfoFloating {
1959 AAPointerInfoArgument(const IRPosition &IRP, Attributor &A)
1960 : AAPointerInfoFloating(IRP, A) {}
1961
1962 /// See AbstractAttribute::trackStatistics()
1963 void trackStatistics() const override {
1964 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
1965 }
1966};
1967
1968struct AAPointerInfoCallSiteArgument final : AAPointerInfoFloating {
1969 AAPointerInfoCallSiteArgument(const IRPosition &IRP, Attributor &A)
1970 : AAPointerInfoFloating(IRP, A) {}
1971
1972 /// See AbstractAttribute::updateImpl(...).
1973 ChangeStatus updateImpl(Attributor &A) override {
1974 using namespace AA::PointerInfo;
1975 // We handle memory intrinsics explicitly, at least the first (=
1976 // destination) and second (=source) arguments as we know how they are
1977 // accessed.
1978 if (auto *MI = dyn_cast_or_null<MemIntrinsic>(getCtxI())) {
1979 int64_t LengthVal = AA::RangeTy::Unknown;
1980 if (auto Length = MI->getLengthInBytes())
1981 LengthVal = Length->getSExtValue();
1982 unsigned ArgNo = getIRPosition().getCallSiteArgNo();
1983 ChangeStatus Changed = ChangeStatus::UNCHANGED;
1984 if (ArgNo > 1) {
1985 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Unhandled memory intrinsic "
1986 << *MI << "\n");
1987 return indicatePessimisticFixpoint();
1988 } else {
1989 auto Kind =
1990 ArgNo == 0 ? AccessKind::AK_MUST_WRITE : AccessKind::AK_MUST_READ;
1991 Changed =
1992 Changed | addAccess(A, {0, LengthVal}, *MI, nullptr, Kind, nullptr);
1993 }
1994 LLVM_DEBUG({
1995 dbgs() << "Accesses by bin after update:\n";
1996 dumpState(dbgs());
1997 });
1998
1999 return Changed;
2000 }
2001
2002 // TODO: Once we have call site specific value information we can provide
2003 // call site specific liveness information and then it makes
2004 // sense to specialize attributes for call sites arguments instead of
2005 // redirecting requests to the callee argument.
2006 Argument *Arg = getAssociatedArgument();
2007 if (Arg) {
2008 const IRPosition &ArgPos = IRPosition::argument(*Arg);
2009 auto *ArgAA =
2010 A.getAAFor<AAPointerInfo>(*this, ArgPos, DepClassTy::REQUIRED);
2011 if (ArgAA && ArgAA->getState().isValidState())
2012 return translateAndAddStateFromCallee(A, *ArgAA,
2013 *cast<CallBase>(getCtxI()));
2014 if (!Arg->getParent()->isDeclaration())
2015 return indicatePessimisticFixpoint();
2016 }
2017
2018 bool IsKnownNoCapture;
2020 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNoCapture))
2021 return indicatePessimisticFixpoint();
2022
2023 bool IsKnown = false;
2024 if (AA::isAssumedReadNone(A, getIRPosition(), *this, IsKnown))
2025 return ChangeStatus::UNCHANGED;
2026 bool ReadOnly = AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown);
2027 auto Kind =
2028 ReadOnly ? AccessKind::AK_MAY_READ : AccessKind::AK_MAY_READ_WRITE;
2029 return addAccess(A, AA::RangeTy::getUnknown(), *getCtxI(), nullptr, Kind,
2030 nullptr);
2031 }
2032
2033 /// See AbstractAttribute::trackStatistics()
2034 void trackStatistics() const override {
2035 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
2036 }
2037};
2038
2039struct AAPointerInfoCallSiteReturned final : AAPointerInfoFloating {
2040 AAPointerInfoCallSiteReturned(const IRPosition &IRP, Attributor &A)
2041 : AAPointerInfoFloating(IRP, A) {}
2042
2043 /// See AbstractAttribute::trackStatistics()
2044 void trackStatistics() const override {
2045 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
2046 }
2047};
2048} // namespace
2049
2050/// -----------------------NoUnwind Function Attribute--------------------------
2051
2052namespace {
2053struct AANoUnwindImpl : AANoUnwind {
2054 AANoUnwindImpl(const IRPosition &IRP, Attributor &A) : AANoUnwind(IRP, A) {}
2055
2056 /// See AbstractAttribute::initialize(...).
2057 void initialize(Attributor &A) override {
2058 bool IsKnown;
2060 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
2061 (void)IsKnown;
2062 }
2063
2064 const std::string getAsStr(Attributor *A) const override {
2065 return getAssumed() ? "nounwind" : "may-unwind";
2066 }
2067
2068 /// See AbstractAttribute::updateImpl(...).
2069 ChangeStatus updateImpl(Attributor &A) override {
2070 auto Opcodes = {
2071 (unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,
2072 (unsigned)Instruction::Call, (unsigned)Instruction::CleanupRet,
2073 (unsigned)Instruction::CatchSwitch, (unsigned)Instruction::Resume};
2074
2075 auto CheckForNoUnwind = [&](Instruction &I) {
2076 if (!I.mayThrow(/* IncludePhaseOneUnwind */ true))
2077 return true;
2078
2079 if (const auto *CB = dyn_cast<CallBase>(&I)) {
2080 bool IsKnownNoUnwind;
2082 A, this, IRPosition::callsite_function(*CB), DepClassTy::REQUIRED,
2083 IsKnownNoUnwind);
2084 }
2085 return false;
2086 };
2087
2088 bool UsedAssumedInformation = false;
2089 if (!A.checkForAllInstructions(CheckForNoUnwind, *this, Opcodes,
2090 UsedAssumedInformation))
2091 return indicatePessimisticFixpoint();
2092
2093 return ChangeStatus::UNCHANGED;
2094 }
2095};
2096
2097struct AANoUnwindFunction final : public AANoUnwindImpl {
2098 AANoUnwindFunction(const IRPosition &IRP, Attributor &A)
2099 : AANoUnwindImpl(IRP, A) {}
2100
2101 /// See AbstractAttribute::trackStatistics()
2102 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nounwind) }
2103};
2104
2105/// NoUnwind attribute deduction for a call sites.
2106struct AANoUnwindCallSite final
2107 : AACalleeToCallSite<AANoUnwind, AANoUnwindImpl> {
2108 AANoUnwindCallSite(const IRPosition &IRP, Attributor &A)
2109 : AACalleeToCallSite<AANoUnwind, AANoUnwindImpl>(IRP, A) {}
2110
2111 /// See AbstractAttribute::trackStatistics()
2112 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nounwind); }
2113};
2114} // namespace
2115
2116/// ------------------------ NoSync Function Attribute -------------------------
2117
2118bool AANoSync::isAlignedBarrier(const CallBase &CB, bool ExecutedAligned) {
2119 switch (CB.getIntrinsicID()) {
2120 case Intrinsic::nvvm_barrier_cta_sync_aligned_all:
2121 case Intrinsic::nvvm_barrier_cta_sync_aligned_count:
2122 case Intrinsic::nvvm_barrier_cta_red_and_aligned_all:
2123 case Intrinsic::nvvm_barrier_cta_red_and_aligned_count:
2124 case Intrinsic::nvvm_barrier_cta_red_or_aligned_all:
2125 case Intrinsic::nvvm_barrier_cta_red_or_aligned_count:
2126 case Intrinsic::nvvm_barrier_cta_red_popc_aligned_all:
2127 case Intrinsic::nvvm_barrier_cta_red_popc_aligned_count:
2128 return true;
2129 case Intrinsic::amdgcn_s_barrier:
2130 if (ExecutedAligned)
2131 return true;
2132 break;
2133 default:
2134 break;
2135 }
2136 return hasAssumption(CB, KnownAssumptionString("ompx_aligned_barrier"));
2137}
2138
2140 if (!I->isAtomic())
2141 return false;
2142
2143 if (auto *FI = dyn_cast<FenceInst>(I))
2144 // All legal orderings for fence are stronger than monotonic.
2145 return FI->getSyncScopeID() != SyncScope::SingleThread;
2146 if (auto *AI = dyn_cast<AtomicCmpXchgInst>(I)) {
2147 // Unordered is not a legal ordering for cmpxchg.
2148 return (AI->getSuccessOrdering() != AtomicOrdering::Monotonic ||
2149 AI->getFailureOrdering() != AtomicOrdering::Monotonic);
2150 }
2151
2152 AtomicOrdering Ordering;
2153 switch (I->getOpcode()) {
2154 case Instruction::AtomicRMW:
2155 Ordering = cast<AtomicRMWInst>(I)->getOrdering();
2156 break;
2157 case Instruction::Store:
2158 Ordering = cast<StoreInst>(I)->getOrdering();
2159 break;
2160 case Instruction::Load:
2161 Ordering = cast<LoadInst>(I)->getOrdering();
2162 break;
2163 default:
2165 "New atomic operations need to be known in the attributor.");
2166 }
2167
2168 return (Ordering != AtomicOrdering::Unordered &&
2169 Ordering != AtomicOrdering::Monotonic);
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);
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 if (auto *CB = dyn_cast<CallBase>(&I)) {
2261 bool IsKnown;
2263 A, this, IRPosition::callsite_function(*CB), DepClassTy::REQUIRED,
2264 IsKnown);
2265 }
2266 // Make sure that synchronization cannot establish happens-before with a
2267 // free on another thread.
2268 return AA::isNoSyncInst(A, I, *this);
2269 };
2270
2271 bool UsedAssumedInformation = false;
2272 if (!A.checkForAllReadWriteInstructions(CheckForNoFree, *this,
2273 UsedAssumedInformation) ||
2274 !A.checkForAllCallLikeInstructions(CheckForNoFree, *this,
2275 UsedAssumedInformation))
2276 return indicatePessimisticFixpoint();
2277
2278 return ChangeStatus::UNCHANGED;
2279 }
2280
2281 /// See AbstractAttribute::getAsStr().
2282 const std::string getAsStr(Attributor *A) const override {
2283 return getAssumed() ? "nofree" : "may-free";
2284 }
2285};
2286
2287struct AANoFreeFunction final : public AANoFreeImpl {
2288 AANoFreeFunction(const IRPosition &IRP, Attributor &A)
2289 : AANoFreeImpl(IRP, A) {}
2290
2291 /// See AbstractAttribute::trackStatistics()
2292 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nofree) }
2293};
2294
2295/// NoFree attribute deduction for a call sites.
2296struct AANoFreeCallSite final : AACalleeToCallSite<AANoFree, AANoFreeImpl> {
2297 AANoFreeCallSite(const IRPosition &IRP, Attributor &A)
2298 : AACalleeToCallSite<AANoFree, AANoFreeImpl>(IRP, A) {}
2299
2300 /// See AbstractAttribute::trackStatistics()
2301 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nofree); }
2302};
2303
2304/// NoFree attribute for floating values.
2305struct AANoFreeFloating : AANoFreeImpl {
2306 AANoFreeFloating(const IRPosition &IRP, Attributor &A)
2307 : AANoFreeImpl(IRP, A) {}
2308
2309 /// See AbstractAttribute::trackStatistics()
2310 void trackStatistics() const override{STATS_DECLTRACK_FLOATING_ATTR(nofree)}
2311
2312 /// See Abstract Attribute::updateImpl(...).
2313 ChangeStatus updateImpl(Attributor &A) override {
2314 const IRPosition &IRP = getIRPosition();
2315
2316 bool IsKnown;
2319 DepClassTy::OPTIONAL, IsKnown))
2320 return ChangeStatus::UNCHANGED;
2321
2322 Value &AssociatedValue = getIRPosition().getAssociatedValue();
2323 auto Pred = [&](const Use &U, bool &Follow) -> bool {
2324 Instruction *UserI = cast<Instruction>(U.getUser());
2325 if (auto *CB = dyn_cast<CallBase>(UserI)) {
2326 if (CB->isBundleOperand(&U))
2327 return false;
2328 if (!CB->isArgOperand(&U))
2329 return true;
2330 unsigned ArgNo = CB->getArgOperandNo(&U);
2331
2332 // Even if the argument is nofree, we still need to check for nocapture,
2333 // as the call may capture the argument without freeing it, and the
2334 // captured argument is freed later.
2335 bool IsKnown;
2337 A, this, IRPosition::callsite_argument(*CB, ArgNo),
2338 DepClassTy::REQUIRED, IsKnown))
2339 return false;
2340
2341 const AANoCapture *NoCaptureAA = nullptr;
2343 A, this, IRPosition::callsite_argument(*CB, ArgNo),
2344 DepClassTy::REQUIRED, IsKnown,
2345 /*IgnoreSubsumingPositions=*/false, &NoCaptureAA)) {
2346 if (NoCaptureAA && NoCaptureAA->isAssumedNoCaptureMaybeReturned()) {
2347 Follow = true;
2348 return true;
2349 }
2350 return false;
2351 }
2352
2353 return true;
2354 }
2355
2356 UseCaptureInfo CI = DetermineUseCaptureKind(U, /*Base=*/nullptr);
2357 if (!capturesAnyProvenance(CI))
2358 return true;
2360 Follow = true;
2361 return true;
2362 }
2363
2364 if (isa<ReturnInst>(UserI) && getIRPosition().isArgumentPosition())
2365 return true;
2366
2367 // Capturing user.
2368 return false;
2369 };
2370 if (!A.checkForAllUses(Pred, *this, AssociatedValue))
2371 return indicatePessimisticFixpoint();
2372
2373 return ChangeStatus::UNCHANGED;
2374 }
2375};
2376
2377/// NoFree attribute for a call site argument.
2378struct AANoFreeArgument final : AANoFreeFloating {
2379 AANoFreeArgument(const IRPosition &IRP, Attributor &A)
2380 : AANoFreeFloating(IRP, A) {}
2381
2382 /// See AbstractAttribute::trackStatistics()
2383 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nofree) }
2384};
2385
2386/// NoFree attribute for call site arguments.
2387struct AANoFreeCallSiteArgument final : AANoFreeFloating {
2388 AANoFreeCallSiteArgument(const IRPosition &IRP, Attributor &A)
2389 : AANoFreeFloating(IRP, A) {}
2390
2391 /// See AbstractAttribute::updateImpl(...).
2392 ChangeStatus updateImpl(Attributor &A) override {
2393 // TODO: Once we have call site specific value information we can provide
2394 // call site specific liveness information and then it makes
2395 // sense to specialize attributes for call sites arguments instead of
2396 // redirecting requests to the callee argument.
2397 Argument *Arg = getAssociatedArgument();
2398 if (!Arg)
2399 return indicatePessimisticFixpoint();
2400 const IRPosition &ArgPos = IRPosition::argument(*Arg);
2401 bool IsKnown;
2403 DepClassTy::REQUIRED, IsKnown))
2404 return ChangeStatus::UNCHANGED;
2405 return indicatePessimisticFixpoint();
2406 }
2407
2408 /// See AbstractAttribute::trackStatistics()
2409 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(nofree) };
2410};
2411
2412/// NoFree attribute for function return value.
2413struct AANoFreeReturned final : AANoFreeFloating {
2414 AANoFreeReturned(const IRPosition &IRP, Attributor &A)
2415 : AANoFreeFloating(IRP, A) {
2416 llvm_unreachable("NoFree is not applicable to function returns!");
2417 }
2418
2419 /// See AbstractAttribute::initialize(...).
2420 void initialize(Attributor &A) override {
2421 llvm_unreachable("NoFree is not applicable to function returns!");
2422 }
2423
2424 /// See AbstractAttribute::updateImpl(...).
2425 ChangeStatus updateImpl(Attributor &A) override {
2426 llvm_unreachable("NoFree is not applicable to function returns!");
2427 }
2428
2429 /// See AbstractAttribute::trackStatistics()
2430 void trackStatistics() const override {}
2431};
2432
2433/// NoFree attribute deduction for a call site return value.
2434struct AANoFreeCallSiteReturned final : AANoFreeFloating {
2435 AANoFreeCallSiteReturned(const IRPosition &IRP, Attributor &A)
2436 : AANoFreeFloating(IRP, A) {}
2437
2438 ChangeStatus manifest(Attributor &A) override {
2439 return ChangeStatus::UNCHANGED;
2440 }
2441 /// See AbstractAttribute::trackStatistics()
2442 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(nofree) }
2443};
2444} // namespace
2445
2446/// ------------------------ NonNull Argument Attribute ------------------------
2447
2449 Attribute::AttrKind ImpliedAttributeKind,
2450 bool IgnoreSubsumingPositions) {
2452 AttrKinds.push_back(Attribute::NonNull);
2455 AttrKinds.push_back(Attribute::Dereferenceable);
2456 if (A.hasAttr(IRP, AttrKinds, IgnoreSubsumingPositions, Attribute::NonNull))
2457 return true;
2458
2459 DominatorTree *DT = nullptr;
2460 AssumptionCache *AC = nullptr;
2461 InformationCache &InfoCache = A.getInfoCache();
2462 if (const Function *Fn = IRP.getAnchorScope()) {
2463 if (!Fn->isDeclaration()) {
2466 }
2467 }
2468
2470 if (IRP.getPositionKind() != IRP_RETURNED) {
2471 Worklist.push_back({IRP.getAssociatedValue(), IRP.getCtxI()});
2472 } else {
2473 bool UsedAssumedInformation = false;
2474 if (!A.checkForAllInstructions(
2475 [&](Instruction &I) {
2476 Worklist.push_back({*cast<ReturnInst>(I).getReturnValue(), &I});
2477 return true;
2478 },
2479 IRP.getAssociatedFunction(), nullptr, {Instruction::Ret},
2480 UsedAssumedInformation, false, /*CheckPotentiallyDead=*/true))
2481 return false;
2482 }
2483
2484 if (llvm::any_of(Worklist, [&](AA::ValueAndContext VAC) {
2485 return !isKnownNonZero(
2486 VAC.getValue(),
2487 SimplifyQuery(A.getDataLayout(), DT, AC, VAC.getCtxI()));
2488 }))
2489 return false;
2490
2491 A.manifestAttrs(IRP, {Attribute::get(IRP.getAnchorValue().getContext(),
2492 Attribute::NonNull)});
2493 return true;
2494}
2495
2496namespace {
2497static int64_t getKnownNonNullAndDerefBytesForUse(
2498 Attributor &A, const AbstractAttribute &QueryingAA, Value &AssociatedValue,
2499 const Use *U, const Instruction *I, bool &IsNonNull, bool &TrackUse) {
2500 TrackUse = false;
2501
2502 const Value *UseV = U->get();
2503 if (!UseV->getType()->isPointerTy())
2504 return 0;
2505
2506 // We need to follow common pointer manipulation uses to the accesses they
2507 // feed into. We can try to be smart to avoid looking through things we do not
2508 // like for now, e.g., non-inbounds GEPs.
2509 if (isa<CastInst>(I)) {
2510 TrackUse = true;
2511 return 0;
2512 }
2513
2515 TrackUse = true;
2516 return 0;
2517 }
2518
2519 Type *PtrTy = UseV->getType();
2520 const Function *F = I->getFunction();
2523 const DataLayout &DL = A.getInfoCache().getDL();
2524 if (const auto *CB = dyn_cast<CallBase>(I)) {
2525 if (CB->isBundleOperand(U)) {
2526 if (RetainedKnowledge RK = getKnowledgeFromUse(
2527 U, {Attribute::NonNull, Attribute::Dereferenceable})) {
2528 IsNonNull |=
2529 (RK.AttrKind == Attribute::NonNull || !NullPointerIsDefined);
2530 return RK.ArgValue;
2531 }
2532 return 0;
2533 }
2534
2535 if (CB->isCallee(U)) {
2536 IsNonNull |= !NullPointerIsDefined;
2537 return 0;
2538 }
2539
2540 unsigned ArgNo = CB->getArgOperandNo(U);
2541 IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo);
2542 // As long as we only use known information there is no need to track
2543 // dependences here.
2544 bool IsKnownNonNull;
2546 DepClassTy::NONE, IsKnownNonNull);
2547 IsNonNull |= IsKnownNonNull;
2548 auto *DerefAA =
2549 A.getAAFor<AADereferenceable>(QueryingAA, IRP, DepClassTy::NONE);
2550 return DerefAA ? DerefAA->getKnownDereferenceableBytes() : 0;
2551 }
2552
2553 std::optional<MemoryLocation> Loc = MemoryLocation::getOrNone(I);
2554 if (!Loc || Loc->Ptr != UseV || !Loc->Size.isPrecise() ||
2555 Loc->Size.isScalable() || I->isVolatile())
2556 return 0;
2557
2558 int64_t Offset;
2559 const Value *Base =
2560 getMinimalBaseOfPointer(A, QueryingAA, Loc->Ptr, Offset, DL);
2561 if (Base && Base == &AssociatedValue) {
2562 int64_t DerefBytes = Loc->Size.getValue() + Offset;
2563 IsNonNull |= !NullPointerIsDefined;
2564 return std::max(int64_t(0), DerefBytes);
2565 }
2566
2567 /// Corner case when an offset is 0.
2569 /*AllowNonInbounds*/ true);
2570 if (Base && Base == &AssociatedValue && Offset == 0) {
2571 int64_t DerefBytes = Loc->Size.getValue();
2572 IsNonNull |= !NullPointerIsDefined;
2573 return std::max(int64_t(0), DerefBytes);
2574 }
2575
2576 return 0;
2577}
2578
2579struct AANonNullImpl : AANonNull {
2580 AANonNullImpl(const IRPosition &IRP, Attributor &A) : AANonNull(IRP, A) {}
2581
2582 /// See AbstractAttribute::initialize(...).
2583 void initialize(Attributor &A) override {
2584 Value &V = *getAssociatedValue().stripPointerCasts();
2585 if (isa<ConstantPointerNull>(V)) {
2586 indicatePessimisticFixpoint();
2587 return;
2588 }
2589
2590 if (Instruction *CtxI = getCtxI())
2591 followUsesInMBEC(*this, A, getState(), *CtxI);
2592 }
2593
2594 /// See followUsesInMBEC
2595 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
2596 AANonNull::StateType &State) {
2597 bool IsNonNull = false;
2598 bool TrackUse = false;
2599 getKnownNonNullAndDerefBytesForUse(A, *this, getAssociatedValue(), U, I,
2600 IsNonNull, TrackUse);
2601 State.setKnown(IsNonNull);
2602 return TrackUse;
2603 }
2604
2605 /// See AbstractAttribute::getAsStr().
2606 const std::string getAsStr(Attributor *A) const override {
2607 return getAssumed() ? "nonnull" : "may-null";
2608 }
2609};
2610
2611/// NonNull attribute for a floating value.
2612struct AANonNullFloating : public AANonNullImpl {
2613 AANonNullFloating(const IRPosition &IRP, Attributor &A)
2614 : AANonNullImpl(IRP, A) {}
2615
2616 /// See AbstractAttribute::updateImpl(...).
2617 ChangeStatus updateImpl(Attributor &A) override {
2618 auto CheckIRP = [&](const IRPosition &IRP) {
2619 bool IsKnownNonNull;
2621 A, *this, IRP, DepClassTy::OPTIONAL, IsKnownNonNull);
2622 };
2623
2624 bool Stripped;
2625 bool UsedAssumedInformation = false;
2626 Value *AssociatedValue = &getAssociatedValue();
2628 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
2629 AA::AnyScope, UsedAssumedInformation))
2630 Stripped = false;
2631 else
2632 Stripped =
2633 Values.size() != 1 || Values.front().getValue() != AssociatedValue;
2634
2635 if (!Stripped) {
2636 bool IsKnown;
2637 if (auto *PHI = dyn_cast<PHINode>(AssociatedValue))
2638 if (llvm::all_of(PHI->incoming_values(), [&](Value *Op) {
2639 return AA::hasAssumedIRAttr<Attribute::NonNull>(
2640 A, this, IRPosition::value(*Op), DepClassTy::OPTIONAL,
2641 IsKnown);
2642 }))
2643 return ChangeStatus::UNCHANGED;
2644 if (auto *Select = dyn_cast<SelectInst>(AssociatedValue))
2646 A, this, IRPosition::value(*Select->getFalseValue()),
2647 DepClassTy::OPTIONAL, IsKnown) &&
2649 A, this, IRPosition::value(*Select->getTrueValue()),
2650 DepClassTy::OPTIONAL, IsKnown))
2651 return ChangeStatus::UNCHANGED;
2652
2653 // If we haven't stripped anything we might still be able to use a
2654 // different AA, but only if the IRP changes. Effectively when we
2655 // interpret this not as a call site value but as a floating/argument
2656 // value.
2657 const IRPosition AVIRP = IRPosition::value(*AssociatedValue);
2658 if (AVIRP == getIRPosition() || !CheckIRP(AVIRP))
2659 return indicatePessimisticFixpoint();
2660 return ChangeStatus::UNCHANGED;
2661 }
2662
2663 for (const auto &VAC : Values)
2664 if (!CheckIRP(IRPosition::value(*VAC.getValue())))
2665 return indicatePessimisticFixpoint();
2666
2667 return ChangeStatus::UNCHANGED;
2668 }
2669
2670 /// See AbstractAttribute::trackStatistics()
2671 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
2672};
2673
2674/// NonNull attribute for function return value.
2675struct AANonNullReturned final
2676 : AAReturnedFromReturnedValues<AANonNull, AANonNull, AANonNull::StateType,
2677 false, AANonNull::IRAttributeKind, false> {
2678 AANonNullReturned(const IRPosition &IRP, Attributor &A)
2679 : AAReturnedFromReturnedValues<AANonNull, AANonNull, AANonNull::StateType,
2680 false, Attribute::NonNull, false>(IRP, A) {
2681 }
2682
2683 /// See AbstractAttribute::getAsStr().
2684 const std::string getAsStr(Attributor *A) const override {
2685 return getAssumed() ? "nonnull" : "may-null";
2686 }
2687
2688 /// See AbstractAttribute::trackStatistics()
2689 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
2690};
2691
2692/// NonNull attribute for function argument.
2693struct AANonNullArgument final
2694 : AAArgumentFromCallSiteArguments<AANonNull, AANonNullImpl> {
2695 AANonNullArgument(const IRPosition &IRP, Attributor &A)
2696 : AAArgumentFromCallSiteArguments<AANonNull, AANonNullImpl>(IRP, A) {}
2697
2698 /// See AbstractAttribute::trackStatistics()
2699 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nonnull) }
2700};
2701
2702struct AANonNullCallSiteArgument final : AANonNullFloating {
2703 AANonNullCallSiteArgument(const IRPosition &IRP, Attributor &A)
2704 : AANonNullFloating(IRP, A) {}
2705
2706 /// See AbstractAttribute::trackStatistics()
2707 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(nonnull) }
2708};
2709
2710/// NonNull attribute for a call site return position.
2711struct AANonNullCallSiteReturned final
2712 : AACalleeToCallSite<AANonNull, AANonNullImpl> {
2713 AANonNullCallSiteReturned(const IRPosition &IRP, Attributor &A)
2714 : AACalleeToCallSite<AANonNull, AANonNullImpl>(IRP, A) {}
2715
2716 /// See AbstractAttribute::trackStatistics()
2717 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(nonnull) }
2718};
2719} // namespace
2720
2721/// ------------------------ Must-Progress Attributes --------------------------
2722namespace {
2723struct AAMustProgressImpl : public AAMustProgress {
2724 AAMustProgressImpl(const IRPosition &IRP, Attributor &A)
2725 : AAMustProgress(IRP, A) {}
2726
2727 /// See AbstractAttribute::initialize(...).
2728 void initialize(Attributor &A) override {
2729 bool IsKnown;
2731 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
2732 (void)IsKnown;
2733 }
2734
2735 /// See AbstractAttribute::getAsStr()
2736 const std::string getAsStr(Attributor *A) const override {
2737 return getAssumed() ? "mustprogress" : "may-not-progress";
2738 }
2739};
2740
2741struct AAMustProgressFunction final : AAMustProgressImpl {
2742 AAMustProgressFunction(const IRPosition &IRP, Attributor &A)
2743 : AAMustProgressImpl(IRP, A) {}
2744
2745 /// See AbstractAttribute::updateImpl(...).
2746 ChangeStatus updateImpl(Attributor &A) override {
2747 bool IsKnown;
2749 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnown)) {
2750 if (IsKnown)
2751 return indicateOptimisticFixpoint();
2752 return ChangeStatus::UNCHANGED;
2753 }
2754
2755 auto CheckForMustProgress = [&](AbstractCallSite ACS) {
2756 IRPosition IPos = IRPosition::callsite_function(*ACS.getInstruction());
2757 bool IsKnownMustProgress;
2759 A, this, IPos, DepClassTy::REQUIRED, IsKnownMustProgress,
2760 /* IgnoreSubsumingPositions */ true);
2761 };
2762
2763 bool AllCallSitesKnown = true;
2764 if (!A.checkForAllCallSites(CheckForMustProgress, *this,
2765 /* RequireAllCallSites */ true,
2766 AllCallSitesKnown))
2767 return indicatePessimisticFixpoint();
2768
2769 return ChangeStatus::UNCHANGED;
2770 }
2771
2772 /// See AbstractAttribute::trackStatistics()
2773 void trackStatistics() const override {
2774 STATS_DECLTRACK_FN_ATTR(mustprogress)
2775 }
2776};
2777
2778/// MustProgress attribute deduction for a call sites.
2779struct AAMustProgressCallSite final : AAMustProgressImpl {
2780 AAMustProgressCallSite(const IRPosition &IRP, Attributor &A)
2781 : AAMustProgressImpl(IRP, A) {}
2782
2783 /// See AbstractAttribute::updateImpl(...).
2784 ChangeStatus updateImpl(Attributor &A) override {
2785 // TODO: Once we have call site specific value information we can provide
2786 // call site specific liveness information and then it makes
2787 // sense to specialize attributes for call sites arguments instead of
2788 // redirecting requests to the callee argument.
2789 const IRPosition &FnPos = IRPosition::function(*getAnchorScope());
2790 bool IsKnownMustProgress;
2792 A, this, FnPos, DepClassTy::REQUIRED, IsKnownMustProgress))
2793 return indicatePessimisticFixpoint();
2794 return ChangeStatus::UNCHANGED;
2795 }
2796
2797 /// See AbstractAttribute::trackStatistics()
2798 void trackStatistics() const override {
2799 STATS_DECLTRACK_CS_ATTR(mustprogress);
2800 }
2801};
2802} // namespace
2803
2804/// ------------------------ No-Recurse Attributes ----------------------------
2805
2806namespace {
2807struct AANoRecurseImpl : public AANoRecurse {
2808 AANoRecurseImpl(const IRPosition &IRP, Attributor &A) : AANoRecurse(IRP, A) {}
2809
2810 /// See AbstractAttribute::initialize(...).
2811 void initialize(Attributor &A) override {
2812 bool IsKnown;
2814 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
2815 (void)IsKnown;
2816 }
2817
2818 /// See AbstractAttribute::getAsStr()
2819 const std::string getAsStr(Attributor *A) const override {
2820 return getAssumed() ? "norecurse" : "may-recurse";
2821 }
2822};
2823
2824struct AANoRecurseFunction final : AANoRecurseImpl {
2825 AANoRecurseFunction(const IRPosition &IRP, Attributor &A)
2826 : AANoRecurseImpl(IRP, A) {}
2827
2828 /// See AbstractAttribute::updateImpl(...).
2829 ChangeStatus updateImpl(Attributor &A) override {
2830
2831 // If all live call sites are known to be no-recurse, we are as well.
2832 auto CallSitePred = [&](AbstractCallSite ACS) {
2833 bool IsKnownNoRecurse;
2835 A, this,
2836 IRPosition::function(*ACS.getInstruction()->getFunction()),
2837 DepClassTy::NONE, IsKnownNoRecurse))
2838 return false;
2839 return IsKnownNoRecurse;
2840 };
2841 bool UsedAssumedInformation = false;
2842 if (A.checkForAllCallSites(CallSitePred, *this, true,
2843 UsedAssumedInformation)) {
2844 // If we know all call sites and all are known no-recurse, we are done.
2845 // If all known call sites, which might not be all that exist, are known
2846 // to be no-recurse, we are not done but we can continue to assume
2847 // no-recurse. If one of the call sites we have not visited will become
2848 // live, another update is triggered.
2849 if (!UsedAssumedInformation)
2850 indicateOptimisticFixpoint();
2851 return ChangeStatus::UNCHANGED;
2852 }
2853
2854 const AAInterFnReachability *EdgeReachability =
2855 A.getAAFor<AAInterFnReachability>(*this, getIRPosition(),
2856 DepClassTy::REQUIRED);
2857 if (EdgeReachability && EdgeReachability->canReach(A, *getAnchorScope()))
2858 return indicatePessimisticFixpoint();
2859 return ChangeStatus::UNCHANGED;
2860 }
2861
2862 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(norecurse) }
2863};
2864
2865/// NoRecurse attribute deduction for a call sites.
2866struct AANoRecurseCallSite final
2867 : AACalleeToCallSite<AANoRecurse, AANoRecurseImpl> {
2868 AANoRecurseCallSite(const IRPosition &IRP, Attributor &A)
2869 : AACalleeToCallSite<AANoRecurse, AANoRecurseImpl>(IRP, A) {}
2870
2871 /// See AbstractAttribute::trackStatistics()
2872 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(norecurse); }
2873};
2874} // namespace
2875
2876/// ------------------------ No-Convergent Attribute --------------------------
2877
2878namespace {
2879struct AANonConvergentImpl : public AANonConvergent {
2880 AANonConvergentImpl(const IRPosition &IRP, Attributor &A)
2881 : AANonConvergent(IRP, A) {}
2882
2883 /// See AbstractAttribute::getAsStr()
2884 const std::string getAsStr(Attributor *A) const override {
2885 return getAssumed() ? "non-convergent" : "may-be-convergent";
2886 }
2887};
2888
2889struct AANonConvergentFunction final : AANonConvergentImpl {
2890 AANonConvergentFunction(const IRPosition &IRP, Attributor &A)
2891 : AANonConvergentImpl(IRP, A) {}
2892
2893 /// See AbstractAttribute::updateImpl(...).
2894 ChangeStatus updateImpl(Attributor &A) override {
2895 // If all function calls are known to not be convergent, we are not
2896 // convergent.
2897 auto CalleeIsNotConvergent = [&](Instruction &Inst) {
2898 CallBase &CB = cast<CallBase>(Inst);
2900 if (!Callee || Callee->isIntrinsic()) {
2901 return false;
2902 }
2903 if (Callee->isDeclaration()) {
2904 return !Callee->hasFnAttribute(Attribute::Convergent);
2905 }
2906 const auto *ConvergentAA = A.getAAFor<AANonConvergent>(
2907 *this, IRPosition::function(*Callee), DepClassTy::REQUIRED);
2908 return ConvergentAA && ConvergentAA->isAssumedNotConvergent();
2909 };
2910
2911 bool UsedAssumedInformation = false;
2912 if (!A.checkForAllCallLikeInstructions(CalleeIsNotConvergent, *this,
2913 UsedAssumedInformation)) {
2914 return indicatePessimisticFixpoint();
2915 }
2916 return ChangeStatus::UNCHANGED;
2917 }
2918
2919 ChangeStatus manifest(Attributor &A) override {
2920 if (isKnownNotConvergent() &&
2921 A.hasAttr(getIRPosition(), Attribute::Convergent)) {
2922 A.removeAttrs(getIRPosition(), {Attribute::Convergent});
2923 return ChangeStatus::CHANGED;
2924 }
2925 return ChangeStatus::UNCHANGED;
2926 }
2927
2928 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(convergent) }
2929};
2930} // namespace
2931
2932/// -------------------- Undefined-Behavior Attributes ------------------------
2933
2934namespace {
2935struct AAUndefinedBehaviorImpl : public AAUndefinedBehavior {
2936 AAUndefinedBehaviorImpl(const IRPosition &IRP, Attributor &A)
2937 : AAUndefinedBehavior(IRP, A) {}
2938
2939 struct UBInfo {
2940 enum Kind {
2941 NullPtrAccess,
2942 UndefPtrAccess,
2943 UndefBranchCondition,
2944 UndefReturnValue,
2945 NullReturnViolatesNonNull,
2946 UndefCallArgument,
2947 NullArgViolatesNonNull,
2948 };
2949
2950 Kind K;
2951 std::optional<unsigned> ArgNo;
2952
2953 UBInfo(Kind K) : K(K), ArgNo(std::nullopt) {}
2954
2955 UBInfo(Kind K, std::optional<unsigned> ArgNo) : K(K), ArgNo(ArgNo) {}
2956 };
2957
2958 /// See AbstractAttribute::updateImpl(...).
2959 // through a pointer (i.e. also branches etc.)
2960 ChangeStatus updateImpl(Attributor &A) override {
2961 const size_t UBPrevSize = KnownUBInsts.size();
2962 const size_t NoUBPrevSize = AssumedNoUBInsts.size();
2963
2964 auto InspectMemAccessInstForUB = [&](Instruction &I) {
2965 // Volatile accesses on null are not necessarily UB.
2966 if (I.isVolatile())
2967 return true;
2968
2969 // Skip instructions that are already saved.
2970 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
2971 return true;
2972
2973 // If we reach here, we know we have an instruction
2974 // that accesses memory through a pointer operand,
2975 // for which getPointerOperand() should give it to us.
2976 Value *PtrOp =
2977 const_cast<Value *>(getPointerOperand(&I, /* AllowVolatile */ true));
2978 assert(PtrOp &&
2979 "Expected pointer operand of memory accessing instruction");
2980
2981 // Either we stopped and the appropriate action was taken,
2982 // or we got back a simplified value to continue.
2983 std::optional<Value *> SimplifiedPtrOp =
2984 stopOnUndefOrAssumed(A, PtrOp, &I, UBInfo::UndefPtrAccess);
2985 if (!SimplifiedPtrOp || !*SimplifiedPtrOp)
2986 return true;
2987 const Value *PtrOpVal = *SimplifiedPtrOp;
2988
2989 // A memory access through a pointer is considered UB
2990 // only if the pointer has constant null value.
2991 // TODO: Expand it to not only check constant values.
2992 if (!isa<ConstantPointerNull>(PtrOpVal)) {
2993 AssumedNoUBInsts.insert(&I);
2994 return true;
2995 }
2996 const Type *PtrTy = PtrOpVal->getType();
2997
2998 // Because we only consider instructions inside functions,
2999 // assume that a parent function exists.
3000 const Function *F = I.getFunction();
3001
3002 // A memory access using constant null pointer is only considered UB
3003 // if null pointer is _not_ defined for the target platform.
3005 AssumedNoUBInsts.insert(&I);
3006 else
3007 KnownUBInsts.try_emplace(&I, UBInfo::NullPtrAccess);
3008 return true;
3009 };
3010
3011 auto InspectBrInstForUB = [&](Instruction &I) {
3012 // A conditional branch instruction is considered UB if it has `undef`
3013 // condition.
3014
3015 // Skip instructions that are already saved.
3016 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
3017 return true;
3018
3019 // We know we have a branch instruction.
3020 auto *BrInst = cast<CondBrInst>(&I);
3021
3022 // Either we stopped and the appropriate action was taken,
3023 // or we got back a simplified value to continue.
3024 std::optional<Value *> SimplifiedCond = stopOnUndefOrAssumed(
3025 A, BrInst->getCondition(), BrInst, UBInfo::UndefBranchCondition);
3026 if (!SimplifiedCond || !*SimplifiedCond)
3027 return true;
3028 AssumedNoUBInsts.insert(&I);
3029 return true;
3030 };
3031
3032 auto InspectCallSiteForUB = [&](Instruction &I) {
3033 // Check whether a callsite always cause UB or not
3034
3035 // Skip instructions that are already saved.
3036 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
3037 return true;
3038
3039 // Check nonnull and noundef argument attribute violation for each
3040 // callsite.
3041 CallBase &CB = cast<CallBase>(I);
3043 if (!Callee)
3044 return true;
3045 for (unsigned idx = 0; idx < CB.arg_size(); idx++) {
3046 // If current argument is known to be simplified to null pointer and the
3047 // corresponding argument position is known to have nonnull attribute,
3048 // the argument is poison. Furthermore, if the argument is poison and
3049 // the position is known to have noundef attriubte, this callsite is
3050 // considered UB.
3051 if (idx >= Callee->arg_size())
3052 break;
3053 Value *ArgVal = CB.getArgOperand(idx);
3054 if (!ArgVal)
3055 continue;
3056 // Here, we handle three cases.
3057 // (1) Not having a value means it is dead. (we can replace the value
3058 // with undef)
3059 // (2) Simplified to undef. The argument violate noundef attriubte.
3060 // (3) Simplified to null pointer where known to be nonnull.
3061 // The argument is a poison value and violate noundef attribute.
3062 IRPosition CalleeArgumentIRP = IRPosition::callsite_argument(CB, idx);
3063 bool IsKnownNoUndef;
3065 A, this, CalleeArgumentIRP, DepClassTy::NONE, IsKnownNoUndef);
3066 if (!IsKnownNoUndef)
3067 continue;
3068 bool UsedAssumedInformation = false;
3069 std::optional<Value *> SimplifiedVal =
3070 A.getAssumedSimplified(IRPosition::value(*ArgVal), *this,
3071 UsedAssumedInformation, AA::Interprocedural);
3072 if (UsedAssumedInformation)
3073 continue;
3074 if (SimplifiedVal && !*SimplifiedVal)
3075 return true;
3076 if (!SimplifiedVal || isa<UndefValue>(**SimplifiedVal)) {
3077 KnownUBInsts.try_emplace(&I, UBInfo(UBInfo::UndefCallArgument, idx));
3078 continue;
3079 }
3080 if (!ArgVal->getType()->isPointerTy() ||
3081 !isa<ConstantPointerNull>(**SimplifiedVal))
3082 continue;
3083 bool IsKnownNonNull;
3085 A, this, CalleeArgumentIRP, DepClassTy::NONE, IsKnownNonNull);
3086 if (IsKnownNonNull)
3087 KnownUBInsts.try_emplace(&I,
3088 UBInfo(UBInfo::NullArgViolatesNonNull, idx));
3089 }
3090 return true;
3091 };
3092
3093 auto InspectReturnInstForUB = [&](Instruction &I) {
3094 auto &RI = cast<ReturnInst>(I);
3095 // Either we stopped and the appropriate action was taken,
3096 // or we got back a simplified return value to continue.
3097 std::optional<Value *> SimplifiedRetValue = stopOnUndefOrAssumed(
3098 A, RI.getReturnValue(), &I, UBInfo::UndefReturnValue);
3099 if (!SimplifiedRetValue || !*SimplifiedRetValue)
3100 return true;
3101
3102 // Check if a return instruction always cause UB or not
3103 // Note: It is guaranteed that the returned position of the anchor
3104 // scope has noundef attribute when this is called.
3105 // We also ensure the return position is not "assumed dead"
3106 // because the returned value was then potentially simplified to
3107 // `undef` in AAReturnedValues without removing the `noundef`
3108 // attribute yet.
3109
3110 // When the returned position has noundef attriubte, UB occurs in the
3111 // following cases.
3112 // (1) Returned value is known to be undef.
3113 // (2) The value is known to be a null pointer and the returned
3114 // position has nonnull attribute (because the returned value is
3115 // poison).
3116 if (isa<ConstantPointerNull>(*SimplifiedRetValue)) {
3117 bool IsKnownNonNull;
3119 A, this, IRPosition::returned(*getAnchorScope()), DepClassTy::NONE,
3120 IsKnownNonNull);
3121 if (IsKnownNonNull)
3122 KnownUBInsts.try_emplace(&I, UBInfo::NullReturnViolatesNonNull);
3123 }
3124
3125 return true;
3126 };
3127
3128 bool UsedAssumedInformation = false;
3129 A.checkForAllInstructions(InspectMemAccessInstForUB, *this,
3130 {Instruction::Load, Instruction::Store,
3131 Instruction::AtomicCmpXchg,
3132 Instruction::AtomicRMW},
3133 UsedAssumedInformation,
3134 /* CheckBBLivenessOnly */ true);
3135 A.checkForAllInstructions(InspectBrInstForUB, *this, {Instruction::CondBr},
3136 UsedAssumedInformation,
3137 /* CheckBBLivenessOnly */ true);
3138 A.checkForAllCallLikeInstructions(InspectCallSiteForUB, *this,
3139 UsedAssumedInformation);
3140
3141 // If the returned position of the anchor scope has noundef attriubte, check
3142 // all returned instructions.
3143 if (!getAnchorScope()->getReturnType()->isVoidTy()) {
3144 const IRPosition &ReturnIRP = IRPosition::returned(*getAnchorScope());
3145 if (!A.isAssumedDead(ReturnIRP, this, nullptr, UsedAssumedInformation)) {
3146 bool IsKnownNoUndef;
3148 A, this, ReturnIRP, DepClassTy::NONE, IsKnownNoUndef);
3149 if (IsKnownNoUndef)
3150 A.checkForAllInstructions(InspectReturnInstForUB, *this,
3151 {Instruction::Ret}, UsedAssumedInformation,
3152 /* CheckBBLivenessOnly */ true);
3153 }
3154 }
3155
3156 if (NoUBPrevSize != AssumedNoUBInsts.size() ||
3157 UBPrevSize != KnownUBInsts.size())
3158 return ChangeStatus::CHANGED;
3159 return ChangeStatus::UNCHANGED;
3160 }
3161
3162 bool isKnownToCauseUB(Instruction *I) const override {
3163 return KnownUBInsts.count(I);
3164 }
3165
3166 bool isAssumedToCauseUB(Instruction *I) const override {
3167 // In simple words, if an instruction is not in the assumed to _not_
3168 // cause UB, then it is assumed UB (that includes those
3169 // in the KnownUBInsts set). The rest is boilerplate
3170 // is to ensure that it is one of the instructions we test
3171 // for UB.
3172
3173 switch (I->getOpcode()) {
3174 case Instruction::Load:
3175 case Instruction::Store:
3176 case Instruction::AtomicCmpXchg:
3177 case Instruction::AtomicRMW:
3178 case Instruction::CondBr:
3179 return !AssumedNoUBInsts.count(I);
3180 default:
3181 return false;
3182 }
3183 return false;
3184 }
3185
3186 /// Emit an optimization remark explaining why \p I is known to cause UB,
3187 /// per \p Info, right before it is replaced with 'unreachable'.
3188 static void emitUBRemark(Attributor &A, Instruction *I, const UBInfo &Info) {
3189 auto Remark = [&](OptimizationRemark OR) {
3190 switch (Info.K) {
3191 case UBInfo::NullPtrAccess:
3192 case UBInfo::UndefPtrAccess: {
3193 return OR << "Memory access through a pointer known to be "
3194 << ore::NV("Pointer",
3195 getPointerOperand(I, /*AllowVolatile*/ true))
3196 << " is undefined behavior; replacing with 'unreachable'.";
3197 }
3198 case UBInfo::UndefBranchCondition:
3199 return OR << "Branch condition known to be "
3200 << ore::NV("Condition", cast<CondBrInst>(I)->getCondition())
3201 << " is undefined behavior; replacing with 'unreachable'.";
3202 case UBInfo::UndefReturnValue:
3203 case UBInfo::NullReturnViolatesNonNull:
3204 return OR << "Value returned known to be "
3205 << ore::NV("ReturnValue",
3206 cast<ReturnInst>(I)->getReturnValue())
3207 << " is undefined behavior; replacing with 'unreachable'.";
3208 case UBInfo::UndefCallArgument:
3209 case UBInfo::NullArgViolatesNonNull: {
3210 bool IsUndef = Info.K == UBInfo::UndefCallArgument;
3211 CallBase &CB = *cast<CallBase>(I);
3212 OR << "Argument " << ore::NV("ArgNo", *Info.ArgNo)
3213 << " passed to parameter of ";
3214 if (auto *Callee = dyn_cast_if_present<Function>(CB.getCalledOperand()))
3215 OR << ore::NV("Callee", Callee);
3216 else
3217 OR << "the callee";
3218 return OR << " known to be "
3219 << ore::NV("Argument", IsUndef ? "undef" : "null")
3220 << " is undefined behavior; replacing with 'unreachable'.";
3221 }
3222 }
3223 llvm_unreachable("Unknown UBInfo::Kind");
3224 };
3225 A.emitRemark<OptimizationRemark>(I, "UndefinedBehavior", Remark);
3226 }
3227
3228 ChangeStatus manifest(Attributor &A) override {
3229 if (KnownUBInsts.empty())
3230 return ChangeStatus::UNCHANGED;
3231 for (const auto &[I, Info] : KnownUBInsts) {
3232 emitUBRemark(A, I, Info);
3233 A.changeToUnreachableAfterManifest(I);
3234 }
3235 return ChangeStatus::CHANGED;
3236 }
3237
3238 /// See AbstractAttribute::getAsStr()
3239 const std::string getAsStr(Attributor *A) const override {
3240 return getAssumed() ? "undefined-behavior" : "no-ub";
3241 }
3242
3243 /// Note: The correctness of this analysis depends on the fact that the
3244 /// following 2 sets will stop changing after some point.
3245 /// "Change" here means that their size changes.
3246 /// The size of each set is monotonically increasing
3247 /// (we only add items to them) and it is upper bounded by the number of
3248 /// instructions in the processed function (we can never save more
3249 /// elements in either set than this number). Hence, at some point,
3250 /// they will stop increasing.
3251 /// Consequently, at some point, both sets will have stopped
3252 /// changing, effectively making the analysis reach a fixpoint.
3253
3254 /// Note: These 2 sets are disjoint and an instruction can be considered
3255 /// one of 3 things:
3256 /// 1) Known to cause UB (AAUndefinedBehavior could prove it) and put it in
3257 /// the KnownUBInsts set.
3258 /// 2) Assumed to cause UB (in every updateImpl, AAUndefinedBehavior
3259 /// has a reason to assume it).
3260 /// 3) Assumed to not cause UB. very other instruction - AAUndefinedBehavior
3261 /// could not find a reason to assume or prove that it can cause UB,
3262 /// hence it assumes it doesn't. We have a set for these instructions
3263 /// so that we don't reprocess them in every update.
3264 /// Note however that instructions in this set may cause UB.
3265
3266protected:
3267 /// A map from all live instructions _known_ to cause UB to the reason why,
3268 /// used to build actionable optimization remarks in manifest().
3269 MapVector<Instruction *, UBInfo> KnownUBInsts;
3270
3271private:
3272 /// A set of all the (live) instructions that are assumed to _not_ cause UB.
3273 SmallPtrSet<Instruction *, 8> AssumedNoUBInsts;
3274
3275 // Should be called on updates in which if we're processing an instruction
3276 // \p I that depends on a value \p V, one of the following has to happen:
3277 // - If the value is assumed, then stop.
3278 // - If the value is known but undef, then consider it UB for \p K.
3279 // - Otherwise, do specific processing with the simplified value.
3280 // We return std::nullopt in the first 2 cases to signify that an appropriate
3281 // action was taken and the caller should stop.
3282 // Otherwise, we return the simplified value that the caller should
3283 // use for specific processing.
3284 std::optional<Value *> stopOnUndefOrAssumed(Attributor &A, Value *V,
3285 Instruction *I, UBInfo::Kind K) {
3286 bool UsedAssumedInformation = false;
3287 std::optional<Value *> SimplifiedV =
3288 A.getAssumedSimplified(IRPosition::value(*V), *this,
3289 UsedAssumedInformation, AA::Interprocedural);
3290 if (!UsedAssumedInformation) {
3291 // Don't depend on assumed values.
3292 if (!SimplifiedV) {
3293 // If it is known (which we tested above) but it doesn't have a value,
3294 // then we can assume `undef` and hence the instruction is UB.
3295 KnownUBInsts.try_emplace(I, K);
3296 return std::nullopt;
3297 }
3298 if (!*SimplifiedV)
3299 return nullptr;
3300 V = *SimplifiedV;
3301 }
3302 if (isa<UndefValue>(V)) {
3303 KnownUBInsts.try_emplace(I, K);
3304 return std::nullopt;
3305 }
3306 return V;
3307 }
3308};
3309
3310struct AAUndefinedBehaviorFunction final : AAUndefinedBehaviorImpl {
3311 AAUndefinedBehaviorFunction(const IRPosition &IRP, Attributor &A)
3312 : AAUndefinedBehaviorImpl(IRP, A) {}
3313
3314 /// See AbstractAttribute::trackStatistics()
3315 void trackStatistics() const override {
3316 STATS_DECL(UndefinedBehaviorInstruction, Instruction,
3317 "Number of instructions known to have UB");
3318 BUILD_STAT_NAME(UndefinedBehaviorInstruction, Instruction) +=
3319 KnownUBInsts.size();
3320 }
3321};
3322} // namespace
3323
3324/// ------------------------ Will-Return Attributes ----------------------------
3325
3326namespace {
3327// Helper function that checks whether a function has any cycle which we don't
3328// know if it is bounded or not.
3329// Loops with maximum trip count are considered bounded, any other cycle not.
3330static bool mayContainUnboundedCycle(Function &F, Attributor &A) {
3331 ScalarEvolution *SE =
3332 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(F);
3333 LoopInfo *LI = A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(F);
3334 // If either SCEV or LoopInfo is not available for the function then we assume
3335 // any cycle to be unbounded cycle.
3336 // We use scc_iterator which uses Tarjan algorithm to find all the maximal
3337 // SCCs.To detect if there's a cycle, we only need to find the maximal ones.
3338 if (!SE || !LI) {
3339 for (scc_iterator<Function *> SCCI = scc_begin(&F); !SCCI.isAtEnd(); ++SCCI)
3340 if (SCCI.hasCycle())
3341 return true;
3342 return false;
3343 }
3344
3345 // If there's irreducible control, the function may contain non-loop cycles.
3347 return true;
3348
3349 // Any loop that does not have a max trip count is considered unbounded cycle.
3350 for (auto *L : LI->getLoopsInPreorder()) {
3351 if (!SE->getSmallConstantMaxTripCount(L))
3352 return true;
3353 }
3354 return false;
3355}
3356
3357struct AAWillReturnImpl : public AAWillReturn {
3358 AAWillReturnImpl(const IRPosition &IRP, Attributor &A)
3359 : AAWillReturn(IRP, A) {}
3360
3361 /// See AbstractAttribute::initialize(...).
3362 void initialize(Attributor &A) override {
3363 bool IsKnown;
3365 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
3366 (void)IsKnown;
3367 }
3368
3369 /// Check for `mustprogress` and `readonly` as they imply `willreturn`.
3370 bool isImpliedByMustprogressAndReadonly(Attributor &A, bool KnownOnly) {
3371 if (!A.hasAttr(getIRPosition(), {Attribute::MustProgress}))
3372 return false;
3373
3374 bool IsKnown;
3375 if (AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown))
3376 return IsKnown || !KnownOnly;
3377 return false;
3378 }
3379
3380 /// See AbstractAttribute::updateImpl(...).
3381 ChangeStatus updateImpl(Attributor &A) override {
3382 if (isImpliedByMustprogressAndReadonly(A, /* KnownOnly */ false))
3383 return ChangeStatus::UNCHANGED;
3384
3385 auto CheckForWillReturn = [&](Instruction &I) {
3387 bool IsKnown;
3389 A, this, IPos, DepClassTy::REQUIRED, IsKnown)) {
3390 if (IsKnown)
3391 return true;
3392 } else {
3393 return false;
3394 }
3395 bool IsKnownNoRecurse;
3397 A, this, IPos, DepClassTy::REQUIRED, IsKnownNoRecurse);
3398 };
3399
3400 bool UsedAssumedInformation = false;
3401 if (!A.checkForAllCallLikeInstructions(CheckForWillReturn, *this,
3402 UsedAssumedInformation))
3403 return indicatePessimisticFixpoint();
3404
3405 auto CheckForVolatile = [&](Instruction &I) {
3406 // Volatile operations are not willreturn.
3407 return !I.isVolatile();
3408 };
3409 if (!A.checkForAllInstructions(CheckForVolatile, *this,
3410 {Instruction::Load, Instruction::Store,
3411 Instruction::AtomicCmpXchg,
3412 Instruction::AtomicRMW},
3413 UsedAssumedInformation))
3414 return indicatePessimisticFixpoint();
3415
3416 return ChangeStatus::UNCHANGED;
3417 }
3418
3419 /// See AbstractAttribute::getAsStr()
3420 const std::string getAsStr(Attributor *A) const override {
3421 return getAssumed() ? "willreturn" : "may-noreturn";
3422 }
3423};
3424
3425struct AAWillReturnFunction final : AAWillReturnImpl {
3426 AAWillReturnFunction(const IRPosition &IRP, Attributor &A)
3427 : AAWillReturnImpl(IRP, A) {}
3428
3429 /// See AbstractAttribute::initialize(...).
3430 void initialize(Attributor &A) override {
3431 AAWillReturnImpl::initialize(A);
3432
3433 Function *F = getAnchorScope();
3434 assert(F && "Did expect an anchor function");
3435 if (F->isDeclaration() || mayContainUnboundedCycle(*F, A))
3436 indicatePessimisticFixpoint();
3437 }
3438
3439 /// See AbstractAttribute::trackStatistics()
3440 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(willreturn) }
3441};
3442
3443/// WillReturn attribute deduction for a call sites.
3444struct AAWillReturnCallSite final
3445 : AACalleeToCallSite<AAWillReturn, AAWillReturnImpl> {
3446 AAWillReturnCallSite(const IRPosition &IRP, Attributor &A)
3447 : AACalleeToCallSite<AAWillReturn, AAWillReturnImpl>(IRP, A) {}
3448
3449 /// See AbstractAttribute::updateImpl(...).
3450 ChangeStatus updateImpl(Attributor &A) override {
3451 if (isImpliedByMustprogressAndReadonly(A, /* KnownOnly */ false))
3452 return ChangeStatus::UNCHANGED;
3453
3454 return AACalleeToCallSite::updateImpl(A);
3455 }
3456
3457 /// See AbstractAttribute::trackStatistics()
3458 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(willreturn); }
3459};
3460} // namespace
3461
3462/// -------------------AAIntraFnReachability Attribute--------------------------
3463
3464/// All information associated with a reachability query. This boilerplate code
3465/// is used by both AAIntraFnReachability and AAInterFnReachability, with
3466/// different \p ToTy values.
3467template <typename ToTy> struct ReachabilityQueryInfo {
3468 enum class Reachable {
3471 };
3472
3473 /// Start here,
3474 const Instruction *From = nullptr;
3475 /// reach this place,
3476 const ToTy *To = nullptr;
3477 /// without going through any of these instructions,
3479 /// and remember if it worked:
3481
3482 /// Precomputed hash for this RQI.
3483 unsigned Hash = 0;
3484
3485 unsigned computeHashValue() const {
3486 assert(Hash == 0 && "Computed hash twice!");
3489 return const_cast<ReachabilityQueryInfo<ToTy> *>(this)->Hash =
3490 detail::combineHashValue(PairDMI ::getHashValue({From, To}),
3491 InstSetDMI::getHashValue(ExclusionSet));
3492 }
3493
3495 : From(From), To(To) {}
3496
3497 /// Constructor replacement to ensure unique and stable sets are used for the
3498 /// cache.
3500 const AA::InstExclusionSetTy *ES, bool MakeUnique)
3501 : From(&From), To(&To), ExclusionSet(ES) {
3502
3503 if (!ES || ES->empty()) {
3504 ExclusionSet = nullptr;
3505 } else if (MakeUnique) {
3506 ExclusionSet = A.getInfoCache().getOrCreateUniqueBlockExecutionSet(ES);
3507 }
3508 }
3509
3512};
3513
3514namespace llvm {
3515template <typename ToTy> struct DenseMapInfo<ReachabilityQueryInfo<ToTy> *> {
3518
3519 static unsigned getHashValue(const ReachabilityQueryInfo<ToTy> *RQI) {
3520 return RQI->Hash ? RQI->Hash : RQI->computeHashValue();
3521 }
3522 static bool isEqual(const ReachabilityQueryInfo<ToTy> *LHS,
3523 const ReachabilityQueryInfo<ToTy> *RHS) {
3524 if (!PairDMI::isEqual({LHS->From, LHS->To}, {RHS->From, RHS->To}))
3525 return false;
3526 return InstSetDMI::isEqual(LHS->ExclusionSet, RHS->ExclusionSet);
3527 }
3528};
3529
3530} // namespace llvm
3531
3532namespace {
3533
3534template <typename BaseTy, typename ToTy>
3535struct CachedReachabilityAA : public BaseTy {
3536 using RQITy = ReachabilityQueryInfo<ToTy>;
3537
3538 CachedReachabilityAA(const IRPosition &IRP, Attributor &A) : BaseTy(IRP, A) {}
3539
3540 /// See AbstractAttribute::isQueryAA.
3541 bool isQueryAA() const override { return true; }
3542
3543 /// See AbstractAttribute::updateImpl(...).
3544 ChangeStatus updateImpl(Attributor &A) override {
3545 ChangeStatus Changed = ChangeStatus::UNCHANGED;
3546 for (unsigned u = 0, e = QueryVector.size(); u < e; ++u) {
3547 RQITy *RQI = QueryVector[u];
3548 if (RQI->Result == RQITy::Reachable::No &&
3549 isReachableImpl(A, *RQI, /*IsTemporaryRQI=*/false))
3550 Changed = ChangeStatus::CHANGED;
3551 }
3552 return Changed;
3553 }
3554
3555 virtual bool isReachableImpl(Attributor &A, RQITy &RQI,
3556 bool IsTemporaryRQI) = 0;
3557
3558 bool rememberResult(Attributor &A, typename RQITy::Reachable Result,
3559 RQITy &RQI, bool UsedExclusionSet, bool IsTemporaryRQI) {
3560 RQI.Result = Result;
3561
3562 // Remove the temporary RQI from the cache.
3563 if (IsTemporaryRQI)
3564 QueryCache.erase(&RQI);
3565
3566 // Insert a plain RQI (w/o exclusion set) if that makes sense. Two options:
3567 // 1) If it is reachable, it doesn't matter if we have an exclusion set for
3568 // this query. 2) We did not use the exclusion set, potentially because
3569 // there is none.
3570 if (Result == RQITy::Reachable::Yes || !UsedExclusionSet) {
3571 RQITy PlainRQI(RQI.From, RQI.To);
3572 if (!QueryCache.count(&PlainRQI)) {
3573 RQITy *RQIPtr = new (A.Allocator) RQITy(RQI.From, RQI.To);
3574 RQIPtr->Result = Result;
3575 QueryVector.push_back(RQIPtr);
3576 QueryCache.insert(RQIPtr);
3577 }
3578 }
3579
3580 // Check if we need to insert a new permanent RQI with the exclusion set.
3581 if (IsTemporaryRQI && Result != RQITy::Reachable::Yes && UsedExclusionSet) {
3582 assert((!RQI.ExclusionSet || !RQI.ExclusionSet->empty()) &&
3583 "Did not expect empty set!");
3584 RQITy *RQIPtr = new (A.Allocator)
3585 RQITy(A, *RQI.From, *RQI.To, RQI.ExclusionSet, true);
3586 assert(RQIPtr->Result == RQITy::Reachable::No && "Already reachable?");
3587 RQIPtr->Result = Result;
3588 assert(!QueryCache.count(RQIPtr));
3589 QueryVector.push_back(RQIPtr);
3590 QueryCache.insert(RQIPtr);
3591 }
3592
3593 if (Result == RQITy::Reachable::No && IsTemporaryRQI)
3594 A.registerForUpdate(*this);
3595 return Result == RQITy::Reachable::Yes;
3596 }
3597
3598 const std::string getAsStr(Attributor *A) const override {
3599 // TODO: Return the number of reachable queries.
3600 return "#queries(" + std::to_string(QueryVector.size()) + ")";
3601 }
3602
3603 bool checkQueryCache(Attributor &A, RQITy &StackRQI,
3604 typename RQITy::Reachable &Result) {
3605 if (!this->getState().isValidState()) {
3606 Result = RQITy::Reachable::Yes;
3607 return true;
3608 }
3609
3610 // If we have an exclusion set we might be able to find our answer by
3611 // ignoring it first.
3612 if (StackRQI.ExclusionSet) {
3613 RQITy PlainRQI(StackRQI.From, StackRQI.To);
3614 auto It = QueryCache.find(&PlainRQI);
3615 if (It != QueryCache.end() && (*It)->Result == RQITy::Reachable::No) {
3616 Result = RQITy::Reachable::No;
3617 return true;
3618 }
3619 }
3620
3621 auto It = QueryCache.find(&StackRQI);
3622 if (It != QueryCache.end()) {
3623 Result = (*It)->Result;
3624 return true;
3625 }
3626
3627 // Insert a temporary for recursive queries. We will replace it with a
3628 // permanent entry later.
3629 QueryCache.insert(&StackRQI);
3630 return false;
3631 }
3632
3633private:
3634 SmallVector<RQITy *> QueryVector;
3635 DenseSet<RQITy *> QueryCache;
3636};
3637
3638struct AAIntraFnReachabilityFunction final
3639 : public CachedReachabilityAA<AAIntraFnReachability, Instruction> {
3640 using Base = CachedReachabilityAA<AAIntraFnReachability, Instruction>;
3641 AAIntraFnReachabilityFunction(const IRPosition &IRP, Attributor &A)
3642 : Base(IRP, A) {
3643 DT = A.getInfoCache().getAnalysisResultForFunction<DominatorTreeAnalysis>(
3644 *IRP.getAssociatedFunction());
3645 }
3646
3647 bool isAssumedReachable(
3648 Attributor &A, const Instruction &From, const Instruction &To,
3649 const AA::InstExclusionSetTy *ExclusionSet) const override {
3650 auto *NonConstThis = const_cast<AAIntraFnReachabilityFunction *>(this);
3651 if (&From == &To)
3652 return true;
3653
3654 RQITy StackRQI(A, From, To, ExclusionSet, false);
3655 RQITy::Reachable Result;
3656 if (!NonConstThis->checkQueryCache(A, StackRQI, Result))
3657 return NonConstThis->isReachableImpl(A, StackRQI,
3658 /*IsTemporaryRQI=*/true);
3659 return Result == RQITy::Reachable::Yes;
3660 }
3661
3662 ChangeStatus updateImpl(Attributor &A) override {
3663 // We only depend on liveness. DeadEdges is all we care about, check if any
3664 // of them changed.
3665 auto *LivenessAA =
3666 A.getAAFor<AAIsDead>(*this, getIRPosition(), DepClassTy::OPTIONAL);
3667 if (LivenessAA &&
3668 llvm::all_of(DeadEdges,
3669 [&](const auto &DeadEdge) {
3670 return LivenessAA->isEdgeDead(DeadEdge.first,
3671 DeadEdge.second);
3672 }) &&
3673 llvm::all_of(DeadBlocks, [&](const BasicBlock *BB) {
3674 return LivenessAA->isAssumedDead(BB);
3675 })) {
3676 return ChangeStatus::UNCHANGED;
3677 }
3678 DeadEdges.clear();
3679 DeadBlocks.clear();
3680 return Base::updateImpl(A);
3681 }
3682
3683 bool isReachableImpl(Attributor &A, RQITy &RQI,
3684 bool IsTemporaryRQI) override {
3685 const Instruction *Origin = RQI.From;
3686 bool UsedExclusionSet = false;
3687
3688 auto WillReachInBlock = [&](const Instruction &From, const Instruction &To,
3689 const AA::InstExclusionSetTy *ExclusionSet) {
3690 const Instruction *IP = &From;
3691 while (IP && IP != &To) {
3692 if (ExclusionSet && IP != Origin && ExclusionSet->count(IP)) {
3693 UsedExclusionSet = true;
3694 break;
3695 }
3696 IP = IP->getNextNode();
3697 }
3698 return IP == &To;
3699 };
3700
3701 const BasicBlock *FromBB = RQI.From->getParent();
3702 const BasicBlock *ToBB = RQI.To->getParent();
3703 assert(FromBB->getParent() == ToBB->getParent() &&
3704 "Not an intra-procedural query!");
3705
3706 // Check intra-block reachability, however, other reaching paths are still
3707 // possible.
3708 if (FromBB == ToBB &&
3709 WillReachInBlock(*RQI.From, *RQI.To, RQI.ExclusionSet))
3710 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
3711 IsTemporaryRQI);
3712
3713 // Check if reaching the ToBB block is sufficient or if even that would not
3714 // ensure reaching the target. In the latter case we are done.
3715 if (!WillReachInBlock(ToBB->front(), *RQI.To, RQI.ExclusionSet))
3716 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
3717 IsTemporaryRQI);
3718
3719 const Function *Fn = FromBB->getParent();
3720 SmallPtrSet<const BasicBlock *, 16> ExclusionBlocks;
3721 if (RQI.ExclusionSet)
3722 for (auto *I : *RQI.ExclusionSet)
3723 if (I->getFunction() == Fn)
3724 ExclusionBlocks.insert(I->getParent());
3725
3726 // Check if we make it out of the FromBB block at all.
3727 if (ExclusionBlocks.count(FromBB) &&
3728 !WillReachInBlock(*RQI.From, *FromBB->getTerminator(),
3729 RQI.ExclusionSet))
3730 return rememberResult(A, RQITy::Reachable::No, RQI, true, IsTemporaryRQI);
3731
3732 auto *LivenessAA =
3733 A.getAAFor<AAIsDead>(*this, getIRPosition(), DepClassTy::OPTIONAL);
3734 if (LivenessAA && LivenessAA->isAssumedDead(ToBB)) {
3735 DeadBlocks.insert(ToBB);
3736 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
3737 IsTemporaryRQI);
3738 }
3739
3740 SmallPtrSet<const BasicBlock *, 16> Visited;
3742 Worklist.push_back(FromBB);
3743
3744 DenseSet<std::pair<const BasicBlock *, const BasicBlock *>> LocalDeadEdges;
3745 while (!Worklist.empty()) {
3746 const BasicBlock *BB = Worklist.pop_back_val();
3747 if (!Visited.insert(BB).second)
3748 continue;
3749 for (const BasicBlock *SuccBB : successors(BB)) {
3750 if (LivenessAA && LivenessAA->isEdgeDead(BB, SuccBB)) {
3751 LocalDeadEdges.insert({BB, SuccBB});
3752 continue;
3753 }
3754 // We checked before if we just need to reach the ToBB block.
3755 if (SuccBB == ToBB)
3756 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
3757 IsTemporaryRQI);
3758 if (DT && ExclusionBlocks.empty() && DT->dominates(BB, ToBB))
3759 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
3760 IsTemporaryRQI);
3761
3762 if (ExclusionBlocks.count(SuccBB)) {
3763 UsedExclusionSet = true;
3764 continue;
3765 }
3766 Worklist.push_back(SuccBB);
3767 }
3768 }
3769
3770 DeadEdges.insert_range(LocalDeadEdges);
3771 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
3772 IsTemporaryRQI);
3773 }
3774
3775 /// See AbstractAttribute::trackStatistics()
3776 void trackStatistics() const override {}
3777
3778private:
3779 // Set of assumed dead blocks we used in the last query. If any changes we
3780 // update the state.
3781 DenseSet<const BasicBlock *> DeadBlocks;
3782
3783 // Set of assumed dead edges we used in the last query. If any changes we
3784 // update the state.
3785 DenseSet<std::pair<const BasicBlock *, const BasicBlock *>> DeadEdges;
3786
3787 /// The dominator tree of the function to short-circuit reasoning.
3788 const DominatorTree *DT = nullptr;
3789};
3790} // namespace
3791
3792/// ------------------------ NoAlias Argument Attribute ------------------------
3793
3795 Attribute::AttrKind ImpliedAttributeKind,
3796 bool IgnoreSubsumingPositions) {
3797 assert(ImpliedAttributeKind == Attribute::NoAlias &&
3798 "Unexpected attribute kind");
3799 Value *Val = &IRP.getAssociatedValue();
3801 if (isa<AllocaInst>(Val))
3802 return true;
3803 } else {
3804 IgnoreSubsumingPositions = true;
3805 }
3806
3807 if (isa<UndefValue>(Val))
3808 return true;
3809
3810 if (isa<ConstantPointerNull>(Val) &&
3813 return true;
3814
3815 if (A.hasAttr(IRP, {Attribute::ByVal, Attribute::NoAlias},
3816 IgnoreSubsumingPositions, Attribute::NoAlias))
3817 return true;
3818
3819 return false;
3820}
3821
3822namespace {
3823struct AANoAliasImpl : AANoAlias {
3824 AANoAliasImpl(const IRPosition &IRP, Attributor &A) : AANoAlias(IRP, A) {
3825 assert(getAssociatedType()->isPointerTy() &&
3826 "Noalias is a pointer attribute");
3827 }
3828
3829 const std::string getAsStr(Attributor *A) const override {
3830 return getAssumed() ? "noalias" : "may-alias";
3831 }
3832};
3833
3834/// NoAlias attribute for a floating value.
3835struct AANoAliasFloating final : AANoAliasImpl {
3836 AANoAliasFloating(const IRPosition &IRP, Attributor &A)
3837 : AANoAliasImpl(IRP, A) {}
3838
3839 /// See AbstractAttribute::updateImpl(...).
3840 ChangeStatus updateImpl(Attributor &A) override {
3841 // TODO: Implement this.
3842 return indicatePessimisticFixpoint();
3843 }
3844
3845 /// See AbstractAttribute::trackStatistics()
3846 void trackStatistics() const override {
3848 }
3849};
3850
3851/// NoAlias attribute for an argument.
3852struct AANoAliasArgument final
3853 : AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl> {
3854 using Base = AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl>;
3855 AANoAliasArgument(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {}
3856
3857 /// See AbstractAttribute::update(...).
3858 ChangeStatus updateImpl(Attributor &A) override {
3859 // We have to make sure no-alias on the argument does not break
3860 // synchronization when this is a callback argument, see also [1] below.
3861 // If synchronization cannot be affected, we delegate to the base updateImpl
3862 // function, otherwise we give up for now.
3863
3864 // If the function is no-sync, no-alias cannot break synchronization.
3865 bool IsKnownNoSycn;
3867 A, this, IRPosition::function_scope(getIRPosition()),
3868 DepClassTy::OPTIONAL, IsKnownNoSycn))
3869 return Base::updateImpl(A);
3870
3871 // If the argument is read-only, no-alias cannot break synchronization.
3872 bool IsKnown;
3873 if (AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown))
3874 return Base::updateImpl(A);
3875
3876 // If the argument is never passed through callbacks, no-alias cannot break
3877 // synchronization.
3878 bool UsedAssumedInformation = false;
3879 if (A.checkForAllCallSites(
3880 [](AbstractCallSite ACS) { return !ACS.isCallbackCall(); }, *this,
3881 true, UsedAssumedInformation))
3882 return Base::updateImpl(A);
3883
3884 // TODO: add no-alias but make sure it doesn't break synchronization by
3885 // introducing fake uses. See:
3886 // [1] Compiler Optimizations for OpenMP, J. Doerfert and H. Finkel,
3887 // International Workshop on OpenMP 2018,
3888 // http://compilers.cs.uni-saarland.de/people/doerfert/par_opt18.pdf
3889
3890 return indicatePessimisticFixpoint();
3891 }
3892
3893 /// See AbstractAttribute::trackStatistics()
3894 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noalias) }
3895};
3896
3897struct AANoAliasCallSiteArgument final : AANoAliasImpl {
3898 AANoAliasCallSiteArgument(const IRPosition &IRP, Attributor &A)
3899 : AANoAliasImpl(IRP, A) {}
3900
3901 /// Determine if the underlying value may alias with the call site argument
3902 /// \p OtherArgNo of \p ICS (= the underlying call site).
3903 bool mayAliasWithArgument(Attributor &A, AAResults *&AAR,
3904 const AAMemoryBehavior &MemBehaviorAA,
3905 const CallBase &CB, unsigned OtherArgNo) {
3906 // We do not need to worry about aliasing with the underlying IRP.
3907 if (this->getCallSiteArgNo() == (int)OtherArgNo)
3908 return false;
3909
3910 // If it is not a pointer or pointer vector we do not alias.
3911 const Value *ArgOp = CB.getArgOperand(OtherArgNo);
3912 if (!ArgOp->getType()->isPtrOrPtrVectorTy())
3913 return false;
3914
3915 auto *CBArgMemBehaviorAA = A.getAAFor<AAMemoryBehavior>(
3916 *this, IRPosition::callsite_argument(CB, OtherArgNo), DepClassTy::NONE);
3917
3918 // If the argument is readnone, there is no read-write aliasing.
3919 if (CBArgMemBehaviorAA && CBArgMemBehaviorAA->isAssumedReadNone()) {
3920 A.recordDependence(*CBArgMemBehaviorAA, *this, DepClassTy::OPTIONAL);
3921 return false;
3922 }
3923
3924 // If the argument is readonly and the underlying value is readonly, there
3925 // is no read-write aliasing.
3926 bool IsReadOnly = MemBehaviorAA.isAssumedReadOnly();
3927 if (CBArgMemBehaviorAA && CBArgMemBehaviorAA->isAssumedReadOnly() &&
3928 IsReadOnly) {
3929 A.recordDependence(MemBehaviorAA, *this, DepClassTy::OPTIONAL);
3930 A.recordDependence(*CBArgMemBehaviorAA, *this, DepClassTy::OPTIONAL);
3931 return false;
3932 }
3933
3934 // We have to utilize actual alias analysis queries so we need the object.
3935 if (!AAR)
3936 AAR = A.getInfoCache().getAnalysisResultForFunction<AAManager>(
3937 *getAnchorScope());
3938
3939 // Try to rule it out at the call site.
3940 bool IsAliasing = !AAR || !AAR->isNoAlias(&getAssociatedValue(), ArgOp);
3941 LLVM_DEBUG(dbgs() << "[NoAliasCSArg] Check alias between "
3942 "callsite arguments: "
3943 << getAssociatedValue() << " " << *ArgOp << " => "
3944 << (IsAliasing ? "" : "no-") << "alias \n");
3945
3946 return IsAliasing;
3947 }
3948
3949 bool isKnownNoAliasDueToNoAliasPreservation(
3950 Attributor &A, AAResults *&AAR, const AAMemoryBehavior &MemBehaviorAA) {
3951 // We can deduce "noalias" if the following conditions hold.
3952 // (i) Associated value is assumed to be noalias in the definition.
3953 // (ii) Associated value is assumed to be no-capture in all the uses
3954 // possibly executed before this callsite.
3955 // (iii) There is no other pointer argument which could alias with the
3956 // value.
3957
3958 const IRPosition &VIRP = IRPosition::value(getAssociatedValue());
3959 const Function *ScopeFn = VIRP.getAnchorScope();
3960 // Check whether the value is captured in the scope using AANoCapture.
3961 // Look at CFG and check only uses possibly executed before this
3962 // callsite.
3963 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
3964 Instruction *UserI = cast<Instruction>(U.getUser());
3965
3966 // If UserI is the curr instruction and there is a single potential use of
3967 // the value in UserI we allow the use.
3968 // TODO: We should inspect the operands and allow those that cannot alias
3969 // with the value.
3970 if (UserI == getCtxI() && UserI->getNumOperands() == 1)
3971 return true;
3972
3973 if (ScopeFn) {
3974 if (auto *CB = dyn_cast<CallBase>(UserI)) {
3975 if (CB->isArgOperand(&U)) {
3976
3977 unsigned ArgNo = CB->getArgOperandNo(&U);
3978
3979 bool IsKnownNoCapture;
3981 A, this, IRPosition::callsite_argument(*CB, ArgNo),
3982 DepClassTy::OPTIONAL, IsKnownNoCapture))
3983 return true;
3984 }
3985 }
3986
3988 A, *UserI, *getCtxI(), *this, /* ExclusionSet */ nullptr,
3989 [ScopeFn](const Function &Fn) { return &Fn != ScopeFn; }))
3990 return true;
3991 }
3992
3993 // TODO: We should track the capturing uses in AANoCapture but the problem
3994 // is CGSCC runs. For those we would need to "allow" AANoCapture for
3995 // a value in the module slice.
3996 // TODO(captures): Make this more precise.
3997 UseCaptureInfo CI = DetermineUseCaptureKind(U, /*Base=*/nullptr);
3998 if (capturesNothing(CI))
3999 return true;
4000 if (CI.isPassthrough()) {
4001 Follow = true;
4002 return true;
4003 }
4004 LLVM_DEBUG(dbgs() << "[AANoAliasCSArg] Unknown user: " << *UserI << "\n");
4005 return false;
4006 };
4007
4008 bool IsKnownNoCapture;
4009 const AANoCapture *NoCaptureAA = nullptr;
4010 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
4011 A, this, VIRP, DepClassTy::NONE, IsKnownNoCapture, false, &NoCaptureAA);
4012 if (!IsAssumedNoCapture &&
4013 (!NoCaptureAA || !NoCaptureAA->isAssumedNoCaptureMaybeReturned())) {
4014 if (!A.checkForAllUses(UsePred, *this, getAssociatedValue())) {
4015 LLVM_DEBUG(
4016 dbgs() << "[AANoAliasCSArg] " << getAssociatedValue()
4017 << " cannot be noalias as it is potentially captured\n");
4018 return false;
4019 }
4020 }
4021 if (NoCaptureAA)
4022 A.recordDependence(*NoCaptureAA, *this, DepClassTy::OPTIONAL);
4023
4024 // Check there is no other pointer argument which could alias with the
4025 // value passed at this call site.
4026 // TODO: AbstractCallSite
4027 const auto &CB = cast<CallBase>(getAnchorValue());
4028 for (unsigned OtherArgNo = 0; OtherArgNo < CB.arg_size(); OtherArgNo++)
4029 if (mayAliasWithArgument(A, AAR, MemBehaviorAA, CB, OtherArgNo))
4030 return false;
4031
4032 return true;
4033 }
4034
4035 /// See AbstractAttribute::updateImpl(...).
4036 ChangeStatus updateImpl(Attributor &A) override {
4037 // If the argument is readnone we are done as there are no accesses via the
4038 // argument.
4039 auto *MemBehaviorAA =
4040 A.getAAFor<AAMemoryBehavior>(*this, getIRPosition(), DepClassTy::NONE);
4041 if (MemBehaviorAA && MemBehaviorAA->isAssumedReadNone()) {
4042 A.recordDependence(*MemBehaviorAA, *this, DepClassTy::OPTIONAL);
4043 return ChangeStatus::UNCHANGED;
4044 }
4045
4046 bool IsKnownNoAlias;
4047 const IRPosition &VIRP = IRPosition::value(getAssociatedValue());
4049 A, this, VIRP, DepClassTy::REQUIRED, IsKnownNoAlias)) {
4050 LLVM_DEBUG(dbgs() << "[AANoAlias] " << getAssociatedValue()
4051 << " is not no-alias at the definition\n");
4052 return indicatePessimisticFixpoint();
4053 }
4054
4055 AAResults *AAR = nullptr;
4056 if (MemBehaviorAA &&
4057 isKnownNoAliasDueToNoAliasPreservation(A, AAR, *MemBehaviorAA)) {
4058 LLVM_DEBUG(
4059 dbgs() << "[AANoAlias] No-Alias deduced via no-alias preservation\n");
4060 return ChangeStatus::UNCHANGED;
4061 }
4062
4063 return indicatePessimisticFixpoint();
4064 }
4065
4066 /// See AbstractAttribute::trackStatistics()
4067 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(noalias) }
4068};
4069
4070/// NoAlias attribute for function return value.
4071struct AANoAliasReturned final : AANoAliasImpl {
4072 AANoAliasReturned(const IRPosition &IRP, Attributor &A)
4073 : AANoAliasImpl(IRP, A) {}
4074
4075 /// See AbstractAttribute::updateImpl(...).
4076 ChangeStatus updateImpl(Attributor &A) override {
4077
4078 auto CheckReturnValue = [&](Value &RV) -> bool {
4079 if (Constant *C = dyn_cast<Constant>(&RV))
4080 if (C->isNullValue() || isa<UndefValue>(C))
4081 return true;
4082
4083 /// For now, we can only deduce noalias if we have call sites.
4084 /// FIXME: add more support.
4085 if (!isa<CallBase>(&RV))
4086 return false;
4087
4088 const IRPosition &RVPos = IRPosition::value(RV);
4089 bool IsKnownNoAlias;
4091 A, this, RVPos, DepClassTy::REQUIRED, IsKnownNoAlias))
4092 return false;
4093
4094 bool IsKnownNoCapture;
4095 const AANoCapture *NoCaptureAA = nullptr;
4096 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
4097 A, this, RVPos, DepClassTy::REQUIRED, IsKnownNoCapture, false,
4098 &NoCaptureAA);
4099 return IsAssumedNoCapture ||
4100 (NoCaptureAA && NoCaptureAA->isAssumedNoCaptureMaybeReturned());
4101 };
4102
4103 if (!A.checkForAllReturnedValues(CheckReturnValue, *this))
4104 return indicatePessimisticFixpoint();
4105
4106 return ChangeStatus::UNCHANGED;
4107 }
4108
4109 /// See AbstractAttribute::trackStatistics()
4110 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noalias) }
4111};
4112
4113/// NoAlias attribute deduction for a call site return value.
4114struct AANoAliasCallSiteReturned final
4115 : AACalleeToCallSite<AANoAlias, AANoAliasImpl> {
4116 AANoAliasCallSiteReturned(const IRPosition &IRP, Attributor &A)
4117 : AACalleeToCallSite<AANoAlias, AANoAliasImpl>(IRP, A) {}
4118
4119 /// See AbstractAttribute::trackStatistics()
4120 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(noalias); }
4121};
4122} // namespace
4123
4124/// -------------------AAIsDead Function Attribute-----------------------
4125
4126namespace {
4127struct AAIsDeadValueImpl : public AAIsDead {
4128 AAIsDeadValueImpl(const IRPosition &IRP, Attributor &A) : AAIsDead(IRP, A) {}
4129
4130 /// See AAIsDead::isAssumedDead().
4131 bool isAssumedDead() const override { return isAssumed(IS_DEAD); }
4132
4133 /// See AAIsDead::isKnownDead().
4134 bool isKnownDead() const override { return isKnown(IS_DEAD); }
4135
4136 /// See AAIsDead::isAssumedDead(BasicBlock *).
4137 bool isAssumedDead(const BasicBlock *BB) const override { return false; }
4138
4139 /// See AAIsDead::isKnownDead(BasicBlock *).
4140 bool isKnownDead(const BasicBlock *BB) const override { return false; }
4141
4142 /// See AAIsDead::isAssumedDead(Instruction *I).
4143 bool isAssumedDead(const Instruction *I) const override {
4144 return I == getCtxI() && isAssumedDead();
4145 }
4146
4147 /// See AAIsDead::isKnownDead(Instruction *I).
4148 bool isKnownDead(const Instruction *I) const override {
4149 return isAssumedDead(I) && isKnownDead();
4150 }
4151
4152 /// See AbstractAttribute::getAsStr().
4153 const std::string getAsStr(Attributor *A) const override {
4154 return isAssumedDead() ? "assumed-dead" : "assumed-live";
4155 }
4156
4157 /// Check if all uses are assumed dead.
4158 bool areAllUsesAssumedDead(Attributor &A, Value &V) {
4159 // Callers might not check the type, void has no uses.
4160 if (V.getType()->isVoidTy() || V.use_empty())
4161 return true;
4162
4163 // If we replace a value with a constant there are no uses left afterwards.
4164 if (!isa<Constant>(V)) {
4165 if (auto *I = dyn_cast<Instruction>(&V))
4166 if (!A.isRunOn(*I->getFunction()))
4167 return false;
4168 bool UsedAssumedInformation = false;
4169 std::optional<Constant *> C =
4170 A.getAssumedConstant(V, *this, UsedAssumedInformation);
4171 if (!C || *C)
4172 return true;
4173 }
4174
4175 auto UsePred = [&](const Use &U, bool &Follow) { return false; };
4176 // Explicitly set the dependence class to required because we want a long
4177 // chain of N dependent instructions to be considered live as soon as one is
4178 // without going through N update cycles. This is not required for
4179 // correctness.
4180 return A.checkForAllUses(UsePred, *this, V, /* CheckBBLivenessOnly */ false,
4181 DepClassTy::REQUIRED,
4182 /* IgnoreDroppableUses */ false);
4183 }
4184
4185 /// Determine if \p I is assumed to be side-effect free.
4186 bool isAssumedSideEffectFree(Attributor &A, Instruction *I) {
4188 return true;
4189
4190 if (!I->isTerminator() && !I->mayHaveSideEffects())
4191 return true;
4192
4193 auto *CB = dyn_cast<CallBase>(I);
4194 if (!CB || isa<IntrinsicInst>(CB))
4195 return false;
4196
4197 const IRPosition &CallIRP = IRPosition::callsite_function(*CB);
4198
4199 bool IsKnownNoUnwind;
4201 A, this, CallIRP, DepClassTy::OPTIONAL, IsKnownNoUnwind))
4202 return false;
4203
4204 bool IsKnown;
4205 return AA::isAssumedReadOnly(A, CallIRP, *this, IsKnown);
4206 }
4207};
4208
4209struct AAIsDeadFloating : public AAIsDeadValueImpl {
4210 AAIsDeadFloating(const IRPosition &IRP, Attributor &A)
4211 : AAIsDeadValueImpl(IRP, A) {}
4212
4213 /// See AbstractAttribute::initialize(...).
4214 void initialize(Attributor &A) override {
4215 AAIsDeadValueImpl::initialize(A);
4216
4217 if (isa<UndefValue>(getAssociatedValue())) {
4218 indicatePessimisticFixpoint();
4219 return;
4220 }
4221
4222 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
4223 if (!isAssumedSideEffectFree(A, I)) {
4225 indicatePessimisticFixpoint();
4226 else
4227 removeAssumedBits(HAS_NO_EFFECT);
4228 }
4229 }
4230
4231 bool isDeadFence(Attributor &A, FenceInst &FI) {
4232 const auto *ExecDomainAA = A.lookupAAFor<AAExecutionDomain>(
4233 IRPosition::function(*FI.getFunction()), *this, DepClassTy::NONE);
4234 if (!ExecDomainAA || !ExecDomainAA->isNoOpFence(FI))
4235 return false;
4236 A.recordDependence(*ExecDomainAA, *this, DepClassTy::OPTIONAL);
4237 return true;
4238 }
4239
4240 bool isDeadStore(Attributor &A, StoreInst &SI,
4241 SmallSetVector<Instruction *, 8> *AssumeOnlyInst = nullptr) {
4242 // Lang ref now states volatile store is not UB/dead, let's skip them.
4243 if (SI.isVolatile())
4244 return false;
4245
4246 // If we are collecting assumes to be deleted we are in the manifest stage.
4247 // It's problematic to collect the potential copies again now so we use the
4248 // cached ones.
4249 bool UsedAssumedInformation = false;
4250 if (!AssumeOnlyInst) {
4251 PotentialCopies.clear();
4252 if (!AA::getPotentialCopiesOfStoredValue(A, SI, PotentialCopies, *this,
4253 UsedAssumedInformation)) {
4254 LLVM_DEBUG(
4255 dbgs()
4256 << "[AAIsDead] Could not determine potential copies of store!\n");
4257 return false;
4258 }
4259 }
4260 LLVM_DEBUG(dbgs() << "[AAIsDead] Store has " << PotentialCopies.size()
4261 << " potential copies.\n");
4262
4263 InformationCache &InfoCache = A.getInfoCache();
4264 return llvm::all_of(PotentialCopies, [&](Value *V) {
4265 if (A.isAssumedDead(IRPosition::value(*V), this, nullptr,
4266 UsedAssumedInformation))
4267 return true;
4268 if (auto *LI = dyn_cast<LoadInst>(V)) {
4269 if (llvm::all_of(LI->uses(), [&](const Use &U) {
4270 auto &UserI = cast<Instruction>(*U.getUser());
4271 if (InfoCache.isOnlyUsedByAssume(UserI)) {
4272 if (AssumeOnlyInst)
4273 AssumeOnlyInst->insert(&UserI);
4274 return true;
4275 }
4276 return A.isAssumedDead(U, this, nullptr, UsedAssumedInformation);
4277 })) {
4278 return true;
4279 }
4280 }
4281 LLVM_DEBUG(dbgs() << "[AAIsDead] Potential copy " << *V
4282 << " is assumed live!\n");
4283 return false;
4284 });
4285 }
4286
4287 /// See AbstractAttribute::getAsStr().
4288 const std::string getAsStr(Attributor *A) const override {
4289 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
4291 if (isValidState())
4292 return "assumed-dead-store";
4294 if (isValidState())
4295 return "assumed-dead-fence";
4296 return AAIsDeadValueImpl::getAsStr(A);
4297 }
4298
4299 /// See AbstractAttribute::updateImpl(...).
4300 ChangeStatus updateImpl(Attributor &A) override {
4301 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
4302 if (auto *SI = dyn_cast_or_null<StoreInst>(I)) {
4303 if (!isDeadStore(A, *SI))
4304 return indicatePessimisticFixpoint();
4305 } else if (auto *FI = dyn_cast_or_null<FenceInst>(I)) {
4306 if (!isDeadFence(A, *FI))
4307 return indicatePessimisticFixpoint();
4308 } else {
4309 if (!isAssumedSideEffectFree(A, I))
4310 return indicatePessimisticFixpoint();
4311 if (!areAllUsesAssumedDead(A, getAssociatedValue()))
4312 return indicatePessimisticFixpoint();
4313 }
4315 }
4316
4317 bool isRemovableStore() const override {
4318 return isAssumed(IS_REMOVABLE) && isa<StoreInst>(&getAssociatedValue());
4319 }
4320
4321 /// See AbstractAttribute::manifest(...).
4322 ChangeStatus manifest(Attributor &A) override {
4323 Value &V = getAssociatedValue();
4324 if (auto *I = dyn_cast<Instruction>(&V)) {
4325 // If we get here we basically know the users are all dead. We check if
4326 // isAssumedSideEffectFree returns true here again because it might not be
4327 // the case and only the users are dead but the instruction (=call) is
4328 // still needed.
4329 if (auto *SI = dyn_cast<StoreInst>(I)) {
4330 SmallSetVector<Instruction *, 8> AssumeOnlyInst;
4331 bool IsDead = isDeadStore(A, *SI, &AssumeOnlyInst);
4332 (void)IsDead;
4333 assert(IsDead && "Store was assumed to be dead!");
4334 A.deleteAfterManifest(*I);
4335 for (size_t i = 0; i < AssumeOnlyInst.size(); ++i) {
4336 Instruction *AOI = AssumeOnlyInst[i];
4337 for (auto *Usr : AOI->users())
4338 AssumeOnlyInst.insert(cast<Instruction>(Usr));
4339 A.deleteAfterManifest(*AOI);
4340 }
4341 return ChangeStatus::CHANGED;
4342 }
4343 if (auto *FI = dyn_cast<FenceInst>(I)) {
4344 assert(isDeadFence(A, *FI));
4345 A.deleteAfterManifest(*FI);
4346 return ChangeStatus::CHANGED;
4347 }
4348 if (isAssumedSideEffectFree(A, I) && !I->isTerminator()) {
4349 A.deleteAfterManifest(*I);
4350 return ChangeStatus::CHANGED;
4351 }
4352 }
4354 }
4355
4356 /// See AbstractAttribute::trackStatistics()
4357 void trackStatistics() const override {
4359 }
4360
4361private:
4362 // The potential copies of a dead store, used for deletion during manifest.
4363 SmallSetVector<Value *, 4> PotentialCopies;
4364};
4365
4366struct AAIsDeadArgument : public AAIsDeadFloating {
4367 AAIsDeadArgument(const IRPosition &IRP, Attributor &A)
4368 : AAIsDeadFloating(IRP, A) {}
4369
4370 /// See AbstractAttribute::manifest(...).
4371 ChangeStatus manifest(Attributor &A) override {
4372 Argument &Arg = *getAssociatedArgument();
4373 if (A.isValidFunctionSignatureRewrite(Arg, /* ReplacementTypes */ {}))
4374 if (A.registerFunctionSignatureRewrite(
4375 Arg, /* ReplacementTypes */ {},
4378 return ChangeStatus::CHANGED;
4379 }
4380 return ChangeStatus::UNCHANGED;
4381 }
4382
4383 /// See AbstractAttribute::trackStatistics()
4384 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(IsDead) }
4385};
4386
4387struct AAIsDeadCallSiteArgument : public AAIsDeadValueImpl {
4388 AAIsDeadCallSiteArgument(const IRPosition &IRP, Attributor &A)
4389 : AAIsDeadValueImpl(IRP, A) {}
4390
4391 /// See AbstractAttribute::initialize(...).
4392 void initialize(Attributor &A) override {
4393 AAIsDeadValueImpl::initialize(A);
4394 if (isa<UndefValue>(getAssociatedValue()))
4395 indicatePessimisticFixpoint();
4396 }
4397
4398 /// See AbstractAttribute::updateImpl(...).
4399 ChangeStatus updateImpl(Attributor &A) override {
4400 // TODO: Once we have call site specific value information we can provide
4401 // call site specific liveness information and then it makes
4402 // sense to specialize attributes for call sites arguments instead of
4403 // redirecting requests to the callee argument.
4404 Argument *Arg = getAssociatedArgument();
4405 if (!Arg)
4406 return indicatePessimisticFixpoint();
4407 const IRPosition &ArgPos = IRPosition::argument(*Arg);
4408 auto *ArgAA = A.getAAFor<AAIsDead>(*this, ArgPos, DepClassTy::REQUIRED);
4409 if (!ArgAA)
4410 return indicatePessimisticFixpoint();
4411 return clampStateAndIndicateChange(getState(), ArgAA->getState());
4412 }
4413
4414 /// See AbstractAttribute::manifest(...).
4415 ChangeStatus manifest(Attributor &A) override {
4416 CallBase &CB = cast<CallBase>(getAnchorValue());
4417 Use &U = CB.getArgOperandUse(getCallSiteArgNo());
4418 assert(!isa<UndefValue>(U.get()) &&
4419 "Expected undef values to be filtered out!");
4420 UndefValue &UV = *UndefValue::get(U->getType());
4421 if (A.changeUseAfterManifest(U, UV))
4422 return ChangeStatus::CHANGED;
4423 return ChangeStatus::UNCHANGED;
4424 }
4425
4426 /// See AbstractAttribute::trackStatistics()
4427 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(IsDead) }
4428};
4429
4430struct AAIsDeadCallSiteReturned : public AAIsDeadFloating {
4431 AAIsDeadCallSiteReturned(const IRPosition &IRP, Attributor &A)
4432 : AAIsDeadFloating(IRP, A) {}
4433
4434 /// See AAIsDead::isAssumedDead().
4435 bool isAssumedDead() const override {
4436 return AAIsDeadFloating::isAssumedDead() && IsAssumedSideEffectFree;
4437 }
4438
4439 /// See AbstractAttribute::initialize(...).
4440 void initialize(Attributor &A) override {
4441 AAIsDeadFloating::initialize(A);
4442 if (isa<UndefValue>(getAssociatedValue())) {
4443 indicatePessimisticFixpoint();
4444 return;
4445 }
4446
4447 // We track this separately as a secondary state.
4448 IsAssumedSideEffectFree = isAssumedSideEffectFree(A, getCtxI());
4449 }
4450
4451 /// See AbstractAttribute::updateImpl(...).
4452 ChangeStatus updateImpl(Attributor &A) override {
4453 ChangeStatus Changed = ChangeStatus::UNCHANGED;
4454 if (IsAssumedSideEffectFree && !isAssumedSideEffectFree(A, getCtxI())) {
4455 IsAssumedSideEffectFree = false;
4456 Changed = ChangeStatus::CHANGED;
4457 }
4458 if (!areAllUsesAssumedDead(A, getAssociatedValue()))
4459 return indicatePessimisticFixpoint();
4460 return Changed;
4461 }
4462
4463 /// See AbstractAttribute::trackStatistics()
4464 void trackStatistics() const override {
4465 if (IsAssumedSideEffectFree)
4467 else
4468 STATS_DECLTRACK_CSRET_ATTR(UnusedResult)
4469 }
4470
4471 /// See AbstractAttribute::getAsStr().
4472 const std::string getAsStr(Attributor *A) const override {
4473 return isAssumedDead()
4474 ? "assumed-dead"
4475 : (getAssumed() ? "assumed-dead-users" : "assumed-live");
4476 }
4477
4478private:
4479 bool IsAssumedSideEffectFree = true;
4480};
4481
4482struct AAIsDeadReturned : public AAIsDeadValueImpl {
4483 AAIsDeadReturned(const IRPosition &IRP, Attributor &A)
4484 : AAIsDeadValueImpl(IRP, A) {}
4485
4486 /// See AbstractAttribute::updateImpl(...).
4487 ChangeStatus updateImpl(Attributor &A) override {
4488
4489 bool UsedAssumedInformation = false;
4490 A.checkForAllInstructions([](Instruction &) { return true; }, *this,
4491 {Instruction::Ret}, UsedAssumedInformation);
4492
4493 auto PredForCallSite = [&](AbstractCallSite ACS) {
4494 if (ACS.isCallbackCall() || !ACS.getInstruction())
4495 return false;
4496 return areAllUsesAssumedDead(A, *ACS.getInstruction());
4497 };
4498
4499 if (!A.checkForAllCallSites(PredForCallSite, *this, true,
4500 UsedAssumedInformation))
4501 return indicatePessimisticFixpoint();
4502
4503 return ChangeStatus::UNCHANGED;
4504 }
4505
4506 /// See AbstractAttribute::manifest(...).
4507 ChangeStatus manifest(Attributor &A) override {
4508 // TODO: Rewrite the signature to return void?
4509 bool AnyChange = false;
4510 UndefValue &UV = *UndefValue::get(getAssociatedFunction()->getReturnType());
4511 auto RetInstPred = [&](Instruction &I) {
4512 ReturnInst &RI = cast<ReturnInst>(I);
4514 AnyChange |= A.changeUseAfterManifest(RI.getOperandUse(0), UV);
4515 return true;
4516 };
4517 bool UsedAssumedInformation = false;
4518 A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret},
4519 UsedAssumedInformation);
4520 return AnyChange ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
4521 }
4522
4523 /// See AbstractAttribute::trackStatistics()
4524 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(IsDead) }
4525};
4526
4527struct AAIsDeadFunction : public AAIsDead {
4528 AAIsDeadFunction(const IRPosition &IRP, Attributor &A) : AAIsDead(IRP, A) {}
4529
4530 /// See AbstractAttribute::initialize(...).
4531 void initialize(Attributor &A) override {
4532 Function *F = getAnchorScope();
4533 assert(F && "Did expect an anchor function");
4534 if (!isAssumedDeadInternalFunction(A)) {
4535 ToBeExploredFrom.insert(&F->getEntryBlock().front());
4536 assumeLive(A, F->getEntryBlock());
4537 }
4538 }
4539
4540 bool isAssumedDeadInternalFunction(Attributor &A) {
4541 if (!getAnchorScope()->hasLocalLinkage())
4542 return false;
4543 // An AA that will not be updated is fixed pessimistically right after
4544 // initialization, so an assumed-dead result would be discarded. Checking
4545 // the call sites recursively initializes the liveness of every internal
4546 // caller, which in CGSCC cleanup repeats for each callee SCC.
4547 if (!A.shouldUpdateAA<AAIsDead>(getIRPosition()))
4548 return false;
4549 bool UsedAssumedInformation = false;
4550 return A.checkForAllCallSites([](AbstractCallSite) { return false; }, *this,
4551 true, UsedAssumedInformation);
4552 }
4553
4554 /// See AbstractAttribute::getAsStr().
4555 const std::string getAsStr(Attributor *A) const override {
4556 return "Live[#BB " + std::to_string(AssumedLiveBlocks.size()) + "/" +
4557 std::to_string(getAnchorScope()->size()) + "][#TBEP " +
4558 std::to_string(ToBeExploredFrom.size()) + "][#KDE " +
4559 std::to_string(KnownDeadEnds.size()) + "]";
4560 }
4561
4562 /// See AbstractAttribute::manifest(...).
4563 ChangeStatus manifest(Attributor &A) override {
4564 assert(getState().isValidState() &&
4565 "Attempted to manifest an invalid state!");
4566
4567 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
4568 Function &F = *getAnchorScope();
4569
4570 if (AssumedLiveBlocks.empty()) {
4571 A.deleteAfterManifest(F);
4572 return ChangeStatus::CHANGED;
4573 }
4574
4575 // Flag to determine if we can change an invoke to a call assuming the
4576 // callee is nounwind. This is not possible if the personality of the
4577 // function allows to catch asynchronous exceptions.
4578 bool Invoke2CallAllowed = !mayCatchAsynchronousExceptions(F);
4579
4580 KnownDeadEnds.set_union(ToBeExploredFrom);
4581 for (const Instruction *DeadEndI : KnownDeadEnds) {
4582 auto *CB = dyn_cast<CallBase>(DeadEndI);
4583 if (!CB)
4584 continue;
4585 bool IsKnownNoReturn;
4587 A, this, IRPosition::callsite_function(*CB), DepClassTy::OPTIONAL,
4588 IsKnownNoReturn);
4589 if (MayReturn && (!Invoke2CallAllowed || !isa<InvokeInst>(CB)))
4590 continue;
4591
4592 if (auto *II = dyn_cast<InvokeInst>(DeadEndI))
4593 A.registerInvokeWithDeadSuccessor(const_cast<InvokeInst &>(*II));
4594 else
4595 A.changeToUnreachableAfterManifest(
4596 const_cast<Instruction *>(DeadEndI->getNextNode()));
4597 HasChanged = ChangeStatus::CHANGED;
4598 }
4599
4600 STATS_DECL(AAIsDead, BasicBlock, "Number of dead basic blocks deleted.");
4601 for (BasicBlock &BB : F)
4602 if (!AssumedLiveBlocks.count(&BB)) {
4603 A.deleteAfterManifest(BB);
4604 ++BUILD_STAT_NAME(AAIsDead, BasicBlock);
4605 HasChanged = ChangeStatus::CHANGED;
4606 }
4607
4608 return HasChanged;
4609 }
4610
4611 /// See AbstractAttribute::updateImpl(...).
4612 ChangeStatus updateImpl(Attributor &A) override;
4613
4614 bool isEdgeDead(const BasicBlock *From, const BasicBlock *To) const override {
4615 assert(From->getParent() == getAnchorScope() &&
4616 To->getParent() == getAnchorScope() &&
4617 "Used AAIsDead of the wrong function");
4618 return isValidState() && !AssumedLiveEdges.count(std::make_pair(From, To));
4619 }
4620
4621 /// See AbstractAttribute::trackStatistics()
4622 void trackStatistics() const override {}
4623
4624 /// Returns true if the function is assumed dead.
4625 bool isAssumedDead() const override { return false; }
4626
4627 /// See AAIsDead::isKnownDead().
4628 bool isKnownDead() const override { return false; }
4629
4630 /// See AAIsDead::isAssumedDead(BasicBlock *).
4631 bool isAssumedDead(const BasicBlock *BB) const override {
4632 assert(BB->getParent() == getAnchorScope() &&
4633 "BB must be in the same anchor scope function.");
4634
4635 if (!getAssumed())
4636 return false;
4637 return !AssumedLiveBlocks.count(BB);
4638 }
4639
4640 /// See AAIsDead::isKnownDead(BasicBlock *).
4641 bool isKnownDead(const BasicBlock *BB) const override {
4642 return getKnown() && isAssumedDead(BB);
4643 }
4644
4645 /// See AAIsDead::isAssumed(Instruction *I).
4646 bool isAssumedDead(const Instruction *I) const override {
4647 assert(I->getParent()->getParent() == getAnchorScope() &&
4648 "Instruction must be in the same anchor scope function.");
4649
4650 if (!getAssumed())
4651 return false;
4652
4653 // If it is not in AssumedLiveBlocks then it for sure dead.
4654 // Otherwise, it can still be after noreturn call in a live block.
4655 if (!AssumedLiveBlocks.count(I->getParent()))
4656 return true;
4657
4658 // If it is not after a liveness barrier it is live.
4659 const Instruction *PrevI = I->getPrevNode();
4660 while (PrevI) {
4661 if (KnownDeadEnds.count(PrevI) || ToBeExploredFrom.count(PrevI))
4662 return true;
4663 PrevI = PrevI->getPrevNode();
4664 }
4665 return false;
4666 }
4667
4668 /// See AAIsDead::isKnownDead(Instruction *I).
4669 bool isKnownDead(const Instruction *I) const override {
4670 return getKnown() && isAssumedDead(I);
4671 }
4672
4673 /// Assume \p BB is (partially) live now and indicate to the Attributor \p A
4674 /// that internal function called from \p BB should now be looked at.
4675 bool assumeLive(Attributor &A, const BasicBlock &BB) {
4676 if (!AssumedLiveBlocks.insert(&BB).second)
4677 return false;
4678
4679 if (!A.isDuringDeduction())
4680 return true;
4681
4682 // We assume that all of BB is (probably) live now and if there are calls to
4683 // internal functions we will assume that those are now live as well. This
4684 // is a performance optimization for blocks with calls to a lot of internal
4685 // functions. It can however cause dead functions to be treated as live.
4686 for (const Instruction &I : BB)
4687 if (const auto *CB = dyn_cast<CallBase>(&I))
4689 if (F->hasLocalLinkage()) {
4690 LLVM_DEBUG({
4691 dbgs() << "[AAIsDead] Seeding live internal callee ";
4692 F->printAsOperand(dbgs(), /*PrintType=*/false);
4693 dbgs() << " from ";
4694 BB.getParent()->printAsOperand(dbgs(), /*PrintType=*/false);
4695 dbgs() << "\n";
4696 });
4697 A.markLiveInternalFunction(*F);
4698 }
4699 return true;
4700 }
4701
4702 /// Collection of instructions that need to be explored again, e.g., we
4703 /// did assume they do not transfer control to (one of their) successors.
4704 SmallSetVector<const Instruction *, 8> ToBeExploredFrom;
4705
4706 /// Collection of instructions that are known to not transfer control.
4707 SmallSetVector<const Instruction *, 8> KnownDeadEnds;
4708
4709 /// Collection of all assumed live edges
4710 DenseSet<std::pair<const BasicBlock *, const BasicBlock *>> AssumedLiveEdges;
4711
4712 /// Collection of all assumed live BasicBlocks.
4713 DenseSet<const BasicBlock *> AssumedLiveBlocks;
4714};
4715
4716static bool
4717identifyAliveSuccessors(Attributor &A, const CallBase &CB,
4718 AbstractAttribute &AA,
4719 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4720 const IRPosition &IPos = IRPosition::callsite_function(CB);
4721
4722 bool IsKnownNoReturn;
4724 A, &AA, IPos, DepClassTy::OPTIONAL, IsKnownNoReturn))
4725 return !IsKnownNoReturn;
4726 if (CB.isTerminator())
4727 AliveSuccessors.push_back(&CB.getSuccessor(0)->front());
4728 else
4729 AliveSuccessors.push_back(CB.getNextNode());
4730 return false;
4731}
4732
4733static bool
4734identifyAliveSuccessors(Attributor &A, const InvokeInst &II,
4735 AbstractAttribute &AA,
4736 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4737 bool UsedAssumedInformation =
4738 identifyAliveSuccessors(A, cast<CallBase>(II), AA, AliveSuccessors);
4739
4740 // First, determine if we can change an invoke to a call assuming the
4741 // callee is nounwind. This is not possible if the personality of the
4742 // function allows to catch asynchronous exceptions.
4743 if (AAIsDeadFunction::mayCatchAsynchronousExceptions(*II.getFunction())) {
4744 AliveSuccessors.push_back(&II.getUnwindDest()->front());
4745 } else {
4746 const IRPosition &IPos = IRPosition::callsite_function(II);
4747
4748 bool IsKnownNoUnwind;
4750 A, &AA, IPos, DepClassTy::OPTIONAL, IsKnownNoUnwind)) {
4751 UsedAssumedInformation |= !IsKnownNoUnwind;
4752 } else {
4753 AliveSuccessors.push_back(&II.getUnwindDest()->front());
4754 }
4755 }
4756 return UsedAssumedInformation;
4757}
4758
4759static bool
4760identifyAliveSuccessors(Attributor &, const UncondBrInst &BI,
4761 AbstractAttribute &,
4762 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4763 AliveSuccessors.push_back(&BI.getSuccessor()->front());
4764 return false;
4765}
4766
4767static bool
4768identifyAliveSuccessors(Attributor &A, const CondBrInst &BI,
4769 AbstractAttribute &AA,
4770 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4771 bool UsedAssumedInformation = false;
4772 std::optional<Constant *> C =
4773 A.getAssumedConstant(*BI.getCondition(), AA, UsedAssumedInformation);
4774 if (!C || isa_and_nonnull<UndefValue>(*C)) {
4775 // No value yet, assume both edges are dead.
4776 } else if (isa_and_nonnull<ConstantInt>(*C)) {
4777 const BasicBlock *SuccBB =
4778 BI.getSuccessor(1 - cast<ConstantInt>(*C)->getValue().getZExtValue());
4779 AliveSuccessors.push_back(&SuccBB->front());
4780 } else {
4781 AliveSuccessors.push_back(&BI.getSuccessor(0)->front());
4782 AliveSuccessors.push_back(&BI.getSuccessor(1)->front());
4783 UsedAssumedInformation = false;
4784 }
4785 return UsedAssumedInformation;
4786}
4787
4788static bool
4789identifyAliveSuccessors(Attributor &A, const SwitchInst &SI,
4790 AbstractAttribute &AA,
4791 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4792 bool UsedAssumedInformation = false;
4794 if (!A.getAssumedSimplifiedValues(IRPosition::value(*SI.getCondition()), &AA,
4796 UsedAssumedInformation)) {
4797 // Something went wrong, assume all successors are live.
4798 for (const BasicBlock *SuccBB : successors(SI.getParent()))
4799 AliveSuccessors.push_back(&SuccBB->front());
4800 return false;
4801 }
4802
4803 if (Values.empty() ||
4804 (Values.size() == 1 &&
4805 isa_and_nonnull<UndefValue>(Values.front().getValue()))) {
4806 // No valid value yet, assume all edges are dead.
4807 return UsedAssumedInformation;
4808 }
4809
4810 Type &Ty = *SI.getCondition()->getType();
4811 SmallPtrSet<ConstantInt *, 8> Constants;
4812 auto CheckForConstantInt = [&](Value *V) {
4813 if (auto *CI = dyn_cast_if_present<ConstantInt>(AA::getWithType(*V, Ty))) {
4814 Constants.insert(CI);
4815 return true;
4816 }
4817 return false;
4818 };
4819
4820 if (!all_of(Values, [&](AA::ValueAndContext &VAC) {
4821 return CheckForConstantInt(VAC.getValue());
4822 })) {
4823 for (const BasicBlock *SuccBB : successors(SI.getParent()))
4824 AliveSuccessors.push_back(&SuccBB->front());
4825 return UsedAssumedInformation;
4826 }
4827
4828 unsigned MatchedCases = 0;
4829 for (const auto &CaseIt : SI.cases()) {
4830 if (Constants.count(CaseIt.getCaseValue())) {
4831 ++MatchedCases;
4832 AliveSuccessors.push_back(&CaseIt.getCaseSuccessor()->front());
4833 }
4834 }
4835
4836 // If all potential values have been matched, we will not visit the default
4837 // case.
4838 if (MatchedCases < Constants.size())
4839 AliveSuccessors.push_back(&SI.getDefaultDest()->front());
4840 return UsedAssumedInformation;
4841}
4842
4843ChangeStatus AAIsDeadFunction::updateImpl(Attributor &A) {
4845
4846 if (AssumedLiveBlocks.empty()) {
4847 if (isAssumedDeadInternalFunction(A))
4849
4850 Function *F = getAnchorScope();
4851 ToBeExploredFrom.insert(&F->getEntryBlock().front());
4852 assumeLive(A, F->getEntryBlock());
4853 Change = ChangeStatus::CHANGED;
4854 }
4855
4856 LLVM_DEBUG(dbgs() << "[AAIsDead] Live [" << AssumedLiveBlocks.size() << "/"
4857 << getAnchorScope()->size() << "] BBs and "
4858 << ToBeExploredFrom.size() << " exploration points and "
4859 << KnownDeadEnds.size() << " known dead ends\n");
4860
4861 // Copy and clear the list of instructions we need to explore from. It is
4862 // refilled with instructions the next update has to look at.
4863 SmallVector<const Instruction *, 8> Worklist(ToBeExploredFrom.begin(),
4864 ToBeExploredFrom.end());
4865 decltype(ToBeExploredFrom) NewToBeExploredFrom;
4866
4868 while (!Worklist.empty()) {
4869 const Instruction *I = Worklist.pop_back_val();
4870 LLVM_DEBUG(dbgs() << "[AAIsDead] Exploration inst: " << *I << "\n");
4871
4872 // Fast forward for uninteresting instructions. We could look for UB here
4873 // though.
4874 while (!I->isTerminator() && !isa<CallBase>(I))
4875 I = I->getNextNode();
4876
4877 AliveSuccessors.clear();
4878
4879 bool UsedAssumedInformation = false;
4880 switch (I->getOpcode()) {
4881 // TODO: look for (assumed) UB to backwards propagate "deadness".
4882 default:
4883 assert(I->isTerminator() &&
4884 "Expected non-terminators to be handled already!");
4885 for (const BasicBlock *SuccBB : successors(I->getParent()))
4886 AliveSuccessors.push_back(&SuccBB->front());
4887 break;
4888 case Instruction::Call:
4889 UsedAssumedInformation = identifyAliveSuccessors(A, cast<CallInst>(*I),
4890 *this, AliveSuccessors);
4891 break;
4892 case Instruction::Invoke:
4893 UsedAssumedInformation = identifyAliveSuccessors(A, cast<InvokeInst>(*I),
4894 *this, AliveSuccessors);
4895 break;
4896 case Instruction::UncondBr:
4897 UsedAssumedInformation = identifyAliveSuccessors(
4898 A, cast<UncondBrInst>(*I), *this, AliveSuccessors);
4899 break;
4900 case Instruction::CondBr:
4901 UsedAssumedInformation = identifyAliveSuccessors(A, cast<CondBrInst>(*I),
4902 *this, AliveSuccessors);
4903 break;
4904 case Instruction::Switch:
4905 UsedAssumedInformation = identifyAliveSuccessors(A, cast<SwitchInst>(*I),
4906 *this, AliveSuccessors);
4907 break;
4908 }
4909
4910 if (UsedAssumedInformation) {
4911 NewToBeExploredFrom.insert(I);
4912 } else if (AliveSuccessors.empty() ||
4913 (I->isTerminator() &&
4914 AliveSuccessors.size() < I->getNumSuccessors())) {
4915 if (KnownDeadEnds.insert(I))
4916 Change = ChangeStatus::CHANGED;
4917 }
4918
4919 LLVM_DEBUG(dbgs() << "[AAIsDead] #AliveSuccessors: "
4920 << AliveSuccessors.size() << " UsedAssumedInformation: "
4921 << UsedAssumedInformation << "\n");
4922
4923 for (const Instruction *AliveSuccessor : AliveSuccessors) {
4924 if (!I->isTerminator()) {
4925 assert(AliveSuccessors.size() == 1 &&
4926 "Non-terminator expected to have a single successor!");
4927 Worklist.push_back(AliveSuccessor);
4928 } else {
4929 // record the assumed live edge
4930 auto Edge = std::make_pair(I->getParent(), AliveSuccessor->getParent());
4931 if (AssumedLiveEdges.insert(Edge).second)
4932 Change = ChangeStatus::CHANGED;
4933 if (assumeLive(A, *AliveSuccessor->getParent()))
4934 Worklist.push_back(AliveSuccessor);
4935 }
4936 }
4937 }
4938
4939 // Check if the content of ToBeExploredFrom changed, ignore the order.
4940 if (NewToBeExploredFrom.size() != ToBeExploredFrom.size() ||
4941 llvm::any_of(NewToBeExploredFrom, [&](const Instruction *I) {
4942 return !ToBeExploredFrom.count(I);
4943 })) {
4944 Change = ChangeStatus::CHANGED;
4945 ToBeExploredFrom = std::move(NewToBeExploredFrom);
4946 }
4947
4948 // If we know everything is live there is no need to query for liveness.
4949 // Instead, indicating a pessimistic fixpoint will cause the state to be
4950 // "invalid" and all queries to be answered conservatively without lookups.
4951 // To be in this state we have to (1) finished the exploration and (3) not
4952 // discovered any non-trivial dead end and (2) not ruled unreachable code
4953 // dead.
4954 if (ToBeExploredFrom.empty() &&
4955 getAnchorScope()->size() == AssumedLiveBlocks.size() &&
4956 llvm::all_of(KnownDeadEnds, [](const Instruction *DeadEndI) {
4957 return DeadEndI->isTerminator() && DeadEndI->getNumSuccessors() == 0;
4958 }))
4959 return indicatePessimisticFixpoint();
4960 return Change;
4961}
4962
4963/// Liveness information for a call sites.
4964struct AAIsDeadCallSite final : AAIsDeadFunction {
4965 AAIsDeadCallSite(const IRPosition &IRP, Attributor &A)
4966 : AAIsDeadFunction(IRP, A) {}
4967
4968 /// See AbstractAttribute::initialize(...).
4969 void initialize(Attributor &A) override {
4970 // TODO: Once we have call site specific value information we can provide
4971 // call site specific liveness information and then it makes
4972 // sense to specialize attributes for call sites instead of
4973 // redirecting requests to the callee.
4974 llvm_unreachable("Abstract attributes for liveness are not "
4975 "supported for call sites yet!");
4976 }
4977
4978 /// See AbstractAttribute::updateImpl(...).
4979 ChangeStatus updateImpl(Attributor &A) override {
4980 return indicatePessimisticFixpoint();
4981 }
4982
4983 /// See AbstractAttribute::trackStatistics()
4984 void trackStatistics() const override {}
4985};
4986} // namespace
4987
4988/// -------------------- Dereferenceable Argument Attribute --------------------
4989
4990namespace {
4991struct AADereferenceableImpl : AADereferenceable {
4992 AADereferenceableImpl(const IRPosition &IRP, Attributor &A)
4993 : AADereferenceable(IRP, A) {}
4994 using StateType = DerefState;
4995
4996 /// See AbstractAttribute::initialize(...).
4997 void initialize(Attributor &A) override {
4998 Value &V = *getAssociatedValue().stripPointerCasts();
5000 A.getAttrs(getIRPosition(),
5001 {Attribute::Dereferenceable, Attribute::DereferenceableOrNull},
5002 Attrs, /* IgnoreSubsumingPositions */ false);
5003 for (const Attribute &Attr : Attrs)
5004 takeKnownDerefBytesMaximum(Attr.getValueAsInt());
5005
5006 // Ensure we initialize the non-null AA (if necessary).
5007 bool IsKnownNonNull;
5009 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNonNull);
5010
5011 bool CanBeNull;
5012 takeKnownDerefBytesMaximum(V.getPointerDereferenceableBytes(
5013 A.getDataLayout(), CanBeNull, /*CanBeFreed=*/nullptr));
5014
5015 if (Instruction *CtxI = getCtxI())
5016 followUsesInMBEC(*this, A, getState(), *CtxI);
5017 }
5018
5019 /// See AbstractAttribute::getState()
5020 /// {
5021 StateType &getState() override { return *this; }
5022 const StateType &getState() const override { return *this; }
5023 /// }
5024
5025 /// Helper function for collecting accessed bytes in must-be-executed-context
5026 void addAccessedBytesForUse(Attributor &A, const Use *U, const Instruction *I,
5027 DerefState &State) {
5028 const Value *UseV = U->get();
5029 if (!UseV->getType()->isPointerTy())
5030 return;
5031
5032 std::optional<MemoryLocation> Loc = MemoryLocation::getOrNone(I);
5033 if (!Loc || Loc->Ptr != UseV || !Loc->Size.isPrecise() || I->isVolatile())
5034 return;
5035
5036 int64_t Offset;
5038 Loc->Ptr, Offset, A.getDataLayout(), /*AllowNonInbounds*/ true);
5039 if (Base && Base == &getAssociatedValue())
5040 State.addAccessedBytes(Offset, Loc->Size.getValue());
5041 }
5042
5043 /// See followUsesInMBEC
5044 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
5045 AADereferenceable::StateType &State) {
5046 bool IsNonNull = false;
5047 bool TrackUse = false;
5048 int64_t DerefBytes = getKnownNonNullAndDerefBytesForUse(
5049 A, *this, getAssociatedValue(), U, I, IsNonNull, TrackUse);
5050 LLVM_DEBUG(dbgs() << "[AADereferenceable] Deref bytes: " << DerefBytes
5051 << " for instruction " << *I << "\n");
5052
5053 addAccessedBytesForUse(A, U, I, State);
5054 State.takeKnownDerefBytesMaximum(DerefBytes);
5055 return TrackUse;
5056 }
5057
5058 /// See AbstractAttribute::manifest(...).
5059 ChangeStatus manifest(Attributor &A) override {
5060 ChangeStatus Change = AADereferenceable::manifest(A);
5061 bool IsKnownNonNull;
5062 bool IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>(
5063 A, this, getIRPosition(), DepClassTy::NONE, IsKnownNonNull);
5064 if (IsAssumedNonNull &&
5065 A.hasAttr(getIRPosition(), Attribute::DereferenceableOrNull)) {
5066 A.removeAttrs(getIRPosition(), {Attribute::DereferenceableOrNull});
5067 return ChangeStatus::CHANGED;
5068 }
5069 return Change;
5070 }
5071
5072 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
5073 SmallVectorImpl<Attribute> &Attrs) const override {
5074 // TODO: Add *_globally support
5075 bool IsKnownNonNull;
5076 bool IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>(
5077 A, this, getIRPosition(), DepClassTy::NONE, IsKnownNonNull);
5078 if (IsAssumedNonNull)
5079 Attrs.emplace_back(Attribute::getWithDereferenceableBytes(
5080 Ctx, getAssumedDereferenceableBytes()));
5081 else
5082 Attrs.emplace_back(Attribute::getWithDereferenceableOrNullBytes(
5083 Ctx, getAssumedDereferenceableBytes()));
5084 }
5085
5086 /// See AbstractAttribute::getAsStr().
5087 const std::string getAsStr(Attributor *A) const override {
5088 if (!getAssumedDereferenceableBytes())
5089 return "unknown-dereferenceable";
5090 bool IsKnownNonNull;
5091 bool IsAssumedNonNull = false;
5092 if (A)
5094 *A, this, getIRPosition(), DepClassTy::NONE, IsKnownNonNull);
5095 return std::string("dereferenceable") +
5096 (IsAssumedNonNull ? "" : "_or_null") +
5097 (isAssumedGlobal() ? "_globally" : "") + "<" +
5098 std::to_string(getKnownDereferenceableBytes()) + "-" +
5099 std::to_string(getAssumedDereferenceableBytes()) + ">" +
5100 (!A ? " [non-null is unknown]" : "");
5101 }
5102};
5103
5104/// Dereferenceable attribute for a floating value.
5105struct AADereferenceableFloating : AADereferenceableImpl {
5106 AADereferenceableFloating(const IRPosition &IRP, Attributor &A)
5107 : AADereferenceableImpl(IRP, A) {}
5108
5109 /// See AbstractAttribute::updateImpl(...).
5110 ChangeStatus updateImpl(Attributor &A) override {
5111 bool Stripped;
5112 bool UsedAssumedInformation = false;
5114 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
5115 AA::AnyScope, UsedAssumedInformation)) {
5116 Values.push_back({getAssociatedValue(), getCtxI()});
5117 Stripped = false;
5118 } else {
5119 Stripped = Values.size() != 1 ||
5120 Values.front().getValue() != &getAssociatedValue();
5121 }
5122
5123 const DataLayout &DL = A.getDataLayout();
5124 DerefState T;
5125
5126 auto VisitValueCB = [&](const Value &V) -> bool {
5127 unsigned IdxWidth =
5128 DL.getIndexSizeInBits(V.getType()->getPointerAddressSpace());
5129 APInt Offset(IdxWidth, 0);
5131 A, *this, &V, DL, Offset, /* GetMinOffset */ false,
5132 /* AllowNonInbounds */ true);
5133
5134 const auto *AA = A.getAAFor<AADereferenceable>(
5135 *this, IRPosition::value(*Base), DepClassTy::REQUIRED);
5136 int64_t DerefBytes = 0;
5137 if (!AA || (!Stripped && this == AA)) {
5138 // Use IR information if we did not strip anything.
5139 // TODO: track globally.
5140 bool CanBeNull;
5141 DerefBytes = Base->getPointerDereferenceableBytes(
5142 DL, CanBeNull, /*CanBeFreed=*/nullptr);
5143 T.GlobalState.indicatePessimisticFixpoint();
5144 } else {
5145 const DerefState &DS = AA->getState();
5146 DerefBytes = DS.DerefBytesState.getAssumed();
5147 T.GlobalState &= DS.GlobalState;
5148 }
5149
5150 // For now we do not try to "increase" dereferenceability due to negative
5151 // indices as we first have to come up with code to deal with loops and
5152 // for overflows of the dereferenceable bytes.
5153 int64_t OffsetSExt = Offset.getSExtValue();
5154 if (OffsetSExt < 0)
5155 OffsetSExt = 0;
5156
5157 T.takeAssumedDerefBytesMinimum(
5158 std::max(int64_t(0), DerefBytes - OffsetSExt));
5159
5160 if (this == AA) {
5161 if (!Stripped) {
5162 // If nothing was stripped IR information is all we got.
5163 T.takeKnownDerefBytesMaximum(
5164 std::max(int64_t(0), DerefBytes - OffsetSExt));
5165 T.indicatePessimisticFixpoint();
5166 } else if (OffsetSExt > 0) {
5167 // If something was stripped but there is circular reasoning we look
5168 // for the offset. If it is positive we basically decrease the
5169 // dereferenceable bytes in a circular loop now, which will simply
5170 // drive them down to the known value in a very slow way which we
5171 // can accelerate.
5172 T.indicatePessimisticFixpoint();
5173 }
5174 }
5175
5176 return T.isValidState();
5177 };
5178
5179 for (const auto &VAC : Values)
5180 if (!VisitValueCB(*VAC.getValue()))
5181 return indicatePessimisticFixpoint();
5182
5183 return clampStateAndIndicateChange(getState(), T);
5184 }
5185
5186 /// See AbstractAttribute::trackStatistics()
5187 void trackStatistics() const override {
5188 STATS_DECLTRACK_FLOATING_ATTR(dereferenceable)
5189 }
5190};
5191
5192/// Dereferenceable attribute for a return value.
5193struct AADereferenceableReturned final
5194 : AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl> {
5195 using Base =
5196 AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl>;
5197 AADereferenceableReturned(const IRPosition &IRP, Attributor &A)
5198 : Base(IRP, A) {}
5199
5200 /// See AbstractAttribute::trackStatistics()
5201 void trackStatistics() const override {
5202 STATS_DECLTRACK_FNRET_ATTR(dereferenceable)
5203 }
5204};
5205
5206/// Dereferenceable attribute for an argument
5207struct AADereferenceableArgument final
5208 : AAArgumentFromCallSiteArguments<AADereferenceable,
5209 AADereferenceableImpl> {
5210 using Base =
5211 AAArgumentFromCallSiteArguments<AADereferenceable, AADereferenceableImpl>;
5212 AADereferenceableArgument(const IRPosition &IRP, Attributor &A)
5213 : Base(IRP, A) {}
5214
5215 /// See AbstractAttribute::trackStatistics()
5216 void trackStatistics() const override {
5217 STATS_DECLTRACK_ARG_ATTR(dereferenceable)
5218 }
5219};
5220
5221/// Dereferenceable attribute for a call site argument.
5222struct AADereferenceableCallSiteArgument final : AADereferenceableFloating {
5223 AADereferenceableCallSiteArgument(const IRPosition &IRP, Attributor &A)
5224 : AADereferenceableFloating(IRP, A) {}
5225
5226 /// See AbstractAttribute::trackStatistics()
5227 void trackStatistics() const override {
5228 STATS_DECLTRACK_CSARG_ATTR(dereferenceable)
5229 }
5230};
5231
5232/// Dereferenceable attribute deduction for a call site return value.
5233struct AADereferenceableCallSiteReturned final
5234 : AACalleeToCallSite<AADereferenceable, AADereferenceableImpl> {
5235 using Base = AACalleeToCallSite<AADereferenceable, AADereferenceableImpl>;
5236 AADereferenceableCallSiteReturned(const IRPosition &IRP, Attributor &A)
5237 : Base(IRP, A) {}
5238
5239 /// See AbstractAttribute::trackStatistics()
5240 void trackStatistics() const override {
5241 STATS_DECLTRACK_CS_ATTR(dereferenceable);
5242 }
5243};
5244} // namespace
5245
5246// ------------------------ Align Argument Attribute ------------------------
5247
5248namespace {
5249
5250static unsigned getKnownAlignForUse(Attributor &A, AAAlign &QueryingAA,
5251 Value &AssociatedValue, const Use *U,
5252 const Instruction *I, bool &TrackUse) {
5253 // We need to follow common pointer manipulation uses to the accesses they
5254 // feed into.
5255 if (isa<CastInst>(I)) {
5256 // Follow all but ptr2int casts.
5257 TrackUse = !isa<PtrToIntInst>(I);
5258 return 0;
5259 }
5260 if (auto *GEP = dyn_cast<GetElementPtrInst>(I)) {
5261 if (GEP->hasAllConstantIndices())
5262 TrackUse = true;
5263 return 0;
5264 }
5265 if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(I))
5266 switch (II->getIntrinsicID()) {
5267 case Intrinsic::ptrmask: {
5268 // Is it appropriate to pull attribute in initialization?
5269 const auto *ConstVals = A.getAAFor<AAPotentialConstantValues>(
5270 QueryingAA, IRPosition::value(*II->getOperand(1)), DepClassTy::NONE);
5271 const auto *AlignAA = A.getAAFor<AAAlign>(
5272 QueryingAA, IRPosition::value(*II), DepClassTy::NONE);
5273 if (ConstVals && ConstVals->isValidState() && ConstVals->isAtFixpoint()) {
5274 unsigned ShiftValue = std::min(ConstVals->getAssumedMinTrailingZeros(),
5276 Align ConstAlign = Align::fromLog2(ShiftValue);
5277 if (ConstAlign >= AlignAA->getKnownAlign())
5278 return Align(1).value();
5279 }
5280 if (AlignAA)
5281 return AlignAA->getKnownAlign().value();
5282 break;
5283 }
5284 case Intrinsic::amdgcn_make_buffer_rsrc: {
5285 const auto *AlignAA = A.getAAFor<AAAlign>(
5286 QueryingAA, IRPosition::value(*II), DepClassTy::NONE);
5287 if (AlignAA)
5288 return AlignAA->getKnownAlign().value();
5289 break;
5290 }
5291 default:
5292 break;
5293 }
5294
5295 MaybeAlign MA;
5296 if (const auto *CB = dyn_cast<CallBase>(I)) {
5297 if (CB->isBundleOperand(U) || CB->isCallee(U))
5298 return 0;
5299
5300 unsigned ArgNo = CB->getArgOperandNo(U);
5301 IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo);
5302 // As long as we only use known information there is no need to track
5303 // dependences here.
5304 auto *AlignAA = A.getAAFor<AAAlign>(QueryingAA, IRP, DepClassTy::NONE);
5305 if (AlignAA)
5306 MA = MaybeAlign(AlignAA->getKnownAlign());
5307 }
5308
5309 const DataLayout &DL = A.getDataLayout();
5310 const Value *UseV = U->get();
5311 if (auto *SI = dyn_cast<StoreInst>(I)) {
5312 if (SI->getPointerOperand() == UseV)
5313 MA = SI->getAlign();
5314 } else if (auto *LI = dyn_cast<LoadInst>(I)) {
5315 if (LI->getPointerOperand() == UseV)
5316 MA = LI->getAlign();
5317 } else if (auto *AI = dyn_cast<AtomicRMWInst>(I)) {
5318 if (AI->getPointerOperand() == UseV)
5319 MA = AI->getAlign();
5320 } else if (auto *AI = dyn_cast<AtomicCmpXchgInst>(I)) {
5321 if (AI->getPointerOperand() == UseV)
5322 MA = AI->getAlign();
5323 }
5324
5325 if (!MA || *MA <= QueryingAA.getKnownAlign())
5326 return 0;
5327
5328 unsigned Alignment = MA->value();
5329 int64_t Offset;
5330
5331 if (const Value *Base = GetPointerBaseWithConstantOffset(UseV, Offset, DL)) {
5332 if (Base == &AssociatedValue) {
5333 // BasePointerAddr + Offset = Alignment * Q for some integer Q.
5334 // So we can say that the maximum power of two which is a divisor of
5335 // gcd(Offset, Alignment) is an alignment.
5336
5337 uint32_t gcd = std::gcd(uint32_t(abs((int32_t)Offset)), Alignment);
5339 }
5340 }
5341
5342 return Alignment;
5343}
5344
5345struct AAAlignImpl : AAAlign {
5346 AAAlignImpl(const IRPosition &IRP, Attributor &A) : AAAlign(IRP, A) {}
5347
5348 /// See AbstractAttribute::initialize(...).
5349 void initialize(Attributor &A) override {
5351 A.getAttrs(getIRPosition(), {Attribute::Alignment}, Attrs);
5352 for (const Attribute &Attr : Attrs)
5353 takeKnownMaximum(Attr.getValueAsInt());
5354
5355 Value &V = *getAssociatedValue().stripPointerCasts();
5356 takeKnownMaximum(V.getPointerAlignment(A.getDataLayout()).value());
5357
5358 if (Instruction *CtxI = getCtxI())
5359 followUsesInMBEC(*this, A, getState(), *CtxI);
5360 }
5361
5362 /// See AbstractAttribute::manifest(...).
5363 ChangeStatus manifest(Attributor &A) override {
5364 ChangeStatus InstrChanged = ChangeStatus::UNCHANGED;
5365
5366 // Check for users that allow alignment annotations.
5367 Value &AssociatedValue = getAssociatedValue();
5368 if (isa<ConstantData>(AssociatedValue))
5369 return ChangeStatus::UNCHANGED;
5370
5371 for (const Use &U : AssociatedValue.uses()) {
5372 if (auto *SI = dyn_cast<StoreInst>(U.getUser())) {
5373 if (SI->getPointerOperand() == &AssociatedValue)
5374 if (SI->getAlign() < getAssumedAlign()) {
5375 STATS_DECLTRACK(AAAlign, Store,
5376 "Number of times alignment added to a store");
5377 SI->setAlignment(getAssumedAlign());
5378 InstrChanged = ChangeStatus::CHANGED;
5379 }
5380 } else if (auto *LI = dyn_cast<LoadInst>(U.getUser())) {
5381 if (LI->getPointerOperand() == &AssociatedValue)
5382 if (LI->getAlign() < getAssumedAlign()) {
5383 LI->setAlignment(getAssumedAlign());
5384 STATS_DECLTRACK(AAAlign, Load,
5385 "Number of times alignment added to a load");
5386 InstrChanged = ChangeStatus::CHANGED;
5387 }
5388 } else if (auto *RMW = dyn_cast<AtomicRMWInst>(U.getUser())) {
5389 if (RMW->getPointerOperand() == &AssociatedValue) {
5390 if (RMW->getAlign() < getAssumedAlign()) {
5391 STATS_DECLTRACK(AAAlign, AtomicRMW,
5392 "Number of times alignment added to atomicrmw");
5393
5394 RMW->setAlignment(getAssumedAlign());
5395 InstrChanged = ChangeStatus::CHANGED;
5396 }
5397 }
5398 } else if (auto *CAS = dyn_cast<AtomicCmpXchgInst>(U.getUser())) {
5399 if (CAS->getPointerOperand() == &AssociatedValue) {
5400 if (CAS->getAlign() < getAssumedAlign()) {
5401 STATS_DECLTRACK(AAAlign, AtomicCmpXchg,
5402 "Number of times alignment added to cmpxchg");
5403 CAS->setAlignment(getAssumedAlign());
5404 InstrChanged = ChangeStatus::CHANGED;
5405 }
5406 }
5407 }
5408 }
5409
5410 ChangeStatus Changed = AAAlign::manifest(A);
5411
5412 Align InheritAlign =
5413 getAssociatedValue().getPointerAlignment(A.getDataLayout());
5414 if (InheritAlign >= getAssumedAlign())
5415 return InstrChanged;
5416 return Changed | InstrChanged;
5417 }
5418
5419 // TODO: Provide a helper to determine the implied ABI alignment and check in
5420 // the existing manifest method and a new one for AAAlignImpl that value
5421 // to avoid making the alignment explicit if it did not improve.
5422
5423 /// See AbstractAttribute::getDeducedAttributes
5424 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
5425 SmallVectorImpl<Attribute> &Attrs) const override {
5426 if (getAssumedAlign() > 1)
5427 Attrs.emplace_back(
5428 Attribute::getWithAlignment(Ctx, Align(getAssumedAlign())));
5429 }
5430
5431 /// See followUsesInMBEC
5432 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
5433 AAAlign::StateType &State) {
5434 bool TrackUse = false;
5435
5436 unsigned int KnownAlign =
5437 getKnownAlignForUse(A, *this, getAssociatedValue(), U, I, TrackUse);
5438 State.takeKnownMaximum(KnownAlign);
5439
5440 return TrackUse;
5441 }
5442
5443 /// See AbstractAttribute::getAsStr().
5444 const std::string getAsStr(Attributor *A) const override {
5445 return "align<" + std::to_string(getKnownAlign().value()) + "-" +
5446 std::to_string(getAssumedAlign().value()) + ">";
5447 }
5448};
5449
5450/// Align attribute for a floating value.
5451struct AAAlignFloating : AAAlignImpl {
5452 AAAlignFloating(const IRPosition &IRP, Attributor &A) : AAAlignImpl(IRP, A) {}
5453
5454 /// See AbstractAttribute::updateImpl(...).
5455 ChangeStatus updateImpl(Attributor &A) override {
5456 const DataLayout &DL = A.getDataLayout();
5457
5458 bool Stripped;
5459 bool UsedAssumedInformation = false;
5461 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
5462 AA::AnyScope, UsedAssumedInformation)) {
5463 Values.push_back({getAssociatedValue(), getCtxI()});
5464 Stripped = false;
5465 } else {
5466 Stripped = Values.size() != 1 ||
5467 Values.front().getValue() != &getAssociatedValue();
5468 }
5469
5470 StateType T;
5471 auto VisitValueCB = [&](Value &V) -> bool {
5473 return true;
5474 const auto *AA = A.getAAFor<AAAlign>(*this, IRPosition::value(V),
5475 DepClassTy::REQUIRED);
5476 if (!AA || (!Stripped && this == AA)) {
5477 int64_t Offset;
5478 unsigned Alignment = 1;
5479 if (const Value *Base =
5481 // TODO: Use AAAlign for the base too.
5482 Align PA = Base->getPointerAlignment(DL);
5483 // BasePointerAddr + Offset = Alignment * Q for some integer Q.
5484 // So we can say that the maximum power of two which is a divisor of
5485 // gcd(Offset, Alignment) is an alignment.
5486
5487 uint32_t gcd =
5488 std::gcd(uint32_t(abs((int32_t)Offset)), uint32_t(PA.value()));
5490 } else {
5491 Alignment = V.getPointerAlignment(DL).value();
5492 }
5493 // Use only IR information if we did not strip anything.
5494 T.takeKnownMaximum(Alignment);
5495 T.indicatePessimisticFixpoint();
5496 } else {
5497 // Use abstract attribute information.
5498 const AAAlign::StateType &DS = AA->getState();
5499 T ^= DS;
5500 }
5501 return T.isValidState();
5502 };
5503
5504 for (const auto &VAC : Values) {
5505 if (!VisitValueCB(*VAC.getValue()))
5506 return indicatePessimisticFixpoint();
5507 }
5508
5509 // TODO: If we know we visited all incoming values, thus no are assumed
5510 // dead, we can take the known information from the state T.
5511 return clampStateAndIndicateChange(getState(), T);
5512 }
5513
5514 /// See AbstractAttribute::trackStatistics()
5515 void trackStatistics() const override { STATS_DECLTRACK_FLOATING_ATTR(align) }
5516};
5517
5518/// Align attribute for function return value.
5519struct AAAlignReturned final
5520 : AAReturnedFromReturnedValues<AAAlign, AAAlignImpl> {
5521 using Base = AAReturnedFromReturnedValues<AAAlign, AAAlignImpl>;
5522 AAAlignReturned(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {}
5523
5524 /// See AbstractAttribute::trackStatistics()
5525 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(aligned) }
5526};
5527
5528/// Align attribute for function argument.
5529struct AAAlignArgument final
5530 : AAArgumentFromCallSiteArguments<AAAlign, AAAlignImpl> {
5531 using Base = AAArgumentFromCallSiteArguments<AAAlign, AAAlignImpl>;
5532 AAAlignArgument(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {}
5533
5534 /// See AbstractAttribute::manifest(...).
5535 ChangeStatus manifest(Attributor &A) override {
5536 // If the associated argument is involved in a must-tail call we give up
5537 // because we would need to keep the argument alignments of caller and
5538 // callee in-sync. Just does not seem worth the trouble right now.
5539 if (A.getInfoCache().isInvolvedInMustTailCall(*getAssociatedArgument()))
5540 return ChangeStatus::UNCHANGED;
5541 return Base::manifest(A);
5542 }
5543
5544 /// See AbstractAttribute::trackStatistics()
5545 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(aligned) }
5546};
5547
5548struct AAAlignCallSiteArgument final : AAAlignFloating {
5549 AAAlignCallSiteArgument(const IRPosition &IRP, Attributor &A)
5550 : AAAlignFloating(IRP, A) {}
5551
5552 /// See AbstractAttribute::manifest(...).
5553 ChangeStatus manifest(Attributor &A) override {
5554 // If the associated argument is involved in a must-tail call we give up
5555 // because we would need to keep the argument alignments of caller and
5556 // callee in-sync. Just does not seem worth the trouble right now.
5557 if (Argument *Arg = getAssociatedArgument())
5558 if (A.getInfoCache().isInvolvedInMustTailCall(*Arg))
5559 return ChangeStatus::UNCHANGED;
5560 ChangeStatus Changed = AAAlignImpl::manifest(A);
5561 Align InheritAlign =
5562 getAssociatedValue().getPointerAlignment(A.getDataLayout());
5563 if (InheritAlign >= getAssumedAlign())
5564 Changed = ChangeStatus::UNCHANGED;
5565 return Changed;
5566 }
5567
5568 /// See AbstractAttribute::updateImpl(Attributor &A).
5569 ChangeStatus updateImpl(Attributor &A) override {
5570 ChangeStatus Changed = AAAlignFloating::updateImpl(A);
5571 if (Argument *Arg = getAssociatedArgument()) {
5572 // We only take known information from the argument
5573 // so we do not need to track a dependence.
5574 const auto *ArgAlignAA = A.getAAFor<AAAlign>(
5575 *this, IRPosition::argument(*Arg), DepClassTy::NONE);
5576 if (ArgAlignAA)
5577 takeKnownMaximum(ArgAlignAA->getKnownAlign().value());
5578 }
5579 return Changed;
5580 }
5581
5582 /// See AbstractAttribute::trackStatistics()
5583 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(aligned) }
5584};
5585
5586/// Align attribute deduction for a call site return value.
5587struct AAAlignCallSiteReturned final
5588 : AACalleeToCallSite<AAAlign, AAAlignImpl> {
5589 using Base = AACalleeToCallSite<AAAlign, AAAlignImpl>;
5590 AAAlignCallSiteReturned(const IRPosition &IRP, Attributor &A)
5591 : Base(IRP, A) {}
5592
5593 ChangeStatus updateImpl(Attributor &A) override {
5594 Instruction *I = getIRPosition().getCtxI();
5595 if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) {
5596 switch (II->getIntrinsicID()) {
5597 case Intrinsic::ptrmask: {
5599 bool Valid = false;
5600
5601 const auto *ConstVals = A.getAAFor<AAPotentialConstantValues>(
5602 *this, IRPosition::value(*II->getOperand(1)), DepClassTy::REQUIRED);
5603 if (ConstVals && ConstVals->isValidState()) {
5604 unsigned ShiftValue =
5605 std::min(ConstVals->getAssumedMinTrailingZeros(),
5606 Value::MaxAlignmentExponent);
5607 Alignment = Align::fromLog2(ShiftValue);
5608 Valid = true;
5609 }
5610
5611 const auto *AlignAA =
5612 A.getAAFor<AAAlign>(*this, IRPosition::value(*(II->getOperand(0))),
5613 DepClassTy::REQUIRED);
5614 if (AlignAA) {
5615 Alignment = std::max(AlignAA->getAssumedAlign(), Alignment);
5616 Valid = true;
5617 }
5618
5619 if (Valid)
5621 this->getState(),
5622 std::min(this->getAssumedAlign(), Alignment).value());
5623 break;
5624 }
5625 // FIXME: Should introduce target specific sub-attributes and letting
5626 // getAAfor<AAAlign> lead to create sub-attribute to handle target
5627 // specific intrinsics.
5628 case Intrinsic::amdgcn_make_buffer_rsrc: {
5629 const auto *AlignAA =
5630 A.getAAFor<AAAlign>(*this, IRPosition::value(*(II->getOperand(0))),
5631 DepClassTy::REQUIRED);
5632 if (AlignAA)
5634 this->getState(), AlignAA->getAssumedAlign().value());
5635 break;
5636 }
5637 default:
5638 break;
5639 }
5640 }
5641 return Base::updateImpl(A);
5642 };
5643 /// See AbstractAttribute::trackStatistics()
5644 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(align); }
5645};
5646} // namespace
5647
5648/// ------------------ Function No-Return Attribute ----------------------------
5649namespace {
5650struct AANoReturnImpl : public AANoReturn {
5651 AANoReturnImpl(const IRPosition &IRP, Attributor &A) : AANoReturn(IRP, A) {}
5652
5653 /// See AbstractAttribute::initialize(...).
5654 void initialize(Attributor &A) override {
5655 bool IsKnown;
5657 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
5658 (void)IsKnown;
5659 }
5660
5661 /// See AbstractAttribute::getAsStr().
5662 const std::string getAsStr(Attributor *A) const override {
5663 return getAssumed() ? "noreturn" : "may-return";
5664 }
5665
5666 /// See AbstractAttribute::updateImpl(Attributor &A).
5667 ChangeStatus updateImpl(Attributor &A) override {
5668 auto CheckForNoReturn = [](Instruction &) { return false; };
5669 bool UsedAssumedInformation = false;
5670 if (!A.checkForAllInstructions(CheckForNoReturn, *this,
5671 {(unsigned)Instruction::Ret},
5672 UsedAssumedInformation))
5673 return indicatePessimisticFixpoint();
5674 return ChangeStatus::UNCHANGED;
5675 }
5676};
5677
5678struct AANoReturnFunction final : AANoReturnImpl {
5679 AANoReturnFunction(const IRPosition &IRP, Attributor &A)
5680 : AANoReturnImpl(IRP, A) {}
5681
5682 /// See AbstractAttribute::trackStatistics()
5683 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(noreturn) }
5684};
5685
5686/// NoReturn attribute deduction for a call sites.
5687struct AANoReturnCallSite final
5688 : AACalleeToCallSite<AANoReturn, AANoReturnImpl> {
5689 AANoReturnCallSite(const IRPosition &IRP, Attributor &A)
5690 : AACalleeToCallSite<AANoReturn, AANoReturnImpl>(IRP, A) {}
5691
5692 /// See AbstractAttribute::trackStatistics()
5693 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(noreturn); }
5694};
5695} // namespace
5696
5697/// ----------------------- Instance Info ---------------------------------
5698
5699namespace {
5700/// A class to hold the state of for no-capture attributes.
5701struct AAInstanceInfoImpl : public AAInstanceInfo {
5702 AAInstanceInfoImpl(const IRPosition &IRP, Attributor &A)
5703 : AAInstanceInfo(IRP, A) {}
5704
5705 /// See AbstractAttribute::initialize(...).
5706 void initialize(Attributor &A) override {
5707 Value &V = getAssociatedValue();
5708 if (auto *C = dyn_cast<Constant>(&V)) {
5709 if (C->isThreadDependent())
5710 indicatePessimisticFixpoint();
5711 else
5712 indicateOptimisticFixpoint();
5713 return;
5714 }
5715 if (auto *CB = dyn_cast<CallBase>(&V))
5716 if (CB->arg_size() == 0 && !CB->mayHaveSideEffects() &&
5717 !CB->mayReadFromMemory()) {
5718 indicateOptimisticFixpoint();
5719 return;
5720 }
5721 if (auto *I = dyn_cast<Instruction>(&V)) {
5722 const auto *CI =
5723 A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>(
5724 *I->getFunction());
5725 if (mayBeInCycle(CI, I, /* HeaderOnly */ false)) {
5726 indicatePessimisticFixpoint();
5727 return;
5728 }
5729 }
5730 }
5731
5732 /// See AbstractAttribute::updateImpl(...).
5733 ChangeStatus updateImpl(Attributor &A) override {
5734 ChangeStatus Changed = ChangeStatus::UNCHANGED;
5735
5736 Value &V = getAssociatedValue();
5737 const Function *Scope = nullptr;
5738 if (auto *I = dyn_cast<Instruction>(&V))
5739 Scope = I->getFunction();
5740 if (auto *A = dyn_cast<Argument>(&V)) {
5741 Scope = A->getParent();
5742 if (!Scope->hasLocalLinkage())
5743 return Changed;
5744 }
5745 if (!Scope)
5746 return indicateOptimisticFixpoint();
5747
5748 bool IsKnownNoRecurse;
5750 A, this, IRPosition::function(*Scope), DepClassTy::OPTIONAL,
5751 IsKnownNoRecurse))
5752 return Changed;
5753
5754 auto UsePred = [&](const Use &U, bool &Follow) {
5755 const Instruction *UserI = dyn_cast<Instruction>(U.getUser());
5756 if (!UserI || isa<GetElementPtrInst>(UserI) || isa<CastInst>(UserI) ||
5757 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) {
5758 Follow = true;
5759 return true;
5760 }
5761 if (isa<LoadInst>(UserI) || isa<CmpInst>(UserI) ||
5762 (isa<StoreInst>(UserI) &&
5763 cast<StoreInst>(UserI)->getValueOperand() != U.get()))
5764 return true;
5765 if (auto *CB = dyn_cast<CallBase>(UserI)) {
5766 // This check is not guaranteeing uniqueness but for now that we cannot
5767 // end up with two versions of \p U thinking it was one.
5769 if (!Callee || !Callee->hasLocalLinkage())
5770 return true;
5771 if (!CB->isArgOperand(&U))
5772 return false;
5773 const auto *ArgInstanceInfoAA = A.getAAFor<AAInstanceInfo>(
5775 DepClassTy::OPTIONAL);
5776 if (!ArgInstanceInfoAA ||
5777 !ArgInstanceInfoAA->isAssumedUniqueForAnalysis())
5778 return false;
5779 // If this call base might reach the scope again we might forward the
5780 // argument back here. This is very conservative.
5782 A, *CB, *Scope, *this, /* ExclusionSet */ nullptr,
5783 [Scope](const Function &Fn) { return &Fn != Scope; }))
5784 return false;
5785 return true;
5786 }
5787 return false;
5788 };
5789
5790 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) {
5791 if (auto *SI = dyn_cast<StoreInst>(OldU.getUser())) {
5792 auto *Ptr = SI->getPointerOperand()->stripPointerCasts();
5793 if ((isa<AllocaInst>(Ptr) || isNoAliasCall(Ptr)) &&
5794 AA::isDynamicallyUnique(A, *this, *Ptr))
5795 return true;
5796 }
5797 return false;
5798 };
5799
5800 if (!A.checkForAllUses(UsePred, *this, V, /* CheckBBLivenessOnly */ true,
5801 DepClassTy::OPTIONAL,
5802 /* IgnoreDroppableUses */ true, EquivalentUseCB))
5803 return indicatePessimisticFixpoint();
5804
5805 return Changed;
5806 }
5807
5808 /// See AbstractState::getAsStr().
5809 const std::string getAsStr(Attributor *A) const override {
5810 return isAssumedUniqueForAnalysis() ? "<unique [fAa]>" : "<unknown>";
5811 }
5812
5813 /// See AbstractAttribute::trackStatistics()
5814 void trackStatistics() const override {}
5815};
5816
5817/// InstanceInfo attribute for floating values.
5818struct AAInstanceInfoFloating : AAInstanceInfoImpl {
5819 AAInstanceInfoFloating(const IRPosition &IRP, Attributor &A)
5820 : AAInstanceInfoImpl(IRP, A) {}
5821};
5822
5823/// NoCapture attribute for function arguments.
5824struct AAInstanceInfoArgument final : AAInstanceInfoFloating {
5825 AAInstanceInfoArgument(const IRPosition &IRP, Attributor &A)
5826 : AAInstanceInfoFloating(IRP, A) {}
5827};
5828
5829/// InstanceInfo attribute for call site arguments.
5830struct AAInstanceInfoCallSiteArgument final : AAInstanceInfoImpl {
5831 AAInstanceInfoCallSiteArgument(const IRPosition &IRP, Attributor &A)
5832 : AAInstanceInfoImpl(IRP, A) {}
5833
5834 /// See AbstractAttribute::updateImpl(...).
5835 ChangeStatus updateImpl(Attributor &A) override {
5836 // TODO: Once we have call site specific value information we can provide
5837 // call site specific liveness information and then it makes
5838 // sense to specialize attributes for call sites arguments instead of
5839 // redirecting requests to the callee argument.
5840 Argument *Arg = getAssociatedArgument();
5841 if (!Arg)
5842 return indicatePessimisticFixpoint();
5843 const IRPosition &ArgPos = IRPosition::argument(*Arg);
5844 auto *ArgAA =
5845 A.getAAFor<AAInstanceInfo>(*this, ArgPos, DepClassTy::REQUIRED);
5846 if (!ArgAA)
5847 return indicatePessimisticFixpoint();
5848 return clampStateAndIndicateChange(getState(), ArgAA->getState());
5849 }
5850};
5851
5852/// InstanceInfo attribute for function return value.
5853struct AAInstanceInfoReturned final : AAInstanceInfoImpl {
5854 AAInstanceInfoReturned(const IRPosition &IRP, Attributor &A)
5855 : AAInstanceInfoImpl(IRP, A) {
5856 llvm_unreachable("InstanceInfo is not applicable to function returns!");
5857 }
5858
5859 /// See AbstractAttribute::initialize(...).
5860 void initialize(Attributor &A) override {
5861 llvm_unreachable("InstanceInfo is not applicable to function returns!");
5862 }
5863
5864 /// See AbstractAttribute::updateImpl(...).
5865 ChangeStatus updateImpl(Attributor &A) override {
5866 llvm_unreachable("InstanceInfo is not applicable to function returns!");
5867 }
5868};
5869
5870/// InstanceInfo attribute deduction for a call site return value.
5871struct AAInstanceInfoCallSiteReturned final : AAInstanceInfoFloating {
5872 AAInstanceInfoCallSiteReturned(const IRPosition &IRP, Attributor &A)
5873 : AAInstanceInfoFloating(IRP, A) {}
5874};
5875} // namespace
5876
5877/// ----------------------- Variable Capturing ---------------------------------
5879 Attribute::AttrKind ImpliedAttributeKind,
5880 bool IgnoreSubsumingPositions) {
5881 assert(ImpliedAttributeKind == Attribute::Captures &&
5882 "Unexpected attribute kind");
5883 Value &V = IRP.getAssociatedValue();
5884 if (!isa<Constant>(V) && !IRP.isArgumentPosition())
5885 return V.use_empty();
5886
5887 // You cannot "capture" null if it is not a valid pointer.
5888 if (isa<UndefValue>(V) ||
5892 return true;
5893 }
5894
5896 A.getAttrs(IRP, {Attribute::Captures}, Attrs,
5897 /* IgnoreSubsumingPositions */ true);
5898 for (const Attribute &Attr : Attrs)
5899 if (capturesNothing(Attr.getCaptureInfo()))
5900 return true;
5901
5903 if (Argument *Arg = IRP.getAssociatedArgument()) {
5905 A.getAttrs(IRPosition::argument(*Arg),
5906 {Attribute::Captures, Attribute::ByVal}, Attrs,
5907 /* IgnoreSubsumingPositions */ true);
5908 bool ArgNoCapture = any_of(Attrs, [](Attribute Attr) {
5909 return Attr.getKindAsEnum() == Attribute::ByVal ||
5911 });
5912 if (ArgNoCapture) {
5913 A.manifestAttrs(IRP, Attribute::getWithCaptureInfo(
5914 V.getContext(), CaptureInfo::none()));
5915 return true;
5916 }
5917 }
5918
5919 if (const Function *F = IRP.getAssociatedFunction()) {
5920 // Check what state the associated function can actually capture.
5923 if (State.isKnown(NO_CAPTURE)) {
5924 A.manifestAttrs(IRP, Attribute::getWithCaptureInfo(V.getContext(),
5926 return true;
5927 }
5928 }
5929
5930 return false;
5931}
5932
5933/// Set the NOT_CAPTURED_IN_MEM and NOT_CAPTURED_IN_RET bits in \p Known
5934/// depending on the ability of the function associated with \p IRP to capture
5935/// state in memory and through "returning/throwing", respectively.
5937 const Function &F,
5938 BitIntegerState &State) {
5939 // TODO: Once we have memory behavior attributes we should use them here.
5940
5941 // If we know we cannot communicate or write to memory, we do not care about
5942 // ptr2int anymore.
5943 bool ReadOnly = F.onlyReadsMemory();
5944 bool NoThrow = F.doesNotThrow();
5945 bool IsVoidReturn = F.getReturnType()->isVoidTy();
5946 if (ReadOnly && NoThrow && IsVoidReturn) {
5947 State.addKnownBits(NO_CAPTURE);
5948 return;
5949 }
5950
5951 // A function cannot capture state in memory if it only reads memory, it can
5952 // however return/throw state and the state might be influenced by the
5953 // pointer value, e.g., loading from a returned pointer might reveal a bit.
5954 if (ReadOnly)
5955 State.addKnownBits(NOT_CAPTURED_IN_MEM);
5956
5957 // A function cannot communicate state back if it does not through
5958 // exceptions and doesn not return values.
5959 if (NoThrow && IsVoidReturn)
5960 State.addKnownBits(NOT_CAPTURED_IN_RET);
5961
5962 // Check existing "returned" attributes.
5963 int ArgNo = IRP.getCalleeArgNo();
5964 if (!NoThrow || ArgNo < 0 ||
5965 !F.getAttributes().hasAttrSomewhere(Attribute::Returned))
5966 return;
5967
5968 for (unsigned U = 0, E = F.arg_size(); U < E; ++U)
5969 if (F.hasParamAttribute(U, Attribute::Returned)) {
5970 if (U == unsigned(ArgNo))
5971 State.removeAssumedBits(NOT_CAPTURED_IN_RET);
5972 else if (ReadOnly)
5973 State.addKnownBits(NO_CAPTURE);
5974 else
5975 State.addKnownBits(NOT_CAPTURED_IN_RET);
5976 break;
5977 }
5978}
5979
5980namespace {
5981/// A class to hold the state of for no-capture attributes.
5982struct AANoCaptureImpl : public AANoCapture {
5983 AANoCaptureImpl(const IRPosition &IRP, Attributor &A) : AANoCapture(IRP, A) {}
5984
5985 /// See AbstractAttribute::initialize(...).
5986 void initialize(Attributor &A) override {
5987 bool IsKnown;
5989 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
5990 (void)IsKnown;
5991 }
5992
5993 /// See AbstractAttribute::updateImpl(...).
5994 ChangeStatus updateImpl(Attributor &A) override;
5995
5996 /// see AbstractAttribute::isAssumedNoCaptureMaybeReturned(...).
5997 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
5998 SmallVectorImpl<Attribute> &Attrs) const override {
5999 if (!isAssumedNoCaptureMaybeReturned())
6000 return;
6001
6002 if (isArgumentPosition()) {
6003 if (isAssumedNoCapture())
6004 Attrs.emplace_back(Attribute::get(Ctx, Attribute::Captures));
6005 else if (ManifestInternal)
6006 Attrs.emplace_back(Attribute::get(Ctx, "no-capture-maybe-returned"));
6007 }
6008 }
6009
6010 /// See AbstractState::getAsStr().
6011 const std::string getAsStr(Attributor *A) const override {
6012 if (isKnownNoCapture())
6013 return "known not-captured";
6014 if (isAssumedNoCapture())
6015 return "assumed not-captured";
6016 if (isKnownNoCaptureMaybeReturned())
6017 return "known not-captured-maybe-returned";
6018 if (isAssumedNoCaptureMaybeReturned())
6019 return "assumed not-captured-maybe-returned";
6020 return "assumed-captured";
6021 }
6022
6023 /// Check the use \p U and update \p State accordingly. Return true if we
6024 /// should continue to update the state.
6025 bool checkUse(Attributor &A, AANoCapture::StateType &State, const Use &U,
6026 bool &Follow) {
6027 Instruction *UInst = cast<Instruction>(U.getUser());
6028 LLVM_DEBUG(dbgs() << "[AANoCapture] Check use: " << *U.get() << " in "
6029 << *UInst << "\n");
6030
6031 // Deal with ptr2int by following uses.
6032 if (isa<PtrToIntInst>(UInst)) {
6033 LLVM_DEBUG(dbgs() << " - ptr2int assume the worst!\n");
6034 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
6035 /* Return */ true);
6036 }
6037
6038 // For stores we already checked if we can follow them, if they make it
6039 // here we give up.
6040 if (isa<StoreInst>(UInst))
6041 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
6042 /* Return */ true);
6043
6044 // Explicitly catch return instructions.
6045 if (isa<ReturnInst>(UInst)) {
6046 if (UInst->getFunction() == getAnchorScope())
6047 return isCapturedIn(State, /* Memory */ false, /* Integer */ false,
6048 /* Return */ true);
6049 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
6050 /* Return */ true);
6051 }
6052
6053 // For now we only use special logic for call sites. However, the tracker
6054 // itself knows about a lot of other non-capturing cases already.
6055 auto *CB = dyn_cast<CallBase>(UInst);
6056 if (!CB || !CB->isArgOperand(&U))
6057 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
6058 /* Return */ true);
6059
6060 unsigned ArgNo = CB->getArgOperandNo(&U);
6061 const IRPosition &CSArgPos = IRPosition::callsite_argument(*CB, ArgNo);
6062 // If we have a abstract no-capture attribute for the argument we can use
6063 // it to justify a non-capture attribute here. This allows recursion!
6064 bool IsKnownNoCapture;
6065 const AANoCapture *ArgNoCaptureAA = nullptr;
6066 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
6067 A, this, CSArgPos, DepClassTy::REQUIRED, IsKnownNoCapture, false,
6068 &ArgNoCaptureAA);
6069 if (IsAssumedNoCapture)
6070 return isCapturedIn(State, /* Memory */ false, /* Integer */ false,
6071 /* Return */ false);
6072 if (ArgNoCaptureAA && ArgNoCaptureAA->isAssumedNoCaptureMaybeReturned()) {
6073 Follow = true;
6074 return isCapturedIn(State, /* Memory */ false, /* Integer */ false,
6075 /* Return */ false);
6076 }
6077
6078 // Lastly, we could not find a reason no-capture can be assumed so we don't.
6079 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
6080 /* Return */ true);
6081 }
6082
6083 /// Update \p State according to \p CapturedInMem, \p CapturedInInt, and
6084 /// \p CapturedInRet, then return true if we should continue updating the
6085 /// state.
6086 static bool isCapturedIn(AANoCapture::StateType &State, bool CapturedInMem,
6087 bool CapturedInInt, bool CapturedInRet) {
6088 LLVM_DEBUG(dbgs() << " - captures [Mem " << CapturedInMem << "|Int "
6089 << CapturedInInt << "|Ret " << CapturedInRet << "]\n");
6090 if (CapturedInMem)
6091 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_MEM);
6092 if (CapturedInInt)
6093 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_INT);
6094 if (CapturedInRet)
6095 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_RET);
6096 return State.isAssumed(AANoCapture::NO_CAPTURE_MAYBE_RETURNED);
6097 }
6098};
6099
6100ChangeStatus AANoCaptureImpl::updateImpl(Attributor &A) {
6101 const IRPosition &IRP = getIRPosition();
6102 Value *V = isArgumentPosition() ? IRP.getAssociatedArgument()
6103 : &IRP.getAssociatedValue();
6104 if (!V)
6105 return indicatePessimisticFixpoint();
6106
6107 const Function *F =
6108 isArgumentPosition() ? IRP.getAssociatedFunction() : IRP.getAnchorScope();
6109
6110 // TODO: Is the checkForAllUses below useful for constants?
6111 if (!F)
6112 return indicatePessimisticFixpoint();
6113
6115 const IRPosition &FnPos = IRPosition::function(*F);
6116
6117 // Readonly means we cannot capture through memory.
6118 bool IsKnown;
6119 if (AA::isAssumedReadOnly(A, FnPos, *this, IsKnown)) {
6120 T.addKnownBits(NOT_CAPTURED_IN_MEM);
6121 if (IsKnown)
6122 addKnownBits(NOT_CAPTURED_IN_MEM);
6123 }
6124
6125 // Make sure all returned values are different than the underlying value.
6126 // TODO: we could do this in a more sophisticated way inside
6127 // AAReturnedValues, e.g., track all values that escape through returns
6128 // directly somehow.
6129 auto CheckReturnedArgs = [&](bool &UsedAssumedInformation) {
6131 if (!A.getAssumedSimplifiedValues(IRPosition::returned(*F), this, Values,
6133 UsedAssumedInformation))
6134 return false;
6135 bool SeenConstant = false;
6136 for (const AA::ValueAndContext &VAC : Values) {
6137 if (isa<Constant>(VAC.getValue())) {
6138 if (SeenConstant)
6139 return false;
6140 SeenConstant = true;
6141 } else if (!isa<Argument>(VAC.getValue()) ||
6142 VAC.getValue() == getAssociatedArgument())
6143 return false;
6144 }
6145 return true;
6146 };
6147
6148 bool IsKnownNoUnwind;
6150 A, this, FnPos, DepClassTy::OPTIONAL, IsKnownNoUnwind)) {
6151 bool IsVoidTy = F->getReturnType()->isVoidTy();
6152 bool UsedAssumedInformation = false;
6153 if (IsVoidTy || CheckReturnedArgs(UsedAssumedInformation)) {
6154 T.addKnownBits(NOT_CAPTURED_IN_RET);
6155 if (T.isKnown(NOT_CAPTURED_IN_MEM))
6157 if (IsKnownNoUnwind && (IsVoidTy || !UsedAssumedInformation)) {
6158 addKnownBits(NOT_CAPTURED_IN_RET);
6159 if (isKnown(NOT_CAPTURED_IN_MEM))
6160 return indicateOptimisticFixpoint();
6161 }
6162 }
6163 }
6164
6165 auto UseCheck = [&](const Use &U, bool &Follow) -> bool {
6166 // TODO(captures): Make this more precise.
6167 UseCaptureInfo CI = DetermineUseCaptureKind(U, /*Base=*/nullptr);
6168 if (capturesNothing(CI))
6169 return true;
6170 if (CI.isPassthrough()) {
6171 Follow = true;
6172 return true;
6173 }
6174 return checkUse(A, T, U, Follow);
6175 };
6176
6177 if (!A.checkForAllUses(UseCheck, *this, *V))
6178 return indicatePessimisticFixpoint();
6179
6180 AANoCapture::StateType &S = getState();
6181 auto Assumed = S.getAssumed();
6182 S.intersectAssumedBits(T.getAssumed());
6183 if (!isAssumedNoCaptureMaybeReturned())
6184 return indicatePessimisticFixpoint();
6185 return Assumed == S.getAssumed() ? ChangeStatus::UNCHANGED
6187}
6188
6189/// NoCapture attribute for function arguments.
6190struct AANoCaptureArgument final : AANoCaptureImpl {
6191 AANoCaptureArgument(const IRPosition &IRP, Attributor &A)
6192 : AANoCaptureImpl(IRP, A) {}
6193
6194 /// See AbstractAttribute::trackStatistics()
6195 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nocapture) }
6196};
6197
6198/// NoCapture attribute for call site arguments.
6199struct AANoCaptureCallSiteArgument final : AANoCaptureImpl {
6200 AANoCaptureCallSiteArgument(const IRPosition &IRP, Attributor &A)
6201 : AANoCaptureImpl(IRP, A) {}
6202
6203 /// See AbstractAttribute::updateImpl(...).
6204 ChangeStatus updateImpl(Attributor &A) override {
6205 // TODO: Once we have call site specific value information we can provide
6206 // call site specific liveness information and then it makes
6207 // sense to specialize attributes for call sites arguments instead of
6208 // redirecting requests to the callee argument.
6209 Argument *Arg = getAssociatedArgument();
6210 if (!Arg)
6211 return indicatePessimisticFixpoint();
6212 const IRPosition &ArgPos = IRPosition::argument(*Arg);
6213 bool IsKnownNoCapture;
6214 const AANoCapture *ArgAA = nullptr;
6216 A, this, ArgPos, DepClassTy::REQUIRED, IsKnownNoCapture, false,
6217 &ArgAA))
6218 return ChangeStatus::UNCHANGED;
6219 if (!ArgAA || !ArgAA->isAssumedNoCaptureMaybeReturned())
6220 return indicatePessimisticFixpoint();
6221 return clampStateAndIndicateChange(getState(), ArgAA->getState());
6222 }
6223
6224 /// See AbstractAttribute::trackStatistics()
6225 void trackStatistics() const override {
6227 };
6228};
6229
6230/// NoCapture attribute for floating values.
6231struct AANoCaptureFloating final : AANoCaptureImpl {
6232 AANoCaptureFloating(const IRPosition &IRP, Attributor &A)
6233 : AANoCaptureImpl(IRP, A) {}
6234
6235 /// See AbstractAttribute::trackStatistics()
6236 void trackStatistics() const override {
6238 }
6239};
6240
6241/// NoCapture attribute for function return value.
6242struct AANoCaptureReturned final : AANoCaptureImpl {
6243 AANoCaptureReturned(const IRPosition &IRP, Attributor &A)
6244 : AANoCaptureImpl(IRP, A) {
6245 llvm_unreachable("NoCapture is not applicable to function returns!");
6246 }
6247
6248 /// See AbstractAttribute::initialize(...).
6249 void initialize(Attributor &A) override {
6250 llvm_unreachable("NoCapture is not applicable to function returns!");
6251 }
6252
6253 /// See AbstractAttribute::updateImpl(...).
6254 ChangeStatus updateImpl(Attributor &A) override {
6255 llvm_unreachable("NoCapture is not applicable to function returns!");
6256 }
6257
6258 /// See AbstractAttribute::trackStatistics()
6259 void trackStatistics() const override {}
6260};
6261
6262/// NoCapture attribute deduction for a call site return value.
6263struct AANoCaptureCallSiteReturned final : AANoCaptureImpl {
6264 AANoCaptureCallSiteReturned(const IRPosition &IRP, Attributor &A)
6265 : AANoCaptureImpl(IRP, A) {}
6266
6267 /// See AbstractAttribute::initialize(...).
6268 void initialize(Attributor &A) override {
6269 const Function *F = getAnchorScope();
6270 // Check what state the associated function can actually capture.
6271 determineFunctionCaptureCapabilities(getIRPosition(), *F, *this);
6272 }
6273
6274 /// See AbstractAttribute::trackStatistics()
6275 void trackStatistics() const override {
6277 }
6278};
6279} // namespace
6280
6281/// ------------------ Value Simplify Attribute ----------------------------
6282
6283bool ValueSimplifyStateType::unionAssumed(std::optional<Value *> Other) {
6284 // FIXME: Add a typecast support.
6287 if (SimplifiedAssociatedValue == std::optional<Value *>(nullptr))
6288 return false;
6289
6290 LLVM_DEBUG({
6292 dbgs() << "[ValueSimplify] is assumed to be "
6293 << **SimplifiedAssociatedValue << "\n";
6294 else
6295 dbgs() << "[ValueSimplify] is assumed to be <none>\n";
6296 });
6297 return true;
6298}
6299
6300namespace {
6301struct AAValueSimplifyImpl : AAValueSimplify {
6302 AAValueSimplifyImpl(const IRPosition &IRP, Attributor &A)
6303 : AAValueSimplify(IRP, A) {}
6304
6305 /// See AbstractAttribute::initialize(...).
6306 void initialize(Attributor &A) override {
6307 if (getAssociatedValue().getType()->isVoidTy())
6308 indicatePessimisticFixpoint();
6309 if (A.hasSimplificationCallback(getIRPosition()))
6310 indicatePessimisticFixpoint();
6311 }
6312
6313 /// See AbstractAttribute::getAsStr().
6314 const std::string getAsStr(Attributor *A) const override {
6315 LLVM_DEBUG({
6316 dbgs() << "SAV: " << (bool)SimplifiedAssociatedValue << " ";
6317 if (SimplifiedAssociatedValue && *SimplifiedAssociatedValue)
6318 dbgs() << "SAV: " << **SimplifiedAssociatedValue << " ";
6319 });
6320 return isValidState() ? (isAtFixpoint() ? "simplified" : "maybe-simple")
6321 : "not-simple";
6322 }
6323
6324 /// See AbstractAttribute::trackStatistics()
6325 void trackStatistics() const override {}
6326
6327 /// See AAValueSimplify::getAssumedSimplifiedValue()
6328 std::optional<Value *>
6329 getAssumedSimplifiedValue(Attributor &A) const override {
6330 return SimplifiedAssociatedValue;
6331 }
6332
6333 /// Ensure the return value is \p V with type \p Ty, if not possible return
6334 /// nullptr. If \p Check is true we will only verify such an operation would
6335 /// suceed and return a non-nullptr value if that is the case. No IR is
6336 /// generated or modified.
6337 static Value *ensureType(Attributor &A, Value &V, Type &Ty, Instruction *CtxI,
6338 bool Check) {
6339 if (auto *TypedV = AA::getWithType(V, Ty))
6340 return TypedV;
6341 if (CtxI && V.getType()->canLosslesslyBitCastTo(&Ty))
6342 return Check ? &V
6343 : BitCastInst::CreatePointerBitCastOrAddrSpaceCast(
6344 &V, &Ty, "", CtxI->getIterator());
6345 return nullptr;
6346 }
6347
6348 /// Reproduce \p I with type \p Ty or return nullptr if that is not posisble.
6349 /// If \p Check is true we will only verify such an operation would suceed and
6350 /// return a non-nullptr value if that is the case. No IR is generated or
6351 /// modified.
6352 static Value *reproduceInst(Attributor &A,
6353 const AbstractAttribute &QueryingAA,
6354 Instruction &I, Type &Ty, Instruction *CtxI,
6355 bool Check, ValueToValueMapTy &VMap) {
6356 assert(CtxI && "Cannot reproduce an instruction without context!");
6357 if (Check && (I.mayReadFromMemory() ||
6358 !isSafeToSpeculativelyExecute(&I, CtxI, /* DT */ nullptr,
6359 /* TLI */ nullptr)))
6360 return nullptr;
6361 for (Value *Op : I.operands()) {
6362 Value *NewOp = reproduceValue(A, QueryingAA, *Op, Ty, CtxI, Check, VMap);
6363 if (!NewOp) {
6364 assert(Check && "Manifest of new value unexpectedly failed!");
6365 return nullptr;
6366 }
6367 if (!Check)
6368 VMap[Op] = NewOp;
6369 }
6370 if (Check)
6371 return &I;
6372
6373 Instruction *CloneI = I.clone();
6374 // TODO: Try to salvage debug information here.
6375 CloneI->setDebugLoc(DebugLoc());
6376 VMap[&I] = CloneI;
6377 CloneI->insertBefore(CtxI->getIterator());
6378 RemapInstruction(CloneI, VMap);
6379 return CloneI;
6380 }
6381
6382 /// Reproduce \p V with type \p Ty or return nullptr if that is not posisble.
6383 /// If \p Check is true we will only verify such an operation would suceed and
6384 /// return a non-nullptr value if that is the case. No IR is generated or
6385 /// modified.
6386 static Value *reproduceValue(Attributor &A,
6387 const AbstractAttribute &QueryingAA, Value &V,
6388 Type &Ty, Instruction *CtxI, bool Check,
6389 ValueToValueMapTy &VMap) {
6390 if (const auto &NewV = VMap.lookup(&V))
6391 return NewV;
6392 bool UsedAssumedInformation = false;
6393 std::optional<Value *> SimpleV = A.getAssumedSimplified(
6394 V, QueryingAA, UsedAssumedInformation, AA::Interprocedural);
6395 if (!SimpleV.has_value())
6396 return PoisonValue::get(&Ty);
6397 Value *EffectiveV = &V;
6398 if (*SimpleV)
6399 EffectiveV = *SimpleV;
6400 if (auto *C = dyn_cast<Constant>(EffectiveV))
6401 return C;
6402 if (CtxI && AA::isValidAtPosition(AA::ValueAndContext(*EffectiveV, *CtxI),
6403 A.getInfoCache()))
6404 return ensureType(A, *EffectiveV, Ty, CtxI, Check);
6405 if (auto *I = dyn_cast<Instruction>(EffectiveV))
6406 if (Value *NewV = reproduceInst(A, QueryingAA, *I, Ty, CtxI, Check, VMap))
6407 return ensureType(A, *NewV, Ty, CtxI, Check);
6408 return nullptr;
6409 }
6410
6411 /// Return a value we can use as replacement for the associated one, or
6412 /// nullptr if we don't have one that makes sense.
6413 Value *manifestReplacementValue(Attributor &A, Instruction *CtxI) const {
6414 Value *NewV = SimplifiedAssociatedValue
6415 ? *SimplifiedAssociatedValue
6416 : UndefValue::get(getAssociatedType());
6417 if (NewV && NewV != &getAssociatedValue()) {
6418 ValueToValueMapTy VMap;
6419 // First verify we can reprduce the value with the required type at the
6420 // context location before we actually start modifying the IR.
6421 if (reproduceValue(A, *this, *NewV, *getAssociatedType(), CtxI,
6422 /* CheckOnly */ true, VMap))
6423 return reproduceValue(A, *this, *NewV, *getAssociatedType(), CtxI,
6424 /* CheckOnly */ false, VMap);
6425 }
6426 return nullptr;
6427 }
6428
6429 /// Helper function for querying AAValueSimplify and updating candidate.
6430 /// \param IRP The value position we are trying to unify with SimplifiedValue
6431 bool checkAndUpdate(Attributor &A, const AbstractAttribute &QueryingAA,
6432 const IRPosition &IRP, bool Simplify = true) {
6433 bool UsedAssumedInformation = false;
6434 std::optional<Value *> QueryingValueSimplified = &IRP.getAssociatedValue();
6435 if (Simplify)
6436 QueryingValueSimplified = A.getAssumedSimplified(
6437 IRP, QueryingAA, UsedAssumedInformation, AA::Interprocedural);
6438 return unionAssumed(QueryingValueSimplified);
6439 }
6440
6441 /// Returns a candidate is found or not
6442 template <typename AAType> bool askSimplifiedValueFor(Attributor &A) {
6443 if (!getAssociatedValue().getType()->isIntegerTy())
6444 return false;
6445
6446 // This will also pass the call base context.
6447 const auto *AA =
6448 A.getAAFor<AAType>(*this, getIRPosition(), DepClassTy::NONE);
6449 if (!AA)
6450 return false;
6451
6452 std::optional<Constant *> COpt = AA->getAssumedConstant(A);
6453
6454 if (!COpt) {
6455 SimplifiedAssociatedValue = std::nullopt;
6456 A.recordDependence(*AA, *this, DepClassTy::OPTIONAL);
6457 return true;
6458 }
6459 if (auto *C = *COpt) {
6460 SimplifiedAssociatedValue = C;
6461 A.recordDependence(*AA, *this, DepClassTy::OPTIONAL);
6462 return true;
6463 }
6464 return false;
6465 }
6466
6467 bool askSimplifiedValueForOtherAAs(Attributor &A) {
6468 if (askSimplifiedValueFor<AAValueConstantRange>(A))
6469 return true;
6470 if (askSimplifiedValueFor<AAPotentialConstantValues>(A))
6471 return true;
6472 return false;
6473 }
6474
6475 /// See AbstractAttribute::manifest(...).
6476 ChangeStatus manifest(Attributor &A) override {
6477 ChangeStatus Changed = ChangeStatus::UNCHANGED;
6478 for (auto &U : getAssociatedValue().uses()) {
6479 // Check if we need to adjust the insertion point to make sure the IR is
6480 // valid.
6481 Instruction *IP = dyn_cast<Instruction>(U.getUser());
6482 if (auto *PHI = dyn_cast_or_null<PHINode>(IP))
6483 IP = PHI->getIncomingBlock(U)->getTerminator();
6484 if (auto *NewV = manifestReplacementValue(A, IP)) {
6485 LLVM_DEBUG(dbgs() << "[ValueSimplify] " << getAssociatedValue()
6486 << " -> " << *NewV << " :: " << *this << "\n");
6487 if (A.changeUseAfterManifest(U, *NewV))
6488 Changed = ChangeStatus::CHANGED;
6489 }
6490 }
6491
6492 return Changed | AAValueSimplify::manifest(A);
6493 }
6494
6495 /// See AbstractState::indicatePessimisticFixpoint(...).
6496 ChangeStatus indicatePessimisticFixpoint() override {
6497 SimplifiedAssociatedValue = &getAssociatedValue();
6498 return AAValueSimplify::indicatePessimisticFixpoint();
6499 }
6500};
6501
6502struct AAValueSimplifyArgument final : AAValueSimplifyImpl {
6503 AAValueSimplifyArgument(const IRPosition &IRP, Attributor &A)
6504 : AAValueSimplifyImpl(IRP, A) {}
6505
6506 void initialize(Attributor &A) override {
6507 AAValueSimplifyImpl::initialize(A);
6508 if (A.hasAttr(getIRPosition(),
6509 {Attribute::InAlloca, Attribute::Preallocated,
6510 Attribute::StructRet, Attribute::Nest, Attribute::ByVal},
6511 /* IgnoreSubsumingPositions */ true))
6512 indicatePessimisticFixpoint();
6513 }
6514
6515 /// See AbstractAttribute::updateImpl(...).
6516 ChangeStatus updateImpl(Attributor &A) override {
6517 // Byval is only replacable if it is readonly otherwise we would write into
6518 // the replaced value and not the copy that byval creates implicitly.
6519 Argument *Arg = getAssociatedArgument();
6520 if (Arg->hasByValAttr()) {
6521 // TODO: We probably need to verify synchronization is not an issue, e.g.,
6522 // there is no race by not copying a constant byval.
6523 bool IsKnown;
6524 if (!AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown))
6525 return indicatePessimisticFixpoint();
6526 }
6527
6528 auto Before = SimplifiedAssociatedValue;
6529
6530 auto PredForCallSite = [&](AbstractCallSite ACS) {
6531 const IRPosition &ACSArgPos =
6532 IRPosition::callsite_argument(ACS, getCallSiteArgNo());
6533 // Check if a coresponding argument was found or if it is on not
6534 // associated (which can happen for callback calls).
6535 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
6536 return false;
6537
6538 // Simplify the argument operand explicitly and check if the result is
6539 // valid in the current scope. This avoids refering to simplified values
6540 // in other functions, e.g., we don't want to say a an argument in a
6541 // static function is actually an argument in a different function.
6542 bool UsedAssumedInformation = false;
6543 std::optional<Constant *> SimpleArgOp =
6544 A.getAssumedConstant(ACSArgPos, *this, UsedAssumedInformation);
6545 if (!SimpleArgOp)
6546 return true;
6547 if (!*SimpleArgOp)
6548 return false;
6549 if (!AA::isDynamicallyUnique(A, *this, **SimpleArgOp))
6550 return false;
6551 return unionAssumed(*SimpleArgOp);
6552 };
6553
6554 // Generate a answer specific to a call site context.
6555 bool Success;
6556 bool UsedAssumedInformation = false;
6557 if (hasCallBaseContext() &&
6558 getCallBaseContext()->getCalledOperand() == Arg->getParent())
6559 Success = PredForCallSite(
6560 AbstractCallSite(&getCallBaseContext()->getCalledOperandUse()));
6561 else
6562 Success = A.checkForAllCallSites(PredForCallSite, *this, true,
6563 UsedAssumedInformation);
6564
6565 if (!Success)
6566 if (!askSimplifiedValueForOtherAAs(A))
6567 return indicatePessimisticFixpoint();
6568
6569 // If a candidate was found in this update, return CHANGED.
6570 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED
6571 : ChangeStatus ::CHANGED;
6572 }
6573
6574 /// See AbstractAttribute::trackStatistics()
6575 void trackStatistics() const override {
6576 STATS_DECLTRACK_ARG_ATTR(value_simplify)
6577 }
6578};
6579
6580struct AAValueSimplifyReturned : AAValueSimplifyImpl {
6581 AAValueSimplifyReturned(const IRPosition &IRP, Attributor &A)
6582 : AAValueSimplifyImpl(IRP, A) {}
6583
6584 /// See AAValueSimplify::getAssumedSimplifiedValue()
6585 std::optional<Value *>
6586 getAssumedSimplifiedValue(Attributor &A) const override {
6587 if (!isValidState())
6588 return nullptr;
6589 return SimplifiedAssociatedValue;
6590 }
6591
6592 /// See AbstractAttribute::updateImpl(...).
6593 ChangeStatus updateImpl(Attributor &A) override {
6594 auto Before = SimplifiedAssociatedValue;
6595
6596 auto ReturnInstCB = [&](Instruction &I) {
6597 auto &RI = cast<ReturnInst>(I);
6598 return checkAndUpdate(
6599 A, *this,
6600 IRPosition::value(*RI.getReturnValue(), getCallBaseContext()));
6601 };
6602
6603 bool UsedAssumedInformation = false;
6604 if (!A.checkForAllInstructions(ReturnInstCB, *this, {Instruction::Ret},
6605 UsedAssumedInformation))
6606 if (!askSimplifiedValueForOtherAAs(A))
6607 return indicatePessimisticFixpoint();
6608
6609 // If a candidate was found in this update, return CHANGED.
6610 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED
6611 : ChangeStatus ::CHANGED;
6612 }
6613
6614 ChangeStatus manifest(Attributor &A) override {
6615 // We queried AAValueSimplify for the returned values so they will be
6616 // replaced if a simplified form was found. Nothing to do here.
6617 return ChangeStatus::UNCHANGED;
6618 }
6619
6620 /// See AbstractAttribute::trackStatistics()
6621 void trackStatistics() const override {
6622 STATS_DECLTRACK_FNRET_ATTR(value_simplify)
6623 }
6624};
6625
6626struct AAValueSimplifyFloating : AAValueSimplifyImpl {
6627 AAValueSimplifyFloating(const IRPosition &IRP, Attributor &A)
6628 : AAValueSimplifyImpl(IRP, A) {}
6629
6630 /// See AbstractAttribute::initialize(...).
6631 void initialize(Attributor &A) override {
6632 AAValueSimplifyImpl::initialize(A);
6633 Value &V = getAnchorValue();
6634
6635 // TODO: add other stuffs
6636 if (isa<Constant>(V))
6637 indicatePessimisticFixpoint();
6638 }
6639
6640 /// See AbstractAttribute::updateImpl(...).
6641 ChangeStatus updateImpl(Attributor &A) override {
6642 auto Before = SimplifiedAssociatedValue;
6643 if (!askSimplifiedValueForOtherAAs(A))
6644 return indicatePessimisticFixpoint();
6645
6646 // If a candidate was found in this update, return CHANGED.
6647 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED
6648 : ChangeStatus ::CHANGED;
6649 }
6650
6651 /// See AbstractAttribute::trackStatistics()
6652 void trackStatistics() const override {
6653 STATS_DECLTRACK_FLOATING_ATTR(value_simplify)
6654 }
6655};
6656
6657struct AAValueSimplifyFunction : AAValueSimplifyImpl {
6658 AAValueSimplifyFunction(const IRPosition &IRP, Attributor &A)
6659 : AAValueSimplifyImpl(IRP, A) {}
6660
6661 /// See AbstractAttribute::initialize(...).
6662 void initialize(Attributor &A) override {
6663 SimplifiedAssociatedValue = nullptr;
6664 indicateOptimisticFixpoint();
6665 }
6666 /// See AbstractAttribute::initialize(...).
6667 ChangeStatus updateImpl(Attributor &A) override {
6669 "AAValueSimplify(Function|CallSite)::updateImpl will not be called");
6670 }
6671 /// See AbstractAttribute::trackStatistics()
6672 void trackStatistics() const override {
6673 STATS_DECLTRACK_FN_ATTR(value_simplify)
6674 }
6675};
6676
6677struct AAValueSimplifyCallSite : AAValueSimplifyFunction {
6678 AAValueSimplifyCallSite(const IRPosition &IRP, Attributor &A)
6679 : AAValueSimplifyFunction(IRP, A) {}
6680 /// See AbstractAttribute::trackStatistics()
6681 void trackStatistics() const override {
6682 STATS_DECLTRACK_CS_ATTR(value_simplify)
6683 }
6684};
6685
6686struct AAValueSimplifyCallSiteReturned : AAValueSimplifyImpl {
6687 AAValueSimplifyCallSiteReturned(const IRPosition &IRP, Attributor &A)
6688 : AAValueSimplifyImpl(IRP, A) {}
6689
6690 void initialize(Attributor &A) override {
6691 AAValueSimplifyImpl::initialize(A);
6692 Function *Fn = getAssociatedFunction();
6693 assert(Fn && "Did expect an associted function");
6694 for (Argument &Arg : Fn->args()) {
6695 if (Arg.hasReturnedAttr()) {
6696 auto IRP = IRPosition::callsite_argument(*cast<CallBase>(getCtxI()),
6697 Arg.getArgNo());
6699 checkAndUpdate(A, *this, IRP))
6700 indicateOptimisticFixpoint();
6701 else
6702 indicatePessimisticFixpoint();
6703 return;
6704 }
6705 }
6706 }
6707
6708 /// See AbstractAttribute::updateImpl(...).
6709 ChangeStatus updateImpl(Attributor &A) override {
6710 return indicatePessimisticFixpoint();
6711 }
6712
6713 void trackStatistics() const override {
6714 STATS_DECLTRACK_CSRET_ATTR(value_simplify)
6715 }
6716};
6717
6718struct AAValueSimplifyCallSiteArgument : AAValueSimplifyFloating {
6719 AAValueSimplifyCallSiteArgument(const IRPosition &IRP, Attributor &A)
6720 : AAValueSimplifyFloating(IRP, A) {}
6721
6722 /// See AbstractAttribute::manifest(...).
6723 ChangeStatus manifest(Attributor &A) override {
6724 ChangeStatus Changed = ChangeStatus::UNCHANGED;
6725 // TODO: We should avoid simplification duplication to begin with.
6726 auto *FloatAA = A.lookupAAFor<AAValueSimplify>(
6727 IRPosition::value(getAssociatedValue()), this, DepClassTy::NONE);
6728 if (FloatAA && FloatAA->getState().isValidState())
6729 return Changed;
6730
6731 if (auto *NewV = manifestReplacementValue(A, getCtxI())) {
6732 Use &U = cast<CallBase>(&getAnchorValue())
6733 ->getArgOperandUse(getCallSiteArgNo());
6734 if (A.changeUseAfterManifest(U, *NewV))
6735 Changed = ChangeStatus::CHANGED;
6736 }
6737
6738 return Changed | AAValueSimplify::manifest(A);
6739 }
6740
6741 void trackStatistics() const override {
6742 STATS_DECLTRACK_CSARG_ATTR(value_simplify)
6743 }
6744};
6745} // namespace
6746
6747/// ----------------------- Heap-To-Stack Conversion ---------------------------
6748namespace {
6749struct AAHeapToStackFunction final : public AAHeapToStack {
6750
6751 static bool isGlobalizedLocal(const CallBase &CB) {
6752 Attribute A = CB.getFnAttr("alloc-family");
6753 return A.isValid() && A.getValueAsString() == "__kmpc_alloc_shared";
6754 }
6755
6756 struct AllocationInfo {
6757 /// The call that allocates the memory.
6758 CallBase *const CB;
6759
6760 /// Whether this allocation is an OpenMP globalized local variable.
6761 bool IsGlobalizedLocal = false;
6762
6763 /// The status wrt. a rewrite.
6764 enum {
6765 STACK_DUE_TO_USE,
6766 STACK_DUE_TO_FREE,
6767 INVALID,
6768 } Status = STACK_DUE_TO_USE;
6769
6770 /// Flag to indicate if we encountered a use that might free this allocation
6771 /// but which is not in the deallocation infos.
6772 bool HasPotentiallyFreeingUnknownUses = false;
6773
6774 /// Flag to indicate that we should place the new alloca in the function
6775 /// entry block rather than where the call site (CB) is.
6776 bool MoveAllocaIntoEntry = true;
6777
6778 /// The set of free calls that use this allocation.
6779 SmallSetVector<CallBase *, 1> PotentialFreeCalls{};
6780 };
6781
6782 struct DeallocationInfo {
6783 /// The call that deallocates the memory.
6784 CallBase *const CB;
6785 /// The value freed by the call.
6786 Value *FreedOp;
6787
6788 /// Flag to indicate if we don't know all objects this deallocation might
6789 /// free.
6790 bool MightFreeUnknownObjects = false;
6791
6792 /// The set of allocation calls that are potentially freed.
6793 SmallSetVector<CallBase *, 1> PotentialAllocationCalls{};
6794 };
6795
6796 AAHeapToStackFunction(const IRPosition &IRP, Attributor &A)
6797 : AAHeapToStack(IRP, A) {}
6798
6799 ~AAHeapToStackFunction() override {
6800 // Ensure we call the destructor so we release any memory allocated in the
6801 // sets.
6802 for (auto &It : AllocationInfos)
6803 It.second->~AllocationInfo();
6804 for (auto &It : DeallocationInfos)
6805 It.second->~DeallocationInfo();
6806 }
6807
6808 void initialize(Attributor &A) override {
6809 AAHeapToStack::initialize(A);
6810
6811 const Function *F = getAnchorScope();
6812 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
6813
6814 auto AllocationIdentifierCB = [&](Instruction &I) {
6815 CallBase *CB = dyn_cast<CallBase>(&I);
6816 if (!CB)
6817 return true;
6818 if (Value *FreedOp = getFreedOperand(CB, TLI)) {
6819 DeallocationInfos[CB] = new (A.Allocator) DeallocationInfo{CB, FreedOp};
6820 return true;
6821 }
6822 // To do heap to stack, we need to know that the allocation itself is
6823 // removable once uses are rewritten, and that we can initialize the
6824 // alloca to the same pattern as the original allocation result.
6825 if (isRemovableAlloc(CB, TLI)) {
6826 auto *I8Ty = Type::getInt8Ty(CB->getParent()->getContext());
6827 if (nullptr != getInitialValueOfAllocation(CB, TLI, I8Ty)) {
6828 AllocationInfo *AI = new (A.Allocator) AllocationInfo{CB};
6829 AllocationInfos[CB] = AI;
6830 AI->IsGlobalizedLocal = isGlobalizedLocal(*CB);
6831 }
6832 }
6833 return true;
6834 };
6835
6836 bool UsedAssumedInformation = false;
6837 bool Success = A.checkForAllCallLikeInstructions(
6838 AllocationIdentifierCB, *this, UsedAssumedInformation,
6839 /* CheckBBLivenessOnly */ false,
6840 /* CheckPotentiallyDead */ true);
6841 (void)Success;
6842 assert(Success && "Did not expect the call base visit callback to fail!");
6843
6845 [](const IRPosition &, const AbstractAttribute *,
6846 bool &) -> std::optional<Value *> { return nullptr; };
6847 for (const auto &It : AllocationInfos)
6848 A.registerSimplificationCallback(IRPosition::callsite_returned(*It.first),
6849 SCB);
6850 for (const auto &It : DeallocationInfos)
6851 A.registerSimplificationCallback(IRPosition::callsite_returned(*It.first),
6852 SCB);
6853 }
6854
6855 const std::string getAsStr(Attributor *A) const override {
6856 unsigned NumH2SMallocs = 0, NumInvalidMallocs = 0;
6857 for (const auto &It : AllocationInfos) {
6858 if (It.second->Status == AllocationInfo::INVALID)
6859 ++NumInvalidMallocs;
6860 else
6861 ++NumH2SMallocs;
6862 }
6863 return "[H2S] Mallocs Good/Bad: " + std::to_string(NumH2SMallocs) + "/" +
6864 std::to_string(NumInvalidMallocs);
6865 }
6866
6867 /// See AbstractAttribute::trackStatistics().
6868 void trackStatistics() const override {
6869 STATS_DECL(
6870 MallocCalls, Function,
6871 "Number of malloc/calloc/aligned_alloc calls converted to allocas");
6872 for (const auto &It : AllocationInfos)
6873 if (It.second->Status != AllocationInfo::INVALID)
6874 ++BUILD_STAT_NAME(MallocCalls, Function);
6875 }
6876
6877 bool isAssumedHeapToStack(const CallBase &CB) const override {
6878 if (isValidState())
6879 if (AllocationInfo *AI =
6880 AllocationInfos.lookup(const_cast<CallBase *>(&CB)))
6881 return AI->Status != AllocationInfo::INVALID;
6882 return false;
6883 }
6884
6885 bool isAssumedHeapToStackRemovedFree(CallBase &CB) const override {
6886 if (!isValidState())
6887 return false;
6888
6889 for (const auto &It : AllocationInfos) {
6890 AllocationInfo &AI = *It.second;
6891 if (AI.Status == AllocationInfo::INVALID)
6892 continue;
6893
6894 if (AI.PotentialFreeCalls.count(&CB))
6895 return true;
6896 }
6897
6898 return false;
6899 }
6900
6901 ChangeStatus manifest(Attributor &A) override {
6902 assert(getState().isValidState() &&
6903 "Attempted to manifest an invalid state!");
6904
6905 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
6906 Function *F = getAnchorScope();
6907 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
6908
6909 for (auto &It : AllocationInfos) {
6910 AllocationInfo &AI = *It.second;
6911 if (AI.Status == AllocationInfo::INVALID)
6912 continue;
6913
6914 for (CallBase *FreeCall : AI.PotentialFreeCalls) {
6915 LLVM_DEBUG(dbgs() << "H2S: Removing free call: " << *FreeCall << "\n");
6916 A.deleteAfterManifest(*FreeCall);
6917 HasChanged = ChangeStatus::CHANGED;
6918 }
6919
6920 LLVM_DEBUG(dbgs() << "H2S: Removing malloc-like call: " << *AI.CB
6921 << "\n");
6922
6923 auto Remark = [&](OptimizationRemark OR) {
6924 if (AI.IsGlobalizedLocal)
6925 return OR << "Moving globalized variable to the stack.";
6926 return OR << "Moving memory allocation from the heap to the stack.";
6927 };
6928 if (AI.IsGlobalizedLocal)
6929 A.emitRemark<OptimizationRemark>(AI.CB, "OMP110", Remark);
6930 else
6931 A.emitRemark<OptimizationRemark>(AI.CB, "HeapToStack", Remark);
6932
6933 const DataLayout &DL = A.getInfoCache().getDL();
6934 Value *Size;
6935 std::optional<APInt> SizeAPI = getSize(A, *this, AI);
6936 if (SizeAPI) {
6937 Size = ConstantInt::get(AI.CB->getContext(), *SizeAPI);
6938 } else {
6939 ObjectSizeOpts Opts;
6940 ObjectSizeOffsetEvaluator Eval(*AI.CB->getModule(), TLI, Opts);
6941 SizeOffsetValue SizeOffsetPair = Eval.compute(AI.CB);
6942 assert(SizeOffsetPair != ObjectSizeOffsetEvaluator::unknown() &&
6943 cast<ConstantInt>(SizeOffsetPair.Offset)->isZero());
6944 Size = SizeOffsetPair.Size;
6945 }
6946
6947 BasicBlock::iterator IP = AI.MoveAllocaIntoEntry
6948 ? F->getEntryBlock().begin()
6949 : AI.CB->getIterator();
6950
6951 Align Alignment(1);
6952 if (MaybeAlign RetAlign = AI.CB->getRetAlign())
6953 Alignment = std::max(Alignment, *RetAlign);
6954 if (Value *Align = getAllocAlignment(AI.CB, TLI)) {
6955 std::optional<APInt> AlignmentAPI = getAPInt(A, *this, *Align);
6956 assert(AlignmentAPI && AlignmentAPI->getZExtValue() > 0 &&
6957 "Expected an alignment during manifest!");
6958 Alignment =
6959 std::max(Alignment, assumeAligned(AlignmentAPI->getZExtValue()));
6960 }
6961
6962 // TODO: Hoist the alloca towards the function entry.
6963 unsigned AS = DL.getAllocaAddrSpace();
6964 Instruction *Alloca =
6965 new AllocaInst(Type::getInt8Ty(F->getContext()), AS, Size, Alignment,
6966 AI.CB->getName() + ".h2s", IP);
6967
6968 if (Alloca->getType() != AI.CB->getType())
6969 Alloca = BitCastInst::CreatePointerBitCastOrAddrSpaceCast(
6970 Alloca, AI.CB->getType(), "malloc_cast", AI.CB->getIterator());
6971
6972 auto *I8Ty = Type::getInt8Ty(F->getContext());
6973 auto *InitVal = getInitialValueOfAllocation(AI.CB, TLI, I8Ty);
6974 assert(InitVal &&
6975 "Must be able to materialize initial memory state of allocation");
6976
6977 A.changeAfterManifest(IRPosition::inst(*AI.CB), *Alloca);
6978
6979 if (auto *II = dyn_cast<InvokeInst>(AI.CB)) {
6980 auto *NBB = II->getNormalDest();
6981 UncondBrInst::Create(NBB, AI.CB->getParent());
6982 A.deleteAfterManifest(*AI.CB);
6983 } else {
6984 A.deleteAfterManifest(*AI.CB);
6985 }
6986
6987 // Initialize the alloca with the same value as used by the allocation
6988 // function. We can skip undef as the initial value of an alloc is
6989 // undef, and the memset would simply end up being DSEd.
6990 if (!isa<UndefValue>(InitVal)) {
6991 IRBuilder<> Builder(Alloca->getNextNode());
6992 // TODO: Use alignment above if align!=1
6993 Builder.CreateMemSet(Alloca, InitVal, Size, std::nullopt);
6994 }
6995 HasChanged = ChangeStatus::CHANGED;
6996 }
6997
6998 return HasChanged;
6999 }
7000
7001 std::optional<APInt> getAPInt(Attributor &A, const AbstractAttribute &AA,
7002 Value &V) {
7003 bool UsedAssumedInformation = false;
7004 std::optional<Constant *> SimpleV =
7005 A.getAssumedConstant(V, AA, UsedAssumedInformation);
7006 if (!SimpleV)
7007 return APInt(64, 0);
7008 if (auto *CI = dyn_cast_or_null<ConstantInt>(*SimpleV))
7009 return CI->getValue();
7010 return std::nullopt;
7011 }
7012
7013 std::optional<APInt> getSize(Attributor &A, const AbstractAttribute &AA,
7014 AllocationInfo &AI) {
7015 auto Mapper = [&](const Value *V) -> const Value * {
7016 bool UsedAssumedInformation = false;
7017 if (std::optional<Constant *> SimpleV =
7018 A.getAssumedConstant(*V, AA, UsedAssumedInformation))
7019 if (*SimpleV)
7020 return *SimpleV;
7021 return V;
7022 };
7023
7024 const Function *F = getAnchorScope();
7025 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
7026 return getAllocSize(AI.CB, TLI, Mapper);
7027 }
7028
7029 /// Collection of all malloc-like calls in a function with associated
7030 /// information.
7031 MapVector<CallBase *, AllocationInfo *> AllocationInfos;
7032
7033 /// Collection of all free-like calls in a function with associated
7034 /// information.
7035 MapVector<CallBase *, DeallocationInfo *> DeallocationInfos;
7036
7037 ChangeStatus updateImpl(Attributor &A) override;
7038};
7039
7040ChangeStatus AAHeapToStackFunction::updateImpl(Attributor &A) {
7042 const Function *F = getAnchorScope();
7043 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
7044
7045 const auto *LivenessAA =
7046 A.getAAFor<AAIsDead>(*this, IRPosition::function(*F), DepClassTy::NONE);
7047
7048 MustBeExecutedContextExplorer *Explorer =
7049 A.getInfoCache().getMustBeExecutedContextExplorer();
7050
7051 bool StackIsAccessibleByOtherThreads =
7052 A.getInfoCache().stackIsAccessibleByOtherThreads();
7053
7054 LoopInfo *LI =
7055 A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(*F);
7056 std::optional<bool> MayContainIrreducibleControl;
7057 auto IsInLoop = [&](BasicBlock &BB) {
7058 if (&F->getEntryBlock() == &BB)
7059 return false;
7060 if (!MayContainIrreducibleControl.has_value())
7061 MayContainIrreducibleControl = mayContainIrreducibleControl(*F, LI);
7062 if (*MayContainIrreducibleControl)
7063 return true;
7064 if (!LI)
7065 return true;
7066 return LI->getLoopFor(&BB) != nullptr;
7067 };
7068
7069 // Flag to ensure we update our deallocation information at most once per
7070 // updateImpl call and only if we use the free check reasoning.
7071 bool HasUpdatedFrees = false;
7072
7073 auto UpdateFrees = [&]() {
7074 HasUpdatedFrees = true;
7075
7076 for (auto &It : DeallocationInfos) {
7077 DeallocationInfo &DI = *It.second;
7078 // For now we cannot use deallocations that have unknown inputs, skip
7079 // them.
7080 if (DI.MightFreeUnknownObjects)
7081 continue;
7082
7083 // No need to analyze dead calls, ignore them instead.
7084 bool UsedAssumedInformation = false;
7085 if (A.isAssumedDead(*DI.CB, this, LivenessAA, UsedAssumedInformation,
7086 /* CheckBBLivenessOnly */ true))
7087 continue;
7088
7089 // Use the non-optimistic version to get the freed object.
7090 Value *Obj = getUnderlyingObject(DI.FreedOp);
7091 if (!Obj) {
7092 LLVM_DEBUG(dbgs() << "[H2S] Unknown underlying object for free!\n");
7093 DI.MightFreeUnknownObjects = true;
7094 continue;
7095 }
7096
7097 // Free of null and undef can be ignored as no-ops (or UB in the latter
7098 // case).
7100 continue;
7101
7102 CallBase *ObjCB = dyn_cast<CallBase>(Obj);
7103 if (!ObjCB) {
7104 LLVM_DEBUG(dbgs() << "[H2S] Free of a non-call object: " << *Obj
7105 << "\n");
7106 DI.MightFreeUnknownObjects = true;
7107 continue;
7108 }
7109
7110 AllocationInfo *AI = AllocationInfos.lookup(ObjCB);
7111 if (!AI) {
7112 LLVM_DEBUG(dbgs() << "[H2S] Free of a non-allocation object: " << *Obj
7113 << "\n");
7114 DI.MightFreeUnknownObjects = true;
7115 continue;
7116 }
7117
7118 DI.PotentialAllocationCalls.insert(ObjCB);
7119 }
7120 };
7121
7122 auto FreeCheck = [&](AllocationInfo &AI) {
7123 // If the stack is not accessible by other threads, the "must-free" logic
7124 // doesn't apply as the pointer could be shared and needs to be places in
7125 // "shareable" memory.
7126 if (!StackIsAccessibleByOtherThreads) {
7127 bool IsKnownNoSycn;
7129 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNoSycn)) {
7130 LLVM_DEBUG(
7131 dbgs() << "[H2S] found an escaping use, stack is not accessible by "
7132 "other threads and function is not nosync:\n");
7133 return false;
7134 }
7135 }
7136 if (!HasUpdatedFrees)
7137 UpdateFrees();
7138
7139 // TODO: Allow multi exit functions that have different free calls.
7140 if (AI.PotentialFreeCalls.size() != 1) {
7141 LLVM_DEBUG(dbgs() << "[H2S] did not find one free call but "
7142 << AI.PotentialFreeCalls.size() << "\n");
7143 return false;
7144 }
7145 CallBase *UniqueFree = *AI.PotentialFreeCalls.begin();
7146 DeallocationInfo *DI = DeallocationInfos.lookup(UniqueFree);
7147 if (!DI) {
7148 LLVM_DEBUG(
7149 dbgs() << "[H2S] unique free call was not known as deallocation call "
7150 << *UniqueFree << "\n");
7151 return false;
7152 }
7153 if (DI->MightFreeUnknownObjects) {
7154 LLVM_DEBUG(
7155 dbgs() << "[H2S] unique free call might free unknown allocations\n");
7156 return false;
7157 }
7158 if (DI->PotentialAllocationCalls.empty())
7159 return true;
7160 if (DI->PotentialAllocationCalls.size() > 1) {
7161 LLVM_DEBUG(dbgs() << "[H2S] unique free call might free "
7162 << DI->PotentialAllocationCalls.size()
7163 << " different allocations\n");
7164 return false;
7165 }
7166 if (*DI->PotentialAllocationCalls.begin() != AI.CB) {
7167 LLVM_DEBUG(
7168 dbgs()
7169 << "[H2S] unique free call not known to free this allocation but "
7170 << **DI->PotentialAllocationCalls.begin() << "\n");
7171 return false;
7172 }
7173
7174 // __kmpc_alloc_shared and __kmpc_free_shared are by construction matched.
7175 if (!AI.IsGlobalizedLocal) {
7176 Instruction *CtxI = isa<InvokeInst>(AI.CB) ? AI.CB : AI.CB->getNextNode();
7177 if (!Explorer || !Explorer->findInContextOf(UniqueFree, CtxI)) {
7178 LLVM_DEBUG(dbgs() << "[H2S] unique free call might not be executed "
7179 "with the allocation "
7180 << *UniqueFree << "\n");
7181 return false;
7182 }
7183 }
7184 return true;
7185 };
7186
7187 auto UsesCheck = [&](AllocationInfo &AI) {
7188 bool ValidUsesOnly = true;
7189
7190 auto Pred = [&](const Use &U, bool &Follow) -> bool {
7191 Instruction *UserI = cast<Instruction>(U.getUser());
7192 if (isa<LoadInst>(UserI))
7193 return true;
7194 if (auto *SI = dyn_cast<StoreInst>(UserI)) {
7195 if (SI->getValueOperand() == U.get()) {
7197 << "[H2S] escaping store to memory: " << *UserI << "\n");
7198 ValidUsesOnly = false;
7199 } else {
7200 // A store into the malloc'ed memory is fine.
7201 }
7202 return true;
7203 }
7204 if (auto *CB = dyn_cast<CallBase>(UserI)) {
7205 if (!CB->isArgOperand(&U) || CB->isLifetimeStartOrEnd())
7206 return true;
7207 if (DeallocationInfos.count(CB)) {
7208 AI.PotentialFreeCalls.insert(CB);
7209 return true;
7210 }
7211
7212 unsigned ArgNo = CB->getArgOperandNo(&U);
7213 auto CBIRP = IRPosition::callsite_argument(*CB, ArgNo);
7214
7215 bool IsKnownNoCapture;
7216 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
7217 A, this, CBIRP, DepClassTy::OPTIONAL, IsKnownNoCapture);
7218
7219 // If a call site argument use is nofree, we are fine.
7220 bool IsKnownNoFree;
7221 bool IsAssumedNoFree = AA::hasAssumedIRAttr<Attribute::NoFree>(
7222 A, this, CBIRP, DepClassTy::OPTIONAL, IsKnownNoFree);
7223
7224 if (!IsAssumedNoCapture ||
7225 (!AI.IsGlobalizedLocal && !IsAssumedNoFree)) {
7226 AI.HasPotentiallyFreeingUnknownUses |= !IsAssumedNoFree;
7227
7228 // Emit a missed remark if this is missed OpenMP globalization.
7229 auto Remark = [&](OptimizationRemarkMissed ORM) {
7230 return ORM
7231 << "Could not move globalized variable to the stack. "
7232 "Variable is potentially captured in call. Mark "
7233 "parameter as `__attribute__((noescape))` to override.";
7234 };
7235
7236 if (ValidUsesOnly && AI.IsGlobalizedLocal)
7237 A.emitRemark<OptimizationRemarkMissed>(CB, "OMP113", Remark);
7238
7239 LLVM_DEBUG(dbgs() << "[H2S] Bad user: " << *UserI << "\n");
7240 ValidUsesOnly = false;
7241 }
7242 return true;
7243 }
7244
7245 if (isa<GetElementPtrInst>(UserI) || isa<BitCastInst>(UserI) ||
7246 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) {
7247 Follow = true;
7248 return true;
7249 }
7250 // Unknown user for which we can not track uses further (in a way that
7251 // makes sense).
7252 LLVM_DEBUG(dbgs() << "[H2S] Unknown user: " << *UserI << "\n");
7253 ValidUsesOnly = false;
7254 return true;
7255 };
7256 if (!A.checkForAllUses(Pred, *this, *AI.CB, /* CheckBBLivenessOnly */ false,
7257 DepClassTy::OPTIONAL, /* IgnoreDroppableUses */ true,
7258 [&](const Use &OldU, const Use &NewU) {
7259 auto *SI = dyn_cast<StoreInst>(OldU.getUser());
7260 return !SI || StackIsAccessibleByOtherThreads ||
7261 AA::isAssumedThreadLocalObject(
7262 A, *SI->getPointerOperand(), *this);
7263 }))
7264 return false;
7265 return ValidUsesOnly;
7266 };
7267
7268 // The actual update starts here. We look at all allocations and depending on
7269 // their status perform the appropriate check(s).
7270 for (auto &It : AllocationInfos) {
7271 AllocationInfo &AI = *It.second;
7272 if (AI.Status == AllocationInfo::INVALID)
7273 continue;
7274
7275 if (Value *Align = getAllocAlignment(AI.CB, TLI)) {
7276 std::optional<APInt> APAlign = getAPInt(A, *this, *Align);
7277 if (!APAlign) {
7278 // Can't generate an alloca which respects the required alignment
7279 // on the allocation.
7280 LLVM_DEBUG(dbgs() << "[H2S] Unknown allocation alignment: " << *AI.CB
7281 << "\n");
7282 AI.Status = AllocationInfo::INVALID;
7284 continue;
7285 }
7286 if (APAlign->ugt(llvm::Value::MaximumAlignment) ||
7287 !APAlign->isPowerOf2()) {
7288 LLVM_DEBUG(dbgs() << "[H2S] Invalid allocation alignment: " << APAlign
7289 << "\n");
7290 AI.Status = AllocationInfo::INVALID;
7292 continue;
7293 }
7294 }
7295
7296 std::optional<APInt> Size = getSize(A, *this, AI);
7297 if (!AI.IsGlobalizedLocal && MaxHeapToStackSize != -1) {
7298 if (!Size || Size->ugt(MaxHeapToStackSize)) {
7299 LLVM_DEBUG({
7300 if (!Size)
7301 dbgs() << "[H2S] Unknown allocation size: " << *AI.CB << "\n";
7302 else
7303 dbgs() << "[H2S] Allocation size too large: " << *AI.CB << " vs. "
7304 << MaxHeapToStackSize << "\n";
7305 });
7306
7307 AI.Status = AllocationInfo::INVALID;
7309 continue;
7310 }
7311 }
7312
7313 switch (AI.Status) {
7314 case AllocationInfo::STACK_DUE_TO_USE:
7315 if (UsesCheck(AI))
7316 break;
7317 AI.Status = AllocationInfo::STACK_DUE_TO_FREE;
7318 [[fallthrough]];
7319 case AllocationInfo::STACK_DUE_TO_FREE:
7320 if (FreeCheck(AI))
7321 break;
7322 AI.Status = AllocationInfo::INVALID;
7324 break;
7325 case AllocationInfo::INVALID:
7326 llvm_unreachable("Invalid allocations should never reach this point!");
7327 };
7328
7329 // Check if we still think we can move it into the entry block. If the
7330 // alloca comes from a converted __kmpc_alloc_shared then we can usually
7331 // ignore the potential complications associated with loops.
7332 bool IsGlobalizedLocal = AI.IsGlobalizedLocal;
7333 if (AI.MoveAllocaIntoEntry &&
7334 (!Size.has_value() ||
7335 (!IsGlobalizedLocal && IsInLoop(*AI.CB->getParent()))))
7336 AI.MoveAllocaIntoEntry = false;
7337 }
7338
7339 return Changed;
7340}
7341} // namespace
7342
7343/// ----------------------- Privatizable Pointers ------------------------------
7344namespace {
7345struct AAPrivatizablePtrImpl : public AAPrivatizablePtr {
7346 AAPrivatizablePtrImpl(const IRPosition &IRP, Attributor &A)
7347 : AAPrivatizablePtr(IRP, A), PrivatizableType(std::nullopt) {}
7348
7349 ChangeStatus indicatePessimisticFixpoint() override {
7350 AAPrivatizablePtr::indicatePessimisticFixpoint();
7351 PrivatizableType = nullptr;
7352 return ChangeStatus::CHANGED;
7353 }
7354
7355 /// Identify the type we can chose for a private copy of the underlying
7356 /// argument. std::nullopt means it is not clear yet, nullptr means there is
7357 /// none.
7358 virtual std::optional<Type *> identifyPrivatizableType(Attributor &A) = 0;
7359
7360 /// Return a privatizable type that encloses both T0 and T1.
7361 /// TODO: This is merely a stub for now as we should manage a mapping as well.
7362 std::optional<Type *> combineTypes(std::optional<Type *> T0,
7363 std::optional<Type *> T1) {
7364 if (!T0)
7365 return T1;
7366 if (!T1)
7367 return T0;
7368 if (T0 == T1)
7369 return T0;
7370 return nullptr;
7371 }
7372
7373 std::optional<Type *> getPrivatizableType() const override {
7374 return PrivatizableType;
7375 }
7376
7377 const std::string getAsStr(Attributor *A) const override {
7378 return isAssumedPrivatizablePtr() ? "[priv]" : "[no-priv]";
7379 }
7380
7381protected:
7382 std::optional<Type *> PrivatizableType;
7383};
7384
7385// TODO: Do this for call site arguments (probably also other values) as well.
7386
7387struct AAPrivatizablePtrArgument final : public AAPrivatizablePtrImpl {
7388 AAPrivatizablePtrArgument(const IRPosition &IRP, Attributor &A)
7389 : AAPrivatizablePtrImpl(IRP, A) {}
7390
7391 /// See AAPrivatizablePtrImpl::identifyPrivatizableType(...)
7392 std::optional<Type *> identifyPrivatizableType(Attributor &A) override {
7393 // If this is a byval argument and we know all the call sites (so we can
7394 // rewrite them), there is no need to check them explicitly.
7395 bool UsedAssumedInformation = false;
7397 A.getAttrs(getIRPosition(), {Attribute::ByVal}, Attrs,
7398 /* IgnoreSubsumingPositions */ true);
7399 if (!Attrs.empty() &&
7400 A.checkForAllCallSites([](AbstractCallSite ACS) { return true; }, *this,
7401 true, UsedAssumedInformation))
7402 return Attrs[0].getValueAsType();
7403
7404 std::optional<Type *> Ty;
7405 unsigned ArgNo = getIRPosition().getCallSiteArgNo();
7406
7407 // Make sure the associated call site argument has the same type at all call
7408 // sites and it is an allocation we know is safe to privatize, for now that
7409 // means we only allow alloca instructions.
7410 // TODO: We can additionally analyze the accesses in the callee to create
7411 // the type from that information instead. That is a little more
7412 // involved and will be done in a follow up patch.
7413 auto CallSiteCheck = [&](AbstractCallSite ACS) {
7414 IRPosition ACSArgPos = IRPosition::callsite_argument(ACS, ArgNo);
7415 // Check if a coresponding argument was found or if it is one not
7416 // associated (which can happen for callback calls).
7417 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
7418 return false;
7419
7420 // Check that all call sites agree on a type.
7421 auto *PrivCSArgAA =
7422 A.getAAFor<AAPrivatizablePtr>(*this, ACSArgPos, DepClassTy::REQUIRED);
7423 if (!PrivCSArgAA)
7424 return false;
7425 std::optional<Type *> CSTy = PrivCSArgAA->getPrivatizableType();
7426
7427 LLVM_DEBUG({
7428 dbgs() << "[AAPrivatizablePtr] ACSPos: " << ACSArgPos << ", CSTy: ";
7429 if (CSTy && *CSTy)
7430 (*CSTy)->print(dbgs());
7431 else if (CSTy)
7432 dbgs() << "<nullptr>";
7433 else
7434 dbgs() << "<none>";
7435 });
7436
7437 Ty = combineTypes(Ty, CSTy);
7438
7439 LLVM_DEBUG({
7440 dbgs() << " : New Type: ";
7441 if (Ty && *Ty)
7442 (*Ty)->print(dbgs());
7443 else if (Ty)
7444 dbgs() << "<nullptr>";
7445 else
7446 dbgs() << "<none>";
7447 dbgs() << "\n";
7448 });
7449
7450 return !Ty || *Ty;
7451 };
7452
7453 if (!A.checkForAllCallSites(CallSiteCheck, *this, true,
7454 UsedAssumedInformation))
7455 return nullptr;
7456 return Ty;
7457 }
7458
7459 /// See AbstractAttribute::updateImpl(...).
7460 ChangeStatus updateImpl(Attributor &A) override {
7461 PrivatizableType = identifyPrivatizableType(A);
7462 if (!PrivatizableType)
7463 return ChangeStatus::UNCHANGED;
7464 if (!*PrivatizableType)
7465 return indicatePessimisticFixpoint();
7466
7467 // The dependence is optional so we don't give up once we give up on the
7468 // alignment.
7469 A.getAAFor<AAAlign>(*this, IRPosition::value(getAssociatedValue()),
7470 DepClassTy::OPTIONAL);
7471
7472 // Avoid arguments with padding for now.
7473 if (!A.hasAttr(getIRPosition(), Attribute::ByVal) &&
7474 !isDenselyPacked(*PrivatizableType, A.getInfoCache().getDL())) {
7475 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Padding detected\n");
7476 return indicatePessimisticFixpoint();
7477 }
7478
7479 // Collect the types that will replace the privatizable type in the function
7480 // signature.
7481 SmallVector<Type *, 16> ReplacementTypes;
7482 identifyReplacementTypes(*PrivatizableType, ReplacementTypes);
7483
7484 // Verify callee and caller agree on how the promoted argument would be
7485 // passed.
7486 Function &Fn = *getIRPosition().getAnchorScope();
7487 const auto *TTI =
7488 A.getInfoCache().getAnalysisResultForFunction<TargetIRAnalysis>(Fn);
7489 if (!TTI) {
7490 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Missing TTI for function "
7491 << Fn.getName() << "\n");
7492 return indicatePessimisticFixpoint();
7493 }
7494
7495 auto CallSiteCheck = [&](AbstractCallSite ACS) {
7496 CallBase *CB = ACS.getInstruction();
7497 return TTI->areTypesABICompatible(
7498 CB->getCaller(),
7500 ReplacementTypes);
7501 };
7502 bool UsedAssumedInformation = false;
7503 if (!A.checkForAllCallSites(CallSiteCheck, *this, true,
7504 UsedAssumedInformation)) {
7505 LLVM_DEBUG(
7506 dbgs() << "[AAPrivatizablePtr] ABI incompatibility detected for "
7507 << Fn.getName() << "\n");
7508 return indicatePessimisticFixpoint();
7509 }
7510
7511 // Register a rewrite of the argument.
7512 Argument *Arg = getAssociatedArgument();
7513 if (!A.isValidFunctionSignatureRewrite(*Arg, ReplacementTypes)) {
7514 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Rewrite not valid\n");
7515 return indicatePessimisticFixpoint();
7516 }
7517
7518 unsigned ArgNo = Arg->getArgNo();
7519
7520 // Helper to check if for the given call site the associated argument is
7521 // passed to a callback where the privatization would be different.
7522 auto IsCompatiblePrivArgOfCallback = [&](CallBase &CB) {
7523 SmallVector<const Use *, 4> CallbackUses;
7524 AbstractCallSite::getCallbackUses(CB, CallbackUses);
7525 for (const Use *U : CallbackUses) {
7526 AbstractCallSite CBACS(U);
7527 assert(CBACS && CBACS.isCallbackCall());
7528 for (Argument &CBArg : CBACS.getCalledFunction()->args()) {
7529 int CBArgNo = CBACS.getCallArgOperandNo(CBArg);
7530
7531 LLVM_DEBUG({
7532 dbgs()
7533 << "[AAPrivatizablePtr] Argument " << *Arg
7534 << "check if can be privatized in the context of its parent ("
7535 << Arg->getParent()->getName()
7536 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7537 "callback ("
7538 << CBArgNo << "@" << CBACS.getCalledFunction()->getName()
7539 << ")\n[AAPrivatizablePtr] " << CBArg << " : "
7540 << CBACS.getCallArgOperand(CBArg) << " vs "
7541 << CB.getArgOperand(ArgNo) << "\n"
7542 << "[AAPrivatizablePtr] " << CBArg << " : "
7543 << CBACS.getCallArgOperandNo(CBArg) << " vs " << ArgNo << "\n";
7544 });
7545
7546 if (CBArgNo != int(ArgNo))
7547 continue;
7548 const auto *CBArgPrivAA = A.getAAFor<AAPrivatizablePtr>(
7549 *this, IRPosition::argument(CBArg), DepClassTy::REQUIRED);
7550 if (CBArgPrivAA && CBArgPrivAA->isValidState()) {
7551 auto CBArgPrivTy = CBArgPrivAA->getPrivatizableType();
7552 if (!CBArgPrivTy)
7553 continue;
7554 if (*CBArgPrivTy == PrivatizableType)
7555 continue;
7556 }
7557
7558 LLVM_DEBUG({
7559 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
7560 << " cannot be privatized in the context of its parent ("
7561 << Arg->getParent()->getName()
7562 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7563 "callback ("
7564 << CBArgNo << "@" << CBACS.getCalledFunction()->getName()
7565 << ").\n[AAPrivatizablePtr] for which the argument "
7566 "privatization is not compatible.\n";
7567 });
7568 return false;
7569 }
7570 }
7571 return true;
7572 };
7573
7574 // Helper to check if for the given call site the associated argument is
7575 // passed to a direct call where the privatization would be different.
7576 auto IsCompatiblePrivArgOfDirectCS = [&](AbstractCallSite ACS) {
7577 CallBase *DC = cast<CallBase>(ACS.getInstruction());
7578 int DCArgNo = ACS.getCallArgOperandNo(ArgNo);
7579 assert(DCArgNo >= 0 && unsigned(DCArgNo) < DC->arg_size() &&
7580 "Expected a direct call operand for callback call operand");
7581
7582 Function *DCCallee =
7584 LLVM_DEBUG({
7585 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
7586 << " check if be privatized in the context of its parent ("
7587 << Arg->getParent()->getName()
7588 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7589 "direct call of ("
7590 << DCArgNo << "@" << DCCallee->getName() << ").\n";
7591 });
7592
7593 if (unsigned(DCArgNo) < DCCallee->arg_size()) {
7594 const auto *DCArgPrivAA = A.getAAFor<AAPrivatizablePtr>(
7595 *this, IRPosition::argument(*DCCallee->getArg(DCArgNo)),
7596 DepClassTy::REQUIRED);
7597 if (DCArgPrivAA && DCArgPrivAA->isValidState()) {
7598 auto DCArgPrivTy = DCArgPrivAA->getPrivatizableType();
7599 if (!DCArgPrivTy)
7600 return true;
7601 if (*DCArgPrivTy == PrivatizableType)
7602 return true;
7603 }
7604 }
7605
7606 LLVM_DEBUG({
7607 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
7608 << " cannot be privatized in the context of its parent ("
7609 << Arg->getParent()->getName()
7610 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7611 "direct call of ("
7613 << ").\n[AAPrivatizablePtr] for which the argument "
7614 "privatization is not compatible.\n";
7615 });
7616 return false;
7617 };
7618
7619 // Helper to check if the associated argument is used at the given abstract
7620 // call site in a way that is incompatible with the privatization assumed
7621 // here.
7622 auto IsCompatiblePrivArgOfOtherCallSite = [&](AbstractCallSite ACS) {
7623 if (ACS.isDirectCall())
7624 return IsCompatiblePrivArgOfCallback(*ACS.getInstruction());
7625 if (ACS.isCallbackCall())
7626 return IsCompatiblePrivArgOfDirectCS(ACS);
7627 return false;
7628 };
7629
7630 if (!A.checkForAllCallSites(IsCompatiblePrivArgOfOtherCallSite, *this, true,
7631 UsedAssumedInformation))
7632 return indicatePessimisticFixpoint();
7633
7634 return ChangeStatus::UNCHANGED;
7635 }
7636
7637 /// Given a type to private \p PrivType, collect the constituates (which are
7638 /// used) in \p ReplacementTypes.
7639 static void
7640 identifyReplacementTypes(Type *PrivType,
7641 SmallVectorImpl<Type *> &ReplacementTypes) {
7642 // TODO: For now we expand the privatization type to the fullest which can
7643 // lead to dead arguments that need to be removed later.
7644 assert(PrivType && "Expected privatizable type!");
7645
7646 // Traverse the type, extract constituate types on the outermost level.
7647 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) {
7648 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++)
7649 ReplacementTypes.push_back(PrivStructType->getElementType(u));
7650 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) {
7651 ReplacementTypes.append(PrivArrayType->getNumElements(),
7652 PrivArrayType->getElementType());
7653 } else {
7654 ReplacementTypes.push_back(PrivType);
7655 }
7656 }
7657
7658 /// Initialize \p Base according to the type \p PrivType at position \p IP.
7659 /// The values needed are taken from the arguments of \p F starting at
7660 /// position \p ArgNo.
7661 static void createInitialization(Type *PrivType, Value &Base, Function &F,
7662 unsigned ArgNo, BasicBlock::iterator IP) {
7663 assert(PrivType && "Expected privatizable type!");
7664
7665 IRBuilder<NoFolder> IRB(IP);
7666 const DataLayout &DL = F.getDataLayout();
7667
7668 // Traverse the type, build GEPs and stores.
7669 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) {
7670 const StructLayout *PrivStructLayout = DL.getStructLayout(PrivStructType);
7671 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++) {
7672 Value *Ptr =
7673 constructPointer(&Base, PrivStructLayout->getElementOffset(u), IRB);
7674 new StoreInst(F.getArg(ArgNo + u), Ptr, IP);
7675 }
7676 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) {
7677 Type *PointeeTy = PrivArrayType->getElementType();
7678 uint64_t PointeeTySize = DL.getTypeStoreSize(PointeeTy);
7679 for (unsigned u = 0, e = PrivArrayType->getNumElements(); u < e; u++) {
7680 Value *Ptr = constructPointer(&Base, u * PointeeTySize, IRB);
7681 new StoreInst(F.getArg(ArgNo + u), Ptr, IP);
7682 }
7683 } else {
7684 new StoreInst(F.getArg(ArgNo), &Base, IP);
7685 }
7686 }
7687
7688 /// Extract values from \p Base according to the type \p PrivType at the
7689 /// call position \p ACS. The values are appended to \p ReplacementValues.
7690 void createReplacementValues(Align Alignment, Type *PrivType,
7691 AbstractCallSite ACS, Value *Base,
7692 SmallVectorImpl<Value *> &ReplacementValues) {
7693 assert(Base && "Expected base value!");
7694 assert(PrivType && "Expected privatizable type!");
7695 Instruction *IP = ACS.getInstruction();
7696
7697 IRBuilder<NoFolder> IRB(IP);
7698 const DataLayout &DL = IP->getDataLayout();
7699
7700 // Traverse the type, build GEPs and loads.
7701 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) {
7702 const StructLayout *PrivStructLayout = DL.getStructLayout(PrivStructType);
7703 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++) {
7704 Type *PointeeTy = PrivStructType->getElementType(u);
7705 Value *Ptr =
7706 constructPointer(Base, PrivStructLayout->getElementOffset(u), IRB);
7707 LoadInst *L = new LoadInst(PointeeTy, Ptr, "", IP->getIterator());
7708 L->setAlignment(Alignment);
7709 ReplacementValues.push_back(L);
7710 }
7711 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) {
7712 Type *PointeeTy = PrivArrayType->getElementType();
7713 uint64_t PointeeTySize = DL.getTypeStoreSize(PointeeTy);
7714 for (unsigned u = 0, e = PrivArrayType->getNumElements(); u < e; u++) {
7715 Value *Ptr = constructPointer(Base, u * PointeeTySize, IRB);
7716 LoadInst *L = new LoadInst(PointeeTy, Ptr, "", IP->getIterator());
7717 L->setAlignment(Alignment);
7718 ReplacementValues.push_back(L);
7719 }
7720 } else {
7721 LoadInst *L = new LoadInst(PrivType, Base, "", IP->getIterator());
7722 L->setAlignment(Alignment);
7723 ReplacementValues.push_back(L);
7724 }
7725 }
7726
7727 /// See AbstractAttribute::manifest(...)
7728 ChangeStatus manifest(Attributor &A) override {
7729 if (!PrivatizableType)
7730 return ChangeStatus::UNCHANGED;
7731 assert(*PrivatizableType && "Expected privatizable type!");
7732
7733 // Collect all tail calls in the function as we cannot allow new allocas to
7734 // escape into tail recursion.
7735 // TODO: Be smarter about new allocas escaping into tail calls.
7737 bool UsedAssumedInformation = false;
7738 if (!A.checkForAllInstructions(
7739 [&](Instruction &I) {
7740 CallInst &CI = cast<CallInst>(I);
7741 if (CI.isTailCall())
7742 TailCalls.push_back(&CI);
7743 return true;
7744 },
7745 *this, {Instruction::Call}, UsedAssumedInformation))
7746 return ChangeStatus::UNCHANGED;
7747
7748 Argument *Arg = getAssociatedArgument();
7749 // Query AAAlign attribute for alignment of associated argument to
7750 // determine the best alignment of loads.
7751 const auto *AlignAA =
7752 A.getAAFor<AAAlign>(*this, IRPosition::value(*Arg), DepClassTy::NONE);
7753
7754 // Callback to repair the associated function. A new alloca is placed at the
7755 // beginning and initialized with the values passed through arguments. The
7756 // new alloca replaces the use of the old pointer argument.
7758 [=](const Attributor::ArgumentReplacementInfo &ARI,
7759 Function &ReplacementFn, Function::arg_iterator ArgIt) {
7760 BasicBlock &EntryBB = ReplacementFn.getEntryBlock();
7762 const DataLayout &DL = IP->getDataLayout();
7763 unsigned AS = DL.getAllocaAddrSpace();
7764 Instruction *AI = new AllocaInst(*PrivatizableType, AS,
7765 Arg->getName() + ".priv", IP);
7766 createInitialization(*PrivatizableType, *AI, ReplacementFn,
7767 ArgIt->getArgNo(), IP);
7768
7769 if (AI->getType() != Arg->getType())
7770 AI = BitCastInst::CreatePointerBitCastOrAddrSpaceCast(
7771 AI, Arg->getType(), "", IP);
7772 Arg->replaceAllUsesWith(AI);
7773
7774 for (CallInst *CI : TailCalls)
7775 CI->setTailCall(false);
7776 };
7777
7778 // Callback to repair a call site of the associated function. The elements
7779 // of the privatizable type are loaded prior to the call and passed to the
7780 // new function version.
7782 [=](const Attributor::ArgumentReplacementInfo &ARI,
7783 AbstractCallSite ACS, SmallVectorImpl<Value *> &NewArgOperands) {
7784 // When no alignment is specified for the load instruction,
7785 // natural alignment is assumed.
7786 createReplacementValues(
7787 AlignAA ? AlignAA->getAssumedAlign() : Align(0),
7788 *PrivatizableType, ACS,
7789 ACS.getCallArgOperand(ARI.getReplacedArg().getArgNo()),
7790 NewArgOperands);
7791 };
7792
7793 // Collect the types that will replace the privatizable type in the function
7794 // signature.
7795 SmallVector<Type *, 16> ReplacementTypes;
7796 identifyReplacementTypes(*PrivatizableType, ReplacementTypes);
7797
7798 // Register a rewrite of the argument.
7799 if (A.registerFunctionSignatureRewrite(*Arg, ReplacementTypes,
7800 std::move(FnRepairCB),
7801 std::move(ACSRepairCB)))
7802 return ChangeStatus::CHANGED;
7803 return ChangeStatus::UNCHANGED;
7804 }
7805
7806 /// See AbstractAttribute::trackStatistics()
7807 void trackStatistics() const override {
7808 STATS_DECLTRACK_ARG_ATTR(privatizable_ptr);
7809 }
7810};
7811
7812struct AAPrivatizablePtrFloating : public AAPrivatizablePtrImpl {
7813 AAPrivatizablePtrFloating(const IRPosition &IRP, Attributor &A)
7814 : AAPrivatizablePtrImpl(IRP, A) {}
7815
7816 /// See AbstractAttribute::initialize(...).
7817 void initialize(Attributor &A) override {
7818 // TODO: We can privatize more than arguments.
7819 indicatePessimisticFixpoint();
7820 }
7821
7822 ChangeStatus updateImpl(Attributor &A) override {
7823 llvm_unreachable("AAPrivatizablePtr(Floating|Returned|CallSiteReturned)::"
7824 "updateImpl will not be called");
7825 }
7826
7827 /// See AAPrivatizablePtrImpl::identifyPrivatizableType(...)
7828 std::optional<Type *> identifyPrivatizableType(Attributor &A) override {
7829 Value *Obj = getUnderlyingObject(&getAssociatedValue());
7830 if (!Obj) {
7831 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] No underlying object found!\n");
7832 return nullptr;
7833 }
7834
7835 if (auto *AI = dyn_cast<AllocaInst>(Obj))
7836 if (auto *CI = dyn_cast<ConstantInt>(AI->getArraySize()))
7837 if (CI->isOne())
7838 return AI->getAllocatedType();
7839 if (auto *Arg = dyn_cast<Argument>(Obj)) {
7840 auto *PrivArgAA = A.getAAFor<AAPrivatizablePtr>(
7841 *this, IRPosition::argument(*Arg), DepClassTy::REQUIRED);
7842 if (PrivArgAA && PrivArgAA->isAssumedPrivatizablePtr())
7843 return PrivArgAA->getPrivatizableType();
7844 }
7845
7846 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Underlying object neither valid "
7847 "alloca nor privatizable argument: "
7848 << *Obj << "!\n");
7849 return nullptr;
7850 }
7851
7852 /// See AbstractAttribute::trackStatistics()
7853 void trackStatistics() const override {
7854 STATS_DECLTRACK_FLOATING_ATTR(privatizable_ptr);
7855 }
7856};
7857
7858struct AAPrivatizablePtrCallSiteArgument final
7859 : public AAPrivatizablePtrFloating {
7860 AAPrivatizablePtrCallSiteArgument(const IRPosition &IRP, Attributor &A)
7861 : AAPrivatizablePtrFloating(IRP, A) {}
7862
7863 /// See AbstractAttribute::initialize(...).
7864 void initialize(Attributor &A) override {
7865 if (A.hasAttr(getIRPosition(), Attribute::ByVal))
7866 indicateOptimisticFixpoint();
7867 }
7868
7869 /// See AbstractAttribute::updateImpl(...).
7870 ChangeStatus updateImpl(Attributor &A) override {
7871 PrivatizableType = identifyPrivatizableType(A);
7872 if (!PrivatizableType)
7873 return ChangeStatus::UNCHANGED;
7874 if (!*PrivatizableType)
7875 return indicatePessimisticFixpoint();
7876
7877 const IRPosition &IRP = getIRPosition();
7878 bool IsKnownNoCapture;
7879 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
7880 A, this, IRP, DepClassTy::REQUIRED, IsKnownNoCapture);
7881 if (!IsAssumedNoCapture) {
7882 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer might be captured!\n");
7883 return indicatePessimisticFixpoint();
7884 }
7885
7886 bool IsKnownNoAlias;
7888 A, this, IRP, DepClassTy::REQUIRED, IsKnownNoAlias)) {
7889 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer might alias!\n");
7890 return indicatePessimisticFixpoint();
7891 }
7892
7893 bool IsKnown;
7894 if (!AA::isAssumedReadOnly(A, IRP, *this, IsKnown)) {
7895 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer is written!\n");
7896 return indicatePessimisticFixpoint();
7897 }
7898
7899 return ChangeStatus::UNCHANGED;
7900 }
7901
7902 /// See AbstractAttribute::trackStatistics()
7903 void trackStatistics() const override {
7904 STATS_DECLTRACK_CSARG_ATTR(privatizable_ptr);
7905 }
7906};
7907
7908struct AAPrivatizablePtrCallSiteReturned final
7909 : public AAPrivatizablePtrFloating {
7910 AAPrivatizablePtrCallSiteReturned(const IRPosition &IRP, Attributor &A)
7911 : AAPrivatizablePtrFloating(IRP, A) {}
7912
7913 /// See AbstractAttribute::initialize(...).
7914 void initialize(Attributor &A) override {
7915 // TODO: We can privatize more than arguments.
7916 indicatePessimisticFixpoint();
7917 }
7918
7919 /// See AbstractAttribute::trackStatistics()
7920 void trackStatistics() const override {
7921 STATS_DECLTRACK_CSRET_ATTR(privatizable_ptr);
7922 }
7923};
7924
7925struct AAPrivatizablePtrReturned final : public AAPrivatizablePtrFloating {
7926 AAPrivatizablePtrReturned(const IRPosition &IRP, Attributor &A)
7927 : AAPrivatizablePtrFloating(IRP, A) {}
7928
7929 /// See AbstractAttribute::initialize(...).
7930 void initialize(Attributor &A) override {
7931 // TODO: We can privatize more than arguments.
7932 indicatePessimisticFixpoint();
7933 }
7934
7935 /// See AbstractAttribute::trackStatistics()
7936 void trackStatistics() const override {
7937 STATS_DECLTRACK_FNRET_ATTR(privatizable_ptr);
7938 }
7939};
7940} // namespace
7941
7942/// -------------------- Memory Behavior Attributes ----------------------------
7943/// Includes read-none, read-only, and write-only.
7944/// ----------------------------------------------------------------------------
7945namespace {
7946struct AAMemoryBehaviorImpl : public AAMemoryBehavior {
7947 AAMemoryBehaviorImpl(const IRPosition &IRP, Attributor &A)
7948 : AAMemoryBehavior(IRP, A) {}
7949
7950 /// See AbstractAttribute::initialize(...).
7951 void initialize(Attributor &A) override {
7952 intersectAssumedBits(BEST_STATE);
7953 getKnownStateFromValue(A, getIRPosition(), getState());
7954 AAMemoryBehavior::initialize(A);
7955 }
7956
7957 /// Return the memory behavior information encoded in the IR for \p IRP.
7958 static void getKnownStateFromValue(Attributor &A, const IRPosition &IRP,
7959 BitIntegerState &State,
7960 bool IgnoreSubsumingPositions = false) {
7962 A.getAttrs(IRP, AttrKinds, Attrs, IgnoreSubsumingPositions);
7963 for (const Attribute &Attr : Attrs) {
7964 switch (Attr.getKindAsEnum()) {
7965 case Attribute::ReadNone:
7966 State.addKnownBits(NO_ACCESSES);
7967 break;
7968 case Attribute::ReadOnly:
7969 State.addKnownBits(NO_WRITES);
7970 break;
7971 case Attribute::WriteOnly:
7972 State.addKnownBits(NO_READS);
7973 break;
7974 default:
7975 llvm_unreachable("Unexpected attribute!");
7976 }
7977 }
7978
7979 if (auto *I = dyn_cast<Instruction>(&IRP.getAnchorValue())) {
7980 if (!I->mayReadFromMemory())
7981 State.addKnownBits(NO_READS);
7982 if (!I->mayWriteToMemory())
7983 State.addKnownBits(NO_WRITES);
7984 }
7985 }
7986
7987 /// See AbstractAttribute::getDeducedAttributes(...).
7988 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
7989 SmallVectorImpl<Attribute> &Attrs) const override {
7990 assert(Attrs.size() == 0);
7991 if (isAssumedReadNone())
7992 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadNone));
7993 else if (isAssumedReadOnly())
7994 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadOnly));
7995 else if (isAssumedWriteOnly())
7996 Attrs.push_back(Attribute::get(Ctx, Attribute::WriteOnly));
7997 assert(Attrs.size() <= 1);
7998 }
7999
8000 /// See AbstractAttribute::manifest(...).
8001 ChangeStatus manifest(Attributor &A) override {
8002 const IRPosition &IRP = getIRPosition();
8003
8004 if (A.hasAttr(IRP, Attribute::ReadNone,
8005 /* IgnoreSubsumingPositions */ true))
8006 return ChangeStatus::UNCHANGED;
8007
8008 // Check if we would improve the existing attributes first.
8009 SmallVector<Attribute, 4> DeducedAttrs;
8010 getDeducedAttributes(A, IRP.getAnchorValue().getContext(), DeducedAttrs);
8011 if (llvm::all_of(DeducedAttrs, [&](const Attribute &Attr) {
8012 return A.hasAttr(IRP, Attr.getKindAsEnum(),
8013 /* IgnoreSubsumingPositions */ true);
8014 }))
8015 return ChangeStatus::UNCHANGED;
8016
8017 // Clear existing attributes.
8018 A.removeAttrs(IRP, AttrKinds);
8019 // Clear conflicting writable attribute.
8020 if (isAssumedReadOnly())
8021 A.removeAttrs(IRP, Attribute::Writable);
8022
8023 // Use the generic manifest method.
8024 return IRAttribute::manifest(A);
8025 }
8026
8027 /// See AbstractState::getAsStr().
8028 const std::string getAsStr(Attributor *A) const override {
8029 if (isAssumedReadNone())
8030 return "readnone";
8031 if (isAssumedReadOnly())
8032 return "readonly";
8033 if (isAssumedWriteOnly())
8034 return "writeonly";
8035 return "may-read/write";
8036 }
8037
8038 /// The set of IR attributes AAMemoryBehavior deals with.
8039 static const Attribute::AttrKind AttrKinds[3];
8040};
8041
8042const Attribute::AttrKind AAMemoryBehaviorImpl::AttrKinds[] = {
8043 Attribute::ReadNone, Attribute::ReadOnly, Attribute::WriteOnly};
8044
8045/// Memory behavior attribute for a floating value.
8046struct AAMemoryBehaviorFloating : AAMemoryBehaviorImpl {
8047 AAMemoryBehaviorFloating(const IRPosition &IRP, Attributor &A)
8048 : AAMemoryBehaviorImpl(IRP, A) {}
8049
8050 /// See AbstractAttribute::updateImpl(...).
8051 ChangeStatus updateImpl(Attributor &A) override;
8052
8053 /// See AbstractAttribute::trackStatistics()
8054 void trackStatistics() const override {
8055 if (isAssumedReadNone())
8057 else if (isAssumedReadOnly())
8059 else if (isAssumedWriteOnly())
8061 }
8062
8063private:
8064 /// Return true if users of \p UserI might access the underlying
8065 /// variable/location described by \p U and should therefore be analyzed.
8066 bool followUsersOfUseIn(Attributor &A, const Use &U,
8067 const Instruction *UserI);
8068
8069 /// Update the state according to the effect of use \p U in \p UserI.
8070 void analyzeUseIn(Attributor &A, const Use &U, const Instruction *UserI);
8071};
8072
8073/// Memory behavior attribute for function argument.
8074struct AAMemoryBehaviorArgument : AAMemoryBehaviorFloating {
8075 AAMemoryBehaviorArgument(const IRPosition &IRP, Attributor &A)
8076 : AAMemoryBehaviorFloating(IRP, A) {}
8077
8078 /// See AbstractAttribute::initialize(...).
8079 void initialize(Attributor &A) override {
8080 intersectAssumedBits(BEST_STATE);
8081 const IRPosition &IRP = getIRPosition();
8082 // TODO: Make IgnoreSubsumingPositions a property of an IRAttribute so we
8083 // can query it when we use has/getAttr. That would allow us to reuse the
8084 // initialize of the base class here.
8085 bool HasByVal = A.hasAttr(IRP, {Attribute::ByVal},
8086 /* IgnoreSubsumingPositions */ true);
8087 getKnownStateFromValue(A, IRP, getState(),
8088 /* IgnoreSubsumingPositions */ HasByVal);
8089 }
8090
8091 ChangeStatus manifest(Attributor &A) override {
8092 // TODO: Pointer arguments are not supported on vectors of pointers yet.
8093 if (!getAssociatedValue().getType()->isPointerTy())
8094 return ChangeStatus::UNCHANGED;
8095
8096 // TODO: From readattrs.ll: "inalloca parameters are always
8097 // considered written"
8098 if (A.hasAttr(getIRPosition(),
8099 {Attribute::InAlloca, Attribute::Preallocated})) {
8100 removeKnownBits(NO_WRITES);
8101 removeAssumedBits(NO_WRITES);
8102 }
8103 A.removeAttrs(getIRPosition(), AttrKinds);
8104 return AAMemoryBehaviorFloating::manifest(A);
8105 }
8106
8107 /// See AbstractAttribute::trackStatistics()
8108 void trackStatistics() const override {
8109 if (isAssumedReadNone())
8110 STATS_DECLTRACK_ARG_ATTR(readnone)
8111 else if (isAssumedReadOnly())
8112 STATS_DECLTRACK_ARG_ATTR(readonly)
8113 else if (isAssumedWriteOnly())
8114 STATS_DECLTRACK_ARG_ATTR(writeonly)
8115 }
8116};
8117
8118struct AAMemoryBehaviorCallSiteArgument final : AAMemoryBehaviorArgument {
8119 AAMemoryBehaviorCallSiteArgument(const IRPosition &IRP, Attributor &A)
8120 : AAMemoryBehaviorArgument(IRP, A) {}
8121
8122 /// See AbstractAttribute::initialize(...).
8123 void initialize(Attributor &A) override {
8124 // If we don't have an associated attribute this is either a variadic call
8125 // or an indirect call, either way, nothing to do here.
8126 Argument *Arg = getAssociatedArgument();
8127 if (!Arg) {
8128 indicatePessimisticFixpoint();
8129 return;
8130 }
8131 if (Arg->hasByValAttr()) {
8132 addKnownBits(NO_WRITES);
8133 removeKnownBits(NO_READS);
8134 removeAssumedBits(NO_READS);
8135 }
8136 AAMemoryBehaviorArgument::initialize(A);
8137 if (getAssociatedFunction()->isDeclaration())
8138 indicatePessimisticFixpoint();
8139 }
8140
8141 /// See AbstractAttribute::updateImpl(...).
8142 ChangeStatus updateImpl(Attributor &A) override {
8143 // TODO: Once we have call site specific value information we can provide
8144 // call site specific liveness liveness information and then it makes
8145 // sense to specialize attributes for call sites arguments instead of
8146 // redirecting requests to the callee argument.
8147 Argument *Arg = getAssociatedArgument();
8148 const IRPosition &ArgPos = IRPosition::argument(*Arg);
8149 auto *ArgAA =
8150 A.getAAFor<AAMemoryBehavior>(*this, ArgPos, DepClassTy::REQUIRED);
8151 if (!ArgAA)
8152 return indicatePessimisticFixpoint();
8153 return clampStateAndIndicateChange(getState(), ArgAA->getState());
8154 }
8155
8156 /// See AbstractAttribute::trackStatistics()
8157 void trackStatistics() const override {
8158 if (isAssumedReadNone())
8160 else if (isAssumedReadOnly())
8162 else if (isAssumedWriteOnly())
8164 }
8165};
8166
8167/// Memory behavior attribute for a call site return position.
8168struct AAMemoryBehaviorCallSiteReturned final : AAMemoryBehaviorFloating {
8169 AAMemoryBehaviorCallSiteReturned(const IRPosition &IRP, Attributor &A)
8170 : AAMemoryBehaviorFloating(IRP, A) {}
8171
8172 /// See AbstractAttribute::initialize(...).
8173 void initialize(Attributor &A) override {
8174 AAMemoryBehaviorImpl::initialize(A);
8175 }
8176 /// See AbstractAttribute::manifest(...).
8177 ChangeStatus manifest(Attributor &A) override {
8178 // We do not annotate returned values.
8179 return ChangeStatus::UNCHANGED;
8180 }
8181
8182 /// See AbstractAttribute::trackStatistics()
8183 void trackStatistics() const override {}
8184};
8185
8186/// An AA to represent the memory behavior function attributes.
8187struct AAMemoryBehaviorFunction final : public AAMemoryBehaviorImpl {
8188 AAMemoryBehaviorFunction(const IRPosition &IRP, Attributor &A)
8189 : AAMemoryBehaviorImpl(IRP, A) {}
8190
8191 /// See AbstractAttribute::updateImpl(Attributor &A).
8192 ChangeStatus updateImpl(Attributor &A) override;
8193
8194 /// See AbstractAttribute::manifest(...).
8195 ChangeStatus manifest(Attributor &A) override {
8196 // TODO: It would be better to merge this with AAMemoryLocation, so that
8197 // we could determine read/write per location. This would also have the
8198 // benefit of only one place trying to manifest the memory attribute.
8199 Function &F = cast<Function>(getAnchorValue());
8201 if (isAssumedReadNone())
8202 ME = MemoryEffects::none();
8203 else if (isAssumedReadOnly())
8205 else if (isAssumedWriteOnly())
8207
8208 A.removeAttrs(getIRPosition(), AttrKinds);
8209 // Clear conflicting writable attribute.
8210 if (ME.onlyReadsMemory())
8211 for (Argument &Arg : F.args())
8212 A.removeAttrs(IRPosition::argument(Arg), Attribute::Writable);
8213 return A.manifestAttrs(getIRPosition(),
8214 Attribute::getWithMemoryEffects(F.getContext(), ME));
8215 }
8216
8217 /// See AbstractAttribute::trackStatistics()
8218 void trackStatistics() const override {
8219 if (isAssumedReadNone())
8220 STATS_DECLTRACK_FN_ATTR(readnone)
8221 else if (isAssumedReadOnly())
8222 STATS_DECLTRACK_FN_ATTR(readonly)
8223 else if (isAssumedWriteOnly())
8224 STATS_DECLTRACK_FN_ATTR(writeonly)
8225 }
8226};
8227
8228/// AAMemoryBehavior attribute for call sites.
8229struct AAMemoryBehaviorCallSite final
8230 : AACalleeToCallSite<AAMemoryBehavior, AAMemoryBehaviorImpl> {
8231 AAMemoryBehaviorCallSite(const IRPosition &IRP, Attributor &A)
8232 : AACalleeToCallSite<AAMemoryBehavior, AAMemoryBehaviorImpl>(IRP, A) {}
8233
8234 /// See AbstractAttribute::manifest(...).
8235 ChangeStatus manifest(Attributor &A) override {
8236 // TODO: Deduplicate this with AAMemoryBehaviorFunction.
8237 CallBase &CB = cast<CallBase>(getAnchorValue());
8239 if (isAssumedReadNone())
8240 ME = MemoryEffects::none();
8241 else if (isAssumedReadOnly())
8243 else if (isAssumedWriteOnly())
8245
8246 A.removeAttrs(getIRPosition(), AttrKinds);
8247 // Clear conflicting writable attribute.
8248 if (ME.onlyReadsMemory())
8249 for (Use &U : CB.args())
8250 A.removeAttrs(IRPosition::callsite_argument(CB, U.getOperandNo()),
8251 Attribute::Writable);
8252 return A.manifestAttrs(
8253 getIRPosition(), Attribute::getWithMemoryEffects(CB.getContext(), ME));
8254 }
8255
8256 /// See AbstractAttribute::trackStatistics()
8257 void trackStatistics() const override {
8258 if (isAssumedReadNone())
8259 STATS_DECLTRACK_CS_ATTR(readnone)
8260 else if (isAssumedReadOnly())
8261 STATS_DECLTRACK_CS_ATTR(readonly)
8262 else if (isAssumedWriteOnly())
8263 STATS_DECLTRACK_CS_ATTR(writeonly)
8264 }
8265};
8266
8267ChangeStatus AAMemoryBehaviorFunction::updateImpl(Attributor &A) {
8268
8269 // The current assumed state used to determine a change.
8270 auto AssumedState = getAssumed();
8271
8272 auto CheckRWInst = [&](Instruction &I) {
8273 // If the instruction has an own memory behavior state, use it to restrict
8274 // the local state. No further analysis is required as the other memory
8275 // state is as optimistic as it gets.
8276 if (const auto *CB = dyn_cast<CallBase>(&I)) {
8277 const auto *MemBehaviorAA = A.getAAFor<AAMemoryBehavior>(
8279 if (MemBehaviorAA) {
8280 intersectAssumedBits(MemBehaviorAA->getAssumed());
8281 return !isAtFixpoint();
8282 }
8283 }
8284
8285 // Remove access kind modifiers if necessary.
8286 if (I.mayReadFromMemory())
8287 removeAssumedBits(NO_READS);
8288 if (I.mayWriteToMemory())
8289 removeAssumedBits(NO_WRITES);
8290 return !isAtFixpoint();
8291 };
8292
8293 bool UsedAssumedInformation = false;
8294 if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this,
8295 UsedAssumedInformation))
8296 return indicatePessimisticFixpoint();
8297
8298 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
8300}
8301
8302ChangeStatus AAMemoryBehaviorFloating::updateImpl(Attributor &A) {
8303
8304 const IRPosition &IRP = getIRPosition();
8305 const IRPosition &FnPos = IRPosition::function_scope(IRP);
8306 AAMemoryBehavior::StateType &S = getState();
8307
8308 // First, check the function scope. We take the known information and we avoid
8309 // work if the assumed information implies the current assumed information for
8310 // this attribute. This is a valid for all but byval arguments.
8311 Argument *Arg = IRP.getAssociatedArgument();
8312 AAMemoryBehavior::base_t FnMemAssumedState =
8314 if (!Arg || !Arg->hasByValAttr()) {
8315 const auto *FnMemAA =
8316 A.getAAFor<AAMemoryBehavior>(*this, FnPos, DepClassTy::OPTIONAL);
8317 if (FnMemAA) {
8318 FnMemAssumedState = FnMemAA->getAssumed();
8319 S.addKnownBits(FnMemAA->getKnown());
8320 if ((S.getAssumed() & FnMemAA->getAssumed()) == S.getAssumed())
8322 }
8323 }
8324
8325 // The current assumed state used to determine a change.
8326 auto AssumedState = S.getAssumed();
8327
8328 // Make sure the value is not captured (except through "return"), if
8329 // it is, any information derived would be irrelevant anyway as we cannot
8330 // check the potential aliases introduced by the capture. However, no need
8331 // to fall back to anythign less optimistic than the function state.
8332 bool IsKnownNoCapture;
8333 const AANoCapture *ArgNoCaptureAA = nullptr;
8334 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
8335 A, this, IRP, DepClassTy::OPTIONAL, IsKnownNoCapture, false,
8336 &ArgNoCaptureAA);
8337
8338 if (!IsAssumedNoCapture &&
8339 (!ArgNoCaptureAA || !ArgNoCaptureAA->isAssumedNoCaptureMaybeReturned())) {
8340 S.intersectAssumedBits(FnMemAssumedState);
8341 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
8343 }
8344
8345 // Visit and expand uses until all are analyzed or a fixpoint is reached.
8346 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
8347 Instruction *UserI = cast<Instruction>(U.getUser());
8348 LLVM_DEBUG(dbgs() << "[AAMemoryBehavior] Use: " << *U << " in " << *UserI
8349 << " \n");
8350
8351 // Droppable users, e.g., llvm::assume does not actually perform any action.
8352 if (UserI->isDroppable())
8353 return true;
8354
8355 // Check if the users of UserI should also be visited.
8356 Follow = followUsersOfUseIn(A, U, UserI);
8357
8358 // If UserI might touch memory we analyze the use in detail.
8359 if (UserI->mayReadOrWriteMemory())
8360 analyzeUseIn(A, U, UserI);
8361
8362 return !isAtFixpoint();
8363 };
8364
8365 if (!A.checkForAllUses(UsePred, *this, getAssociatedValue()))
8366 return indicatePessimisticFixpoint();
8367
8368 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
8370}
8371
8372bool AAMemoryBehaviorFloating::followUsersOfUseIn(Attributor &A, const Use &U,
8373 const Instruction *UserI) {
8374 // The loaded value is unrelated to the pointer argument, no need to
8375 // follow the users of the load.
8376 if (isa<LoadInst>(UserI) || isa<ReturnInst>(UserI))
8377 return false;
8378
8379 // By default we follow all uses assuming UserI might leak information on U,
8380 // we have special handling for call sites operands though.
8381 const auto *CB = dyn_cast<CallBase>(UserI);
8382 if (!CB || !CB->isArgOperand(&U))
8383 return true;
8384
8385 // If the use is a call argument known not to be captured, the users of
8386 // the call do not need to be visited because they have to be unrelated to
8387 // the input. Note that this check is not trivial even though we disallow
8388 // general capturing of the underlying argument. The reason is that the
8389 // call might the argument "through return", which we allow and for which we
8390 // need to check call users.
8391 if (U.get()->getType()->isPointerTy()) {
8392 unsigned ArgNo = CB->getArgOperandNo(&U);
8393 bool IsKnownNoCapture;
8395 A, this, IRPosition::callsite_argument(*CB, ArgNo),
8396 DepClassTy::OPTIONAL, IsKnownNoCapture);
8397 }
8398
8399 return true;
8400}
8401
8402void AAMemoryBehaviorFloating::analyzeUseIn(Attributor &A, const Use &U,
8403 const Instruction *UserI) {
8404 assert(UserI->mayReadOrWriteMemory());
8405
8406 switch (UserI->getOpcode()) {
8407 default:
8408 // TODO: Handle all atomics and other side-effect operations we know of.
8409 break;
8410 case Instruction::Load:
8411 // Loads cause the NO_READS property to disappear.
8412 removeAssumedBits(NO_READS);
8413 return;
8414
8415 case Instruction::Store:
8416 // Stores cause the NO_WRITES property to disappear if the use is the
8417 // pointer operand. Note that while capturing was taken care of somewhere
8418 // else we need to deal with stores of the value that is not looked through.
8419 if (cast<StoreInst>(UserI)->getPointerOperand() == U.get())
8420 removeAssumedBits(NO_WRITES);
8421 else
8422 indicatePessimisticFixpoint();
8423 return;
8424
8425 case Instruction::Call:
8426 case Instruction::CallBr:
8427 case Instruction::Invoke: {
8428 // For call sites we look at the argument memory behavior attribute (this
8429 // could be recursive!) in order to restrict our own state.
8430 const auto *CB = cast<CallBase>(UserI);
8431
8432 // Give up on operand bundles.
8433 if (CB->isBundleOperand(&U)) {
8434 indicatePessimisticFixpoint();
8435 return;
8436 }
8437
8438 // Calling a function does read the function pointer, maybe write it if the
8439 // function is self-modifying.
8440 if (CB->isCallee(&U)) {
8441 removeAssumedBits(NO_READS);
8442 break;
8443 }
8444
8445 // Adjust the possible access behavior based on the information on the
8446 // argument.
8447 IRPosition Pos;
8448 if (U.get()->getType()->isPointerTy())
8450 else
8452 const auto *MemBehaviorAA =
8453 A.getAAFor<AAMemoryBehavior>(*this, Pos, DepClassTy::OPTIONAL);
8454 if (!MemBehaviorAA)
8455 break;
8456 // "assumed" has at most the same bits as the MemBehaviorAA assumed
8457 // and at least "known".
8458 intersectAssumedBits(MemBehaviorAA->getAssumed());
8459 return;
8460 }
8461 };
8462
8463 // Generally, look at the "may-properties" and adjust the assumed state if we
8464 // did not trigger special handling before.
8465 if (UserI->mayReadFromMemory())
8466 removeAssumedBits(NO_READS);
8467 if (UserI->mayWriteToMemory())
8468 removeAssumedBits(NO_WRITES);
8469}
8470} // namespace
8471
8472/// -------------------- Memory Locations Attributes ---------------------------
8473/// Includes read-none, argmemonly, inaccessiblememonly,
8474/// inaccessiblememorargmemonly
8475/// ----------------------------------------------------------------------------
8476
8479 if (0 == (MLK & AAMemoryLocation::NO_LOCATIONS))
8480 return "all memory";
8482 return "no memory";
8483 std::string S = "memory:";
8484 if (0 == (MLK & AAMemoryLocation::NO_LOCAL_MEM))
8485 S += "stack,";
8486 if (0 == (MLK & AAMemoryLocation::NO_CONST_MEM))
8487 S += "constant,";
8489 S += "internal global,";
8491 S += "external global,";
8492 if (0 == (MLK & AAMemoryLocation::NO_ARGUMENT_MEM))
8493 S += "argument,";
8495 S += "inaccessible,";
8496 if (0 == (MLK & AAMemoryLocation::NO_MALLOCED_MEM))
8497 S += "malloced,";
8498 if (0 == (MLK & AAMemoryLocation::NO_UNKOWN_MEM))
8499 S += "unknown,";
8500 S.pop_back();
8501 return S;
8502}
8503
8504namespace {
8505struct AAMemoryLocationImpl : public AAMemoryLocation {
8506
8507 AAMemoryLocationImpl(const IRPosition &IRP, Attributor &A)
8508 : AAMemoryLocation(IRP, A), Allocator(A.Allocator) {
8509 AccessKind2Accesses.fill(nullptr);
8510 }
8511
8512 ~AAMemoryLocationImpl() override {
8513 // The AccessSets are allocated via a BumpPtrAllocator, we call
8514 // the destructor manually.
8515 for (AccessSet *AS : AccessKind2Accesses)
8516 if (AS)
8517 AS->~AccessSet();
8518 }
8519
8520 /// See AbstractAttribute::initialize(...).
8521 void initialize(Attributor &A) override {
8522 intersectAssumedBits(BEST_STATE);
8523 getKnownStateFromValue(A, getIRPosition(), getState());
8524 AAMemoryLocation::initialize(A);
8525 }
8526
8527 /// Return the memory behavior information encoded in the IR for \p IRP.
8528 static void getKnownStateFromValue(Attributor &A, const IRPosition &IRP,
8529 BitIntegerState &State,
8530 bool IgnoreSubsumingPositions = false) {
8531 // For internal functions we ignore `argmemonly` and
8532 // `inaccessiblememorargmemonly` as we might break it via interprocedural
8533 // constant propagation. It is unclear if this is the best way but it is
8534 // unlikely this will cause real performance problems. If we are deriving
8535 // attributes for the anchor function we even remove the attribute in
8536 // addition to ignoring it.
8537 // TODO: A better way to handle this would be to add ~NO_GLOBAL_MEM /
8538 // MemoryEffects::Other as a possible location.
8539 bool UseArgMemOnly = true;
8540 Function *AnchorFn = IRP.getAnchorScope();
8541 if (AnchorFn && A.isRunOn(*AnchorFn))
8542 UseArgMemOnly = !AnchorFn->hasLocalLinkage();
8543
8545 A.getAttrs(IRP, {Attribute::Memory}, Attrs, IgnoreSubsumingPositions);
8546 for (const Attribute &Attr : Attrs) {
8547 // TODO: We can map MemoryEffects to Attributor locations more precisely.
8548 MemoryEffects ME = Attr.getMemoryEffects();
8549 if (ME.doesNotAccessMemory()) {
8550 State.addKnownBits(NO_LOCAL_MEM | NO_CONST_MEM);
8551 continue;
8552 }
8553 if (ME.onlyAccessesInaccessibleMem()) {
8554 State.addKnownBits(inverseLocation(NO_INACCESSIBLE_MEM, true, true));
8555 continue;
8556 }
8557 if (ME.onlyAccessesArgPointees()) {
8558 if (UseArgMemOnly)
8559 State.addKnownBits(inverseLocation(NO_ARGUMENT_MEM, true, true));
8560 else {
8561 // Remove location information, only keep read/write info.
8562 ME = MemoryEffects(ME.getModRef());
8563 A.manifestAttrs(IRP,
8564 Attribute::getWithMemoryEffects(
8565 IRP.getAnchorValue().getContext(), ME),
8566 /*ForceReplace*/ true);
8567 }
8568 continue;
8569 }
8571 if (UseArgMemOnly)
8572 State.addKnownBits(inverseLocation(
8573 NO_INACCESSIBLE_MEM | NO_ARGUMENT_MEM, true, true));
8574 else {
8575 // Remove location information, only keep read/write info.
8576 ME = MemoryEffects(ME.getModRef());
8577 A.manifestAttrs(IRP,
8578 Attribute::getWithMemoryEffects(
8579 IRP.getAnchorValue().getContext(), ME),
8580 /*ForceReplace*/ true);
8581 }
8582 continue;
8583 }
8584 }
8585 }
8586
8587 /// See AbstractAttribute::getDeducedAttributes(...).
8588 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
8589 SmallVectorImpl<Attribute> &Attrs) const override {
8590 // TODO: We can map Attributor locations to MemoryEffects more precisely.
8591 assert(Attrs.size() == 0);
8592 if (getIRPosition().getPositionKind() == IRPosition::IRP_FUNCTION) {
8593 if (isAssumedReadNone())
8594 Attrs.push_back(
8595 Attribute::getWithMemoryEffects(Ctx, MemoryEffects::none()));
8596 else if (isAssumedInaccessibleMemOnly())
8597 Attrs.push_back(Attribute::getWithMemoryEffects(
8599 else if (isAssumedArgMemOnly())
8600 Attrs.push_back(
8601 Attribute::getWithMemoryEffects(Ctx, MemoryEffects::argMemOnly()));
8602 else if (isAssumedInaccessibleOrArgMemOnly())
8603 Attrs.push_back(Attribute::getWithMemoryEffects(
8605 }
8606 assert(Attrs.size() <= 1);
8607 }
8608
8609 /// See AbstractAttribute::manifest(...).
8610 ChangeStatus manifest(Attributor &A) override {
8611 // TODO: If AAMemoryLocation and AAMemoryBehavior are merged, we could
8612 // provide per-location modref information here.
8613 const IRPosition &IRP = getIRPosition();
8614
8615 SmallVector<Attribute, 1> DeducedAttrs;
8616 getDeducedAttributes(A, IRP.getAnchorValue().getContext(), DeducedAttrs);
8617 if (DeducedAttrs.size() != 1)
8618 return ChangeStatus::UNCHANGED;
8619 MemoryEffects ME = DeducedAttrs[0].getMemoryEffects();
8620
8621 return A.manifestAttrs(IRP, Attribute::getWithMemoryEffects(
8622 IRP.getAnchorValue().getContext(), ME));
8623 }
8624
8625 /// See AAMemoryLocation::checkForAllAccessesToMemoryKind(...).
8626 bool checkForAllAccessesToMemoryKind(
8627 function_ref<bool(const Instruction *, const Value *, AccessKind,
8628 MemoryLocationsKind)>
8629 Pred,
8630 MemoryLocationsKind RequestedMLK) const override {
8631 if (!isValidState())
8632 return false;
8633
8634 MemoryLocationsKind AssumedMLK = getAssumedNotAccessedLocation();
8635 if (AssumedMLK == NO_LOCATIONS)
8636 return true;
8637
8638 unsigned Idx = 0;
8639 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS;
8640 CurMLK *= 2, ++Idx) {
8641 if (CurMLK & RequestedMLK)
8642 continue;
8643
8644 if (const AccessSet *Accesses = AccessKind2Accesses[Idx])
8645 for (const AccessInfo &AI : *Accesses)
8646 if (!Pred(AI.I, AI.Ptr, AI.Kind, CurMLK))
8647 return false;
8648 }
8649
8650 return true;
8651 }
8652
8653 ChangeStatus indicatePessimisticFixpoint() override {
8654 // If we give up and indicate a pessimistic fixpoint this instruction will
8655 // become an access for all potential access kinds:
8656 // TODO: Add pointers for argmemonly and globals to improve the results of
8657 // checkForAllAccessesToMemoryKind.
8658 bool Changed = false;
8659 MemoryLocationsKind KnownMLK = getKnown();
8660 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
8661 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS; CurMLK *= 2)
8662 if (!(CurMLK & KnownMLK))
8663 updateStateAndAccessesMap(getState(), CurMLK, I, nullptr, Changed,
8664 getAccessKindFromInst(I));
8665 return AAMemoryLocation::indicatePessimisticFixpoint();
8666 }
8667
8668protected:
8669 /// Helper struct to tie together an instruction that has a read or write
8670 /// effect with the pointer it accesses (if any).
8671 struct AccessInfo {
8672
8673 /// The instruction that caused the access.
8674 const Instruction *I;
8675
8676 /// The base pointer that is accessed, or null if unknown.
8677 const Value *Ptr;
8678
8679 /// The kind of access (read/write/read+write).
8681
8682 bool operator==(const AccessInfo &RHS) const {
8683 return I == RHS.I && Ptr == RHS.Ptr && Kind == RHS.Kind;
8684 }
8685 bool operator()(const AccessInfo &LHS, const AccessInfo &RHS) const {
8686 if (LHS.I != RHS.I)
8687 return LHS.I < RHS.I;
8688 if (LHS.Ptr != RHS.Ptr)
8689 return LHS.Ptr < RHS.Ptr;
8690 if (LHS.Kind != RHS.Kind)
8691 return LHS.Kind < RHS.Kind;
8692 return false;
8693 }
8694 };
8695
8696 /// Mapping from *single* memory location kinds, e.g., LOCAL_MEM with the
8697 /// value of NO_LOCAL_MEM, to the accesses encountered for this memory kind.
8698 using AccessSet = SmallSet<AccessInfo, 2, AccessInfo>;
8699 std::array<AccessSet *, llvm::ConstantLog2<VALID_STATE>()>
8700 AccessKind2Accesses;
8701
8702 /// Categorize the pointer arguments of CB that might access memory in
8703 /// AccessedLoc and update the state and access map accordingly.
8704 void
8705 categorizeArgumentPointerLocations(Attributor &A, CallBase &CB,
8706 AAMemoryLocation::StateType &AccessedLocs,
8707 bool &Changed);
8708
8709 /// Return the kind(s) of location that may be accessed by \p V.
8711 categorizeAccessedLocations(Attributor &A, Instruction &I, bool &Changed);
8712
8713 /// Return the access kind as determined by \p I.
8714 AccessKind getAccessKindFromInst(const Instruction *I) {
8715 AccessKind AK = READ_WRITE;
8716 if (I) {
8717 AK = I->mayReadFromMemory() ? READ : NONE;
8718 AK = AccessKind(AK | (I->mayWriteToMemory() ? WRITE : NONE));
8719 }
8720 return AK;
8721 }
8722
8723 /// Update the state \p State and the AccessKind2Accesses given that \p I is
8724 /// an access of kind \p AK to a \p MLK memory location with the access
8725 /// pointer \p Ptr.
8726 void updateStateAndAccessesMap(AAMemoryLocation::StateType &State,
8727 MemoryLocationsKind MLK, const Instruction *I,
8728 const Value *Ptr, bool &Changed,
8729 AccessKind AK = READ_WRITE) {
8730
8731 assert(isPowerOf2_32(MLK) && "Expected a single location set!");
8732 auto *&Accesses = AccessKind2Accesses[llvm::Log2_32(MLK)];
8733 if (!Accesses)
8734 Accesses = new (Allocator) AccessSet();
8735 Changed |= Accesses->insert(AccessInfo{I, Ptr, AK}).second;
8736 if (MLK == NO_UNKOWN_MEM)
8737 MLK = NO_LOCATIONS;
8738 State.removeAssumedBits(MLK);
8739 }
8740
8741 /// Determine the underlying locations kinds for \p Ptr, e.g., globals or
8742 /// arguments, and update the state and access map accordingly.
8743 void categorizePtrValue(Attributor &A, const Instruction &I, const Value &Ptr,
8744 AAMemoryLocation::StateType &State, bool &Changed,
8745 unsigned AccessAS = 0);
8746
8747 /// Used to allocate access sets.
8749};
8750
8751void AAMemoryLocationImpl::categorizePtrValue(
8752 Attributor &A, const Instruction &I, const Value &Ptr,
8753 AAMemoryLocation::StateType &State, bool &Changed, unsigned AccessAS) {
8754 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize pointer locations for "
8755 << Ptr << " ["
8756 << getMemoryLocationsAsStr(State.getAssumed()) << "]\n");
8757
8758 auto Pred = [&](Value &Obj) {
8759 unsigned ObjectAS = Obj.getType()->getPointerAddressSpace();
8760 // TODO: recognize the TBAA used for constant accesses.
8761 MemoryLocationsKind MLK = NO_LOCATIONS;
8762
8763 // Filter accesses to constant (GPU) memory if we have an AS at the access
8764 // site or the object is known to actually have the associated AS.
8765 if (AA::isGPU(A.getModule())) {
8766 if (AA::isGPUConstantAddressSpace(A.getModule(), AccessAS) ||
8767 (AA::isGPUConstantAddressSpace(A.getModule(), ObjectAS) &&
8768 isIdentifiedObject(&Obj)))
8769 return true;
8770 }
8771
8772 if (isa<UndefValue>(&Obj))
8773 return true;
8774 if (isa<Argument>(&Obj)) {
8775 // TODO: For now we do not treat byval arguments as local copies performed
8776 // on the call edge, though, we should. To make that happen we need to
8777 // teach various passes, e.g., DSE, about the copy effect of a byval. That
8778 // would also allow us to mark functions only accessing byval arguments as
8779 // readnone again, arguably their accesses have no effect outside of the
8780 // function, like accesses to allocas.
8781 MLK = NO_ARGUMENT_MEM;
8782 } else if (auto *GV = dyn_cast<GlobalValue>(&Obj)) {
8783 // Reading constant memory is not treated as a read "effect" by the
8784 // function attr pass so we won't neither. Constants defined by TBAA are
8785 // similar. (We know we do not write it because it is constant.)
8786 if (auto *GVar = dyn_cast<GlobalVariable>(GV))
8787 if (GVar->isConstant())
8788 return true;
8789
8790 if (GV->hasLocalLinkage())
8791 MLK = NO_GLOBAL_INTERNAL_MEM;
8792 else
8793 MLK = NO_GLOBAL_EXTERNAL_MEM;
8794 } else if (isa<ConstantPointerNull>(&Obj) && ObjectAS == AccessAS &&
8795 !NullPointerIsDefined(getAssociatedFunction(), AccessAS)) {
8796 // Accessing null is undefined, but not accessing a null pointer cast to
8797 // another address space, which may be a valid address there.
8798 return true;
8799 } else if (isa<AllocaInst>(&Obj)) {
8800 MLK = NO_LOCAL_MEM;
8801 } else if (const auto *CB = dyn_cast<CallBase>(&Obj)) {
8802 bool IsKnownNoAlias;
8805 IsKnownNoAlias))
8806 MLK = NO_MALLOCED_MEM;
8807 else
8808 MLK = NO_UNKOWN_MEM;
8809 } else {
8810 MLK = NO_UNKOWN_MEM;
8811 }
8812
8813 assert(MLK != NO_LOCATIONS && "No location specified!");
8814 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Ptr value can be categorized: "
8815 << Obj << " -> " << getMemoryLocationsAsStr(MLK) << "\n");
8816 updateStateAndAccessesMap(State, MLK, &I, &Obj, Changed,
8817 getAccessKindFromInst(&I));
8818
8819 return true;
8820 };
8821
8822 const auto *AA = A.getAAFor<AAUnderlyingObjects>(
8824 if (!AA || !AA->forallUnderlyingObjects(Pred, AA::Intraprocedural)) {
8825 LLVM_DEBUG(
8826 dbgs() << "[AAMemoryLocation] Pointer locations not categorized\n");
8827 updateStateAndAccessesMap(State, NO_UNKOWN_MEM, &I, nullptr, Changed,
8828 getAccessKindFromInst(&I));
8829 return;
8830 }
8831
8832 LLVM_DEBUG(
8833 dbgs() << "[AAMemoryLocation] Accessed locations with pointer locations: "
8834 << getMemoryLocationsAsStr(State.getAssumed()) << "\n");
8835}
8836
8837void AAMemoryLocationImpl::categorizeArgumentPointerLocations(
8838 Attributor &A, CallBase &CB, AAMemoryLocation::StateType &AccessedLocs,
8839 bool &Changed) {
8840 for (unsigned ArgNo = 0, E = CB.arg_size(); ArgNo < E; ++ArgNo) {
8841
8842 // Skip non-pointer arguments.
8843 const Value *ArgOp = CB.getArgOperand(ArgNo);
8844 if (!ArgOp->getType()->isPtrOrPtrVectorTy())
8845 continue;
8846
8847 // Skip readnone arguments.
8848 const IRPosition &ArgOpIRP = IRPosition::callsite_argument(CB, ArgNo);
8849 const auto *ArgOpMemLocationAA =
8850 A.getAAFor<AAMemoryBehavior>(*this, ArgOpIRP, DepClassTy::OPTIONAL);
8851
8852 if (ArgOpMemLocationAA && ArgOpMemLocationAA->isAssumedReadNone())
8853 continue;
8854
8855 // Categorize potentially accessed pointer arguments as if there was an
8856 // access instruction with them as pointer.
8857 categorizePtrValue(A, CB, *ArgOp, AccessedLocs, Changed);
8858 }
8859}
8860
8862AAMemoryLocationImpl::categorizeAccessedLocations(Attributor &A, Instruction &I,
8863 bool &Changed) {
8864 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize accessed locations for "
8865 << I << "\n");
8866
8867 AAMemoryLocation::StateType AccessedLocs;
8868 AccessedLocs.intersectAssumedBits(NO_LOCATIONS);
8869
8870 if (auto *CB = dyn_cast<CallBase>(&I)) {
8871
8872 // First check if we assume any memory is access is visible.
8873 const auto *CBMemLocationAA = A.getAAFor<AAMemoryLocation>(
8875 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize call site: " << I
8876 << " [" << CBMemLocationAA << "]\n");
8877 if (!CBMemLocationAA) {
8878 updateStateAndAccessesMap(AccessedLocs, NO_UNKOWN_MEM, &I, nullptr,
8879 Changed, getAccessKindFromInst(&I));
8880 return NO_UNKOWN_MEM;
8881 }
8882
8883 if (CBMemLocationAA->isAssumedReadNone())
8884 return NO_LOCATIONS;
8885
8886 if (CBMemLocationAA->isAssumedInaccessibleMemOnly()) {
8887 updateStateAndAccessesMap(AccessedLocs, NO_INACCESSIBLE_MEM, &I, nullptr,
8888 Changed, getAccessKindFromInst(&I));
8889 return AccessedLocs.getAssumed();
8890 }
8891
8892 uint32_t CBAssumedNotAccessedLocs =
8893 CBMemLocationAA->getAssumedNotAccessedLocation();
8894
8895 // Set the argmemonly and global bit as we handle them separately below.
8896 uint32_t CBAssumedNotAccessedLocsNoArgMem =
8897 CBAssumedNotAccessedLocs | NO_ARGUMENT_MEM | NO_GLOBAL_MEM;
8898
8899 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS; CurMLK *= 2) {
8900 if (CBAssumedNotAccessedLocsNoArgMem & CurMLK)
8901 continue;
8902 updateStateAndAccessesMap(AccessedLocs, CurMLK, &I, nullptr, Changed,
8903 getAccessKindFromInst(&I));
8904 }
8905
8906 // Now handle global memory if it might be accessed. This is slightly tricky
8907 // as NO_GLOBAL_MEM has multiple bits set.
8908 bool HasGlobalAccesses = ((~CBAssumedNotAccessedLocs) & NO_GLOBAL_MEM);
8909 if (HasGlobalAccesses) {
8910 auto AccessPred = [&](const Instruction *, const Value *Ptr,
8911 AccessKind Kind, MemoryLocationsKind MLK) {
8912 updateStateAndAccessesMap(AccessedLocs, MLK, &I, Ptr, Changed,
8913 getAccessKindFromInst(&I));
8914 return true;
8915 };
8916 if (!CBMemLocationAA->checkForAllAccessesToMemoryKind(
8917 AccessPred, inverseLocation(NO_GLOBAL_MEM, false, false)))
8918 return AccessedLocs.getWorstState();
8919 }
8920
8921 LLVM_DEBUG(
8922 dbgs() << "[AAMemoryLocation] Accessed state before argument handling: "
8923 << getMemoryLocationsAsStr(AccessedLocs.getAssumed()) << "\n");
8924
8925 // Now handle argument memory if it might be accessed.
8926 bool HasArgAccesses = ((~CBAssumedNotAccessedLocs) & NO_ARGUMENT_MEM);
8927 if (HasArgAccesses)
8928 categorizeArgumentPointerLocations(A, *CB, AccessedLocs, Changed);
8929
8930 LLVM_DEBUG(
8931 dbgs() << "[AAMemoryLocation] Accessed state after argument handling: "
8932 << getMemoryLocationsAsStr(AccessedLocs.getAssumed()) << "\n");
8933
8934 return AccessedLocs.getAssumed();
8935 }
8936
8937 if (const Value *Ptr = getPointerOperand(&I, /* AllowVolatile */ true)) {
8938 LLVM_DEBUG(
8939 dbgs() << "[AAMemoryLocation] Categorize memory access with pointer: "
8940 << I << " [" << *Ptr << "]\n");
8941 categorizePtrValue(A, I, *Ptr, AccessedLocs, Changed,
8942 Ptr->getType()->getPointerAddressSpace());
8943 return AccessedLocs.getAssumed();
8944 }
8945
8946 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Failed to categorize instruction: "
8947 << I << "\n");
8948 updateStateAndAccessesMap(AccessedLocs, NO_UNKOWN_MEM, &I, nullptr, Changed,
8949 getAccessKindFromInst(&I));
8950 return AccessedLocs.getAssumed();
8951}
8952
8953/// An AA to represent the memory behavior function attributes.
8954struct AAMemoryLocationFunction final : public AAMemoryLocationImpl {
8955 AAMemoryLocationFunction(const IRPosition &IRP, Attributor &A)
8956 : AAMemoryLocationImpl(IRP, A) {}
8957
8958 /// See AbstractAttribute::updateImpl(Attributor &A).
8959 ChangeStatus updateImpl(Attributor &A) override {
8960
8961 const auto *MemBehaviorAA =
8962 A.getAAFor<AAMemoryBehavior>(*this, getIRPosition(), DepClassTy::NONE);
8963 if (MemBehaviorAA && MemBehaviorAA->isAssumedReadNone()) {
8964 if (MemBehaviorAA->isKnownReadNone())
8965 return indicateOptimisticFixpoint();
8967 "AAMemoryLocation was not read-none but AAMemoryBehavior was!");
8968 A.recordDependence(*MemBehaviorAA, *this, DepClassTy::OPTIONAL);
8969 return ChangeStatus::UNCHANGED;
8970 }
8971
8972 // The current assumed state used to determine a change.
8973 auto AssumedState = getAssumed();
8974 bool Changed = false;
8975
8976 auto CheckRWInst = [&](Instruction &I) {
8977 MemoryLocationsKind MLK = categorizeAccessedLocations(A, I, Changed);
8978 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Accessed locations for " << I
8979 << ": " << getMemoryLocationsAsStr(MLK) << "\n");
8980 removeAssumedBits(inverseLocation(MLK, false, false));
8981 // Stop once only the valid bit set in the *not assumed location*, thus
8982 // once we don't actually exclude any memory locations in the state.
8983 return getAssumedNotAccessedLocation() != VALID_STATE;
8984 };
8985
8986 bool UsedAssumedInformation = false;
8987 if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this,
8988 UsedAssumedInformation))
8989 return indicatePessimisticFixpoint();
8990
8991 Changed |= AssumedState != getAssumed();
8992 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
8993 }
8994
8995 /// See AbstractAttribute::trackStatistics()
8996 void trackStatistics() const override {
8997 if (isAssumedReadNone())
8998 STATS_DECLTRACK_FN_ATTR(readnone)
8999 else if (isAssumedArgMemOnly())
9000 STATS_DECLTRACK_FN_ATTR(argmemonly)
9001 else if (isAssumedInaccessibleMemOnly())
9002 STATS_DECLTRACK_FN_ATTR(inaccessiblememonly)
9003 else if (isAssumedInaccessibleOrArgMemOnly())
9004 STATS_DECLTRACK_FN_ATTR(inaccessiblememorargmemonly)
9005 }
9006};
9007
9008/// AAMemoryLocation attribute for call sites.
9009struct AAMemoryLocationCallSite final : AAMemoryLocationImpl {
9010 AAMemoryLocationCallSite(const IRPosition &IRP, Attributor &A)
9011 : AAMemoryLocationImpl(IRP, A) {}
9012
9013 /// See AbstractAttribute::updateImpl(...).
9014 ChangeStatus updateImpl(Attributor &A) override {
9015 // TODO: Once we have call site specific value information we can provide
9016 // call site specific liveness liveness information and then it makes
9017 // sense to specialize attributes for call sites arguments instead of
9018 // redirecting requests to the callee argument.
9019 Function *F = getAssociatedFunction();
9020 const IRPosition &FnPos = IRPosition::function(*F);
9021 auto *FnAA =
9022 A.getAAFor<AAMemoryLocation>(*this, FnPos, DepClassTy::REQUIRED);
9023 if (!FnAA)
9024 return indicatePessimisticFixpoint();
9025 bool Changed = false;
9026 auto AccessPred = [&](const Instruction *I, const Value *Ptr,
9027 AccessKind Kind, MemoryLocationsKind MLK) {
9028 updateStateAndAccessesMap(getState(), MLK, I, Ptr, Changed,
9029 getAccessKindFromInst(I));
9030 return true;
9031 };
9032 if (!FnAA->checkForAllAccessesToMemoryKind(AccessPred, ALL_LOCATIONS))
9033 return indicatePessimisticFixpoint();
9034 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
9035 }
9036
9037 /// See AbstractAttribute::trackStatistics()
9038 void trackStatistics() const override {
9039 if (isAssumedReadNone())
9040 STATS_DECLTRACK_CS_ATTR(readnone)
9041 }
9042};
9043} // namespace
9044
9045/// ------------------ denormal-fp-math Attribute -------------------------
9046
9047namespace {
9048struct AADenormalFPMathImpl : public AADenormalFPMath {
9049 AADenormalFPMathImpl(const IRPosition &IRP, Attributor &A)
9050 : AADenormalFPMath(IRP, A) {}
9051
9052 const std::string getAsStr(Attributor *A) const override {
9053 std::string Str("AADenormalFPMath[");
9054 raw_string_ostream OS(Str);
9055
9056 DenormalState Known = getKnown();
9057 if (Known.Mode.isValid())
9058 OS << "denormal-fp-math=" << Known.Mode;
9059 else
9060 OS << "invalid";
9061
9062 if (Known.ModeF32.isValid())
9063 OS << " denormal-fp-math-f32=" << Known.ModeF32;
9064 OS << ']';
9065 return Str;
9066 }
9067};
9068
9069struct AADenormalFPMathFunction final : AADenormalFPMathImpl {
9070 AADenormalFPMathFunction(const IRPosition &IRP, Attributor &A)
9071 : AADenormalFPMathImpl(IRP, A) {}
9072
9073 void initialize(Attributor &A) override {
9074 const Function *F = getAnchorScope();
9075 DenormalFPEnv DenormEnv = F->getDenormalFPEnv();
9076
9077 Known = DenormalState{DenormEnv.DefaultMode, DenormEnv.F32Mode};
9078 if (isModeFixed())
9079 indicateFixpoint();
9080 }
9081
9082 ChangeStatus updateImpl(Attributor &A) override {
9083 ChangeStatus Change = ChangeStatus::UNCHANGED;
9084
9085 auto CheckCallSite = [=, &Change, &A](AbstractCallSite CS) {
9086 Function *Caller = CS.getInstruction()->getFunction();
9087 LLVM_DEBUG(dbgs() << "[AADenormalFPMath] Call " << Caller->getName()
9088 << "->" << getAssociatedFunction()->getName() << '\n');
9089
9090 const auto *CallerInfo = A.getAAFor<AADenormalFPMath>(
9091 *this, IRPosition::function(*Caller), DepClassTy::REQUIRED);
9092 if (!CallerInfo)
9093 return false;
9094
9095 Change = Change | clampStateAndIndicateChange(this->getState(),
9096 CallerInfo->getState());
9097 return true;
9098 };
9099
9100 bool AllCallSitesKnown = true;
9101 if (!A.checkForAllCallSites(CheckCallSite, *this, true, AllCallSitesKnown))
9102 return indicatePessimisticFixpoint();
9103
9104 if (Change == ChangeStatus::CHANGED && isModeFixed())
9105 indicateFixpoint();
9106 return Change;
9107 }
9108
9109 ChangeStatus manifest(Attributor &A) override {
9110 LLVMContext &Ctx = getAssociatedFunction()->getContext();
9111
9112 SmallVector<Attribute, 2> AttrToAdd;
9114
9115 // TODO: Change to use DenormalFPEnv everywhere.
9116 DenormalFPEnv KnownEnv(Known.Mode, Known.ModeF32);
9117
9118 if (KnownEnv == DenormalFPEnv::getDefault()) {
9119 AttrToRemove.push_back(Attribute::DenormalFPEnv);
9120 } else {
9121 AttrToAdd.push_back(Attribute::get(
9122 Ctx, Attribute::DenormalFPEnv,
9123 DenormalFPEnv(Known.Mode, Known.ModeF32).toIntValue()));
9124 }
9125
9126 auto &IRP = getIRPosition();
9127
9128 // TODO: There should be a combined add and remove API.
9129 return A.removeAttrs(IRP, AttrToRemove) |
9130 A.manifestAttrs(IRP, AttrToAdd, /*ForceReplace=*/true);
9131 }
9132
9133 void trackStatistics() const override {
9134 STATS_DECLTRACK_FN_ATTR(denormal_fpenv)
9135 }
9136};
9137} // namespace
9138
9139/// ------------------ Value Constant Range Attribute -------------------------
9140
9141namespace {
9142struct AAValueConstantRangeImpl : AAValueConstantRange {
9143 using StateType = IntegerRangeState;
9144 AAValueConstantRangeImpl(const IRPosition &IRP, Attributor &A)
9145 : AAValueConstantRange(IRP, A) {}
9146
9147 /// See AbstractAttribute::initialize(..).
9148 void initialize(Attributor &A) override {
9149 if (A.hasSimplificationCallback(getIRPosition())) {
9150 indicatePessimisticFixpoint();
9151 return;
9152 }
9153
9154 // Intersect a range given by SCEV.
9155 intersectKnown(getConstantRangeFromSCEV(A, getCtxI()));
9156
9157 // Intersect a range given by LVI.
9158 intersectKnown(getConstantRangeFromLVI(A, getCtxI()));
9159 }
9160
9161 /// See AbstractAttribute::getAsStr().
9162 const std::string getAsStr(Attributor *A) const override {
9163 std::string Str;
9164 llvm::raw_string_ostream OS(Str);
9165 OS << "range(" << getBitWidth() << ")<";
9166 getKnown().print(OS);
9167 OS << " / ";
9168 getAssumed().print(OS);
9169 OS << ">";
9170 return Str;
9171 }
9172
9173 /// Helper function to get a SCEV expr for the associated value at program
9174 /// point \p I.
9175 const SCEV *getSCEV(Attributor &A, const Instruction *I = nullptr) const {
9176 if (!getAnchorScope())
9177 return nullptr;
9178
9179 ScalarEvolution *SE =
9180 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(
9181 *getAnchorScope());
9182
9183 LoopInfo *LI = A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(
9184 *getAnchorScope());
9185
9186 if (!SE || !LI)
9187 return nullptr;
9188
9189 const SCEV *S = SE->getSCEV(&getAssociatedValue());
9190 if (!I)
9191 return S;
9192
9193 return SE->getSCEVAtScope(S, LI->getLoopFor(I->getParent()));
9194 }
9195
9196 /// Helper function to get a range from SCEV for the associated value at
9197 /// program point \p I.
9198 ConstantRange getConstantRangeFromSCEV(Attributor &A,
9199 const Instruction *I = nullptr) const {
9200 if (!getAnchorScope())
9201 return getWorstState(getBitWidth());
9202
9203 ScalarEvolution *SE =
9204 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(
9205 *getAnchorScope());
9206
9207 const SCEV *S = getSCEV(A, I);
9208 if (!SE || !S)
9209 return getWorstState(getBitWidth());
9210
9211 return SE->getUnsignedRange(S);
9212 }
9213
9214 /// Helper function to get a range from LVI for the associated value at
9215 /// program point \p I.
9216 ConstantRange
9217 getConstantRangeFromLVI(Attributor &A,
9218 const Instruction *CtxI = nullptr) const {
9219 if (!getAnchorScope())
9220 return getWorstState(getBitWidth());
9221
9222 LazyValueInfo *LVI =
9223 A.getInfoCache().getAnalysisResultForFunction<LazyValueAnalysis>(
9224 *getAnchorScope());
9225
9226 if (!LVI || !CtxI)
9227 return getWorstState(getBitWidth());
9228 return LVI->getConstantRange(&getAssociatedValue(),
9229 const_cast<Instruction *>(CtxI),
9230 /*UndefAllowed*/ false);
9231 }
9232
9233 /// Return true if \p CtxI is valid for querying outside analyses.
9234 /// This basically makes sure we do not ask intra-procedural analysis
9235 /// about a context in the wrong function or a context that violates
9236 /// dominance assumptions they might have. The \p AllowAACtxI flag indicates
9237 /// if the original context of this AA is OK or should be considered invalid.
9238 bool isValidCtxInstructionForOutsideAnalysis(Attributor &A,
9239 const Instruction *CtxI,
9240 bool AllowAACtxI) const {
9241 if (!CtxI || (!AllowAACtxI && CtxI == getCtxI()))
9242 return false;
9243
9244 // Our context might be in a different function, neither intra-procedural
9245 // analysis (ScalarEvolution nor LazyValueInfo) can handle that.
9246 if (!AA::isValidInScope(getAssociatedValue(), CtxI->getFunction()))
9247 return false;
9248
9249 // If the context is not dominated by the value there are paths to the
9250 // context that do not define the value. This cannot be handled by
9251 // LazyValueInfo so we need to bail.
9252 if (auto *I = dyn_cast<Instruction>(&getAssociatedValue())) {
9253 InformationCache &InfoCache = A.getInfoCache();
9254 const DominatorTree *DT =
9255 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(
9256 *I->getFunction());
9257 return DT && DT->dominates(I, CtxI);
9258 }
9259
9260 return true;
9261 }
9262
9263 /// See AAValueConstantRange::getAssumedConstantRange(..).
9264 ConstantRange
9265 getAssumedConstantRange(Attributor &A,
9266 const Instruction *CtxI = nullptr) const override {
9267 // TODO: Make SCEV use Attributor assumption.
9268 // We may be able to bound a variable range via assumptions in
9269 // Attributor. ex.) If x is assumed to be in [1, 3] and y is known to
9270 // evolve to x^2 + x, then we can say that y is in [2, 12].
9271 if (!isValidCtxInstructionForOutsideAnalysis(A, CtxI,
9272 /* AllowAACtxI */ false))
9273 return getAssumed();
9274
9275 ConstantRange LVIR = getConstantRangeFromLVI(A, CtxI);
9276 ConstantRange SCEVR = getConstantRangeFromSCEV(A, CtxI);
9277 return getAssumed().intersectWith(SCEVR).intersectWith(LVIR);
9278 }
9279
9280 /// Helper function to create MDNode for range metadata.
9281 static MDNode *
9282 getMDNodeForConstantRange(Type *Ty, LLVMContext &Ctx,
9283 const ConstantRange &AssumedConstantRange) {
9284 Metadata *LowAndHigh[] = {ConstantAsMetadata::get(ConstantInt::get(
9285 Ty, AssumedConstantRange.getLower())),
9286 ConstantAsMetadata::get(ConstantInt::get(
9287 Ty, AssumedConstantRange.getUpper()))};
9288 return MDNode::get(Ctx, LowAndHigh);
9289 }
9290
9291 /// Return true if \p Assumed is included in ranges from instruction \p I.
9292 static bool isBetterRange(const ConstantRange &Assumed,
9293 const Instruction &I) {
9294 if (Assumed.isFullSet())
9295 return false;
9296
9297 std::optional<ConstantRange> Known;
9298
9299 if (const auto *CB = dyn_cast<CallBase>(&I)) {
9300 Known = CB->getRange();
9301 } else if (MDNode *KnownRanges = I.getMetadata(LLVMContext::MD_range)) {
9302 // If multiple ranges are annotated in IR, we give up to annotate assumed
9303 // range for now.
9304
9305 // TODO: If there exists a known range which containts assumed range, we
9306 // can say assumed range is better.
9307 if (KnownRanges->getNumOperands() > 2)
9308 return false;
9309
9310 ConstantInt *Lower =
9311 mdconst::extract<ConstantInt>(KnownRanges->getOperand(0));
9312 ConstantInt *Upper =
9313 mdconst::extract<ConstantInt>(KnownRanges->getOperand(1));
9314
9315 Known.emplace(Lower->getValue(), Upper->getValue());
9316 }
9317 return !Known || (*Known != Assumed && Known->contains(Assumed));
9318 }
9319
9320 /// Helper function to set range metadata.
9321 static bool
9322 setRangeMetadataIfisBetterRange(Instruction *I,
9323 const ConstantRange &AssumedConstantRange) {
9324 if (isBetterRange(AssumedConstantRange, *I)) {
9325 I->setMetadata(LLVMContext::MD_range,
9326 getMDNodeForConstantRange(I->getType(), I->getContext(),
9327 AssumedConstantRange));
9328 return true;
9329 }
9330 return false;
9331 }
9332 /// Helper function to set range return attribute.
9333 static bool
9334 setRangeRetAttrIfisBetterRange(Attributor &A, const IRPosition &IRP,
9335 Instruction *I,
9336 const ConstantRange &AssumedConstantRange) {
9337 if (isBetterRange(AssumedConstantRange, *I)) {
9338 A.manifestAttrs(IRP,
9339 Attribute::get(I->getContext(), Attribute::Range,
9340 AssumedConstantRange),
9341 /*ForceReplace*/ true);
9342 return true;
9343 }
9344 return false;
9345 }
9346
9347 /// See AbstractAttribute::manifest()
9348 ChangeStatus manifest(Attributor &A) override {
9349 ChangeStatus Changed = ChangeStatus::UNCHANGED;
9350 ConstantRange AssumedConstantRange = getAssumedConstantRange(A);
9351 assert(!AssumedConstantRange.isFullSet() && "Invalid state");
9352
9353 auto &V = getAssociatedValue();
9354 if (!AssumedConstantRange.isEmptySet() &&
9355 !AssumedConstantRange.isSingleElement()) {
9356 if (Instruction *I = dyn_cast<Instruction>(&V)) {
9357 assert(I == getCtxI() && "Should not annotate an instruction which is "
9358 "not the context instruction");
9359 if (isa<LoadInst>(I))
9360 if (setRangeMetadataIfisBetterRange(I, AssumedConstantRange))
9361 Changed = ChangeStatus::CHANGED;
9362 if (isa<CallInst>(I))
9363 if (setRangeRetAttrIfisBetterRange(A, getIRPosition(), I,
9364 AssumedConstantRange))
9365 Changed = ChangeStatus::CHANGED;
9366 }
9367 }
9368
9369 return Changed;
9370 }
9371};
9372
9373struct AAValueConstantRangeArgument final
9374 : AAArgumentFromCallSiteArguments<
9375 AAValueConstantRange, AAValueConstantRangeImpl, IntegerRangeState,
9376 true /* BridgeCallBaseContext */> {
9377 using Base = AAArgumentFromCallSiteArguments<
9378 AAValueConstantRange, AAValueConstantRangeImpl, IntegerRangeState,
9379 true /* BridgeCallBaseContext */>;
9380 AAValueConstantRangeArgument(const IRPosition &IRP, Attributor &A)
9381 : Base(IRP, A) {}
9382
9383 /// See AbstractAttribute::trackStatistics()
9384 void trackStatistics() const override {
9385 STATS_DECLTRACK_ARG_ATTR(value_range)
9386 }
9387};
9388
9389struct AAValueConstantRangeReturned
9390 : AAReturnedFromReturnedValues<AAValueConstantRange,
9391 AAValueConstantRangeImpl,
9392 AAValueConstantRangeImpl::StateType,
9393 /* PropagateCallBaseContext */ true> {
9394 using Base =
9395 AAReturnedFromReturnedValues<AAValueConstantRange,
9396 AAValueConstantRangeImpl,
9397 AAValueConstantRangeImpl::StateType,
9398 /* PropagateCallBaseContext */ true>;
9399 AAValueConstantRangeReturned(const IRPosition &IRP, Attributor &A)
9400 : Base(IRP, A) {}
9401
9402 /// See AbstractAttribute::initialize(...).
9403 void initialize(Attributor &A) override {
9404 if (!A.isFunctionIPOAmendable(*getAssociatedFunction()))
9405 indicatePessimisticFixpoint();
9406 }
9407
9408 /// See AbstractAttribute::trackStatistics()
9409 void trackStatistics() const override {
9410 STATS_DECLTRACK_FNRET_ATTR(value_range)
9411 }
9412};
9413
9414struct AAValueConstantRangeFloating : AAValueConstantRangeImpl {
9415 AAValueConstantRangeFloating(const IRPosition &IRP, Attributor &A)
9416 : AAValueConstantRangeImpl(IRP, A) {}
9417
9418 /// See AbstractAttribute::initialize(...).
9419 void initialize(Attributor &A) override {
9420 AAValueConstantRangeImpl::initialize(A);
9421 if (isAtFixpoint())
9422 return;
9423
9424 Value &V = getAssociatedValue();
9425
9426 if (auto *C = dyn_cast<ConstantInt>(&V)) {
9427 unionAssumed(ConstantRange(C->getValue()));
9428 indicateOptimisticFixpoint();
9429 return;
9430 }
9431
9432 if (isa<UndefValue>(&V)) {
9433 // Collapse the undef state to 0.
9434 unionAssumed(ConstantRange(APInt(getBitWidth(), 0)));
9435 indicateOptimisticFixpoint();
9436 return;
9437 }
9438
9439 if (isa<CallBase>(&V))
9440 return;
9441
9442 if (isa<BinaryOperator>(&V) || isa<CmpInst>(&V) || isa<CastInst>(&V))
9443 return;
9444
9445 // If it is a load instruction with range metadata, use it.
9446 if (LoadInst *LI = dyn_cast<LoadInst>(&V))
9447 if (auto *RangeMD = LI->getMetadata(LLVMContext::MD_range)) {
9448 intersectKnown(getConstantRangeFromMetadata(*RangeMD));
9449 return;
9450 }
9451
9452 // We can work with PHI and select instruction as we traverse their operands
9453 // during update.
9454 if (isa<SelectInst>(V) || isa<PHINode>(V))
9455 return;
9456
9457 // Otherwise we give up.
9458 indicatePessimisticFixpoint();
9459
9460 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] We give up: "
9461 << getAssociatedValue() << "\n");
9462 }
9463
9464 bool calculateBinaryOperator(
9465 Attributor &A, BinaryOperator *BinOp, IntegerRangeState &T,
9466 const Instruction *CtxI,
9467 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) {
9468 Value *LHS = BinOp->getOperand(0);
9469 Value *RHS = BinOp->getOperand(1);
9470
9471 // Simplify the operands first.
9472 bool UsedAssumedInformation = false;
9473 const auto &SimplifiedLHS = A.getAssumedSimplified(
9474 IRPosition::value(*LHS, getCallBaseContext()), *this,
9475 UsedAssumedInformation, AA::Interprocedural);
9476 if (!SimplifiedLHS.has_value())
9477 return true;
9478 if (!*SimplifiedLHS)
9479 return false;
9480 LHS = *SimplifiedLHS;
9481
9482 const auto &SimplifiedRHS = A.getAssumedSimplified(
9483 IRPosition::value(*RHS, getCallBaseContext()), *this,
9484 UsedAssumedInformation, AA::Interprocedural);
9485 if (!SimplifiedRHS.has_value())
9486 return true;
9487 if (!*SimplifiedRHS)
9488 return false;
9489 RHS = *SimplifiedRHS;
9490
9491 // TODO: Allow non integers as well.
9492 if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy())
9493 return false;
9494
9495 auto *LHSAA = A.getAAFor<AAValueConstantRange>(
9496 *this, IRPosition::value(*LHS, getCallBaseContext()),
9497 DepClassTy::REQUIRED);
9498 if (!LHSAA)
9499 return false;
9500 QuerriedAAs.push_back(LHSAA);
9501 auto LHSAARange = LHSAA->getAssumedConstantRange(A, CtxI);
9502
9503 auto *RHSAA = A.getAAFor<AAValueConstantRange>(
9504 *this, IRPosition::value(*RHS, getCallBaseContext()),
9505 DepClassTy::REQUIRED);
9506 if (!RHSAA)
9507 return false;
9508 QuerriedAAs.push_back(RHSAA);
9509 auto RHSAARange = RHSAA->getAssumedConstantRange(A, CtxI);
9510
9511 auto AssumedRange = LHSAARange.binaryOp(BinOp->getOpcode(), RHSAARange);
9512
9513 T.unionAssumed(AssumedRange);
9514
9515 // TODO: Track a known state too.
9516
9517 return T.isValidState();
9518 }
9519
9520 bool calculateCastInst(
9521 Attributor &A, CastInst *CastI, IntegerRangeState &T,
9522 const Instruction *CtxI,
9523 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) {
9524 assert(CastI->getNumOperands() == 1 && "Expected cast to be unary!");
9525 // TODO: Allow non integers as well.
9526 Value *OpV = CastI->getOperand(0);
9527
9528 // Simplify the operand first.
9529 bool UsedAssumedInformation = false;
9530 const auto &SimplifiedOpV = A.getAssumedSimplified(
9531 IRPosition::value(*OpV, getCallBaseContext()), *this,
9532 UsedAssumedInformation, AA::Interprocedural);
9533 if (!SimplifiedOpV.has_value())
9534 return true;
9535 if (!*SimplifiedOpV)
9536 return false;
9537 OpV = *SimplifiedOpV;
9538
9539 if (!OpV->getType()->isIntegerTy())
9540 return false;
9541
9542 auto *OpAA = A.getAAFor<AAValueConstantRange>(
9543 *this, IRPosition::value(*OpV, getCallBaseContext()),
9544 DepClassTy::REQUIRED);
9545 if (!OpAA)
9546 return false;
9547 QuerriedAAs.push_back(OpAA);
9548 T.unionAssumed(OpAA->getAssumed().castOp(CastI->getOpcode(),
9549 getState().getBitWidth()));
9550 return T.isValidState();
9551 }
9552
9553 bool
9554 calculateCmpInst(Attributor &A, CmpInst *CmpI, IntegerRangeState &T,
9555 const Instruction *CtxI,
9556 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) {
9557 Value *LHS = CmpI->getOperand(0);
9558 Value *RHS = CmpI->getOperand(1);
9559
9560 // Simplify the operands first.
9561 bool UsedAssumedInformation = false;
9562 const auto &SimplifiedLHS = A.getAssumedSimplified(
9563 IRPosition::value(*LHS, getCallBaseContext()), *this,
9564 UsedAssumedInformation, AA::Interprocedural);
9565 if (!SimplifiedLHS.has_value())
9566 return true;
9567 if (!*SimplifiedLHS)
9568 return false;
9569 LHS = *SimplifiedLHS;
9570
9571 const auto &SimplifiedRHS = A.getAssumedSimplified(
9572 IRPosition::value(*RHS, getCallBaseContext()), *this,
9573 UsedAssumedInformation, AA::Interprocedural);
9574 if (!SimplifiedRHS.has_value())
9575 return true;
9576 if (!*SimplifiedRHS)
9577 return false;
9578 RHS = *SimplifiedRHS;
9579
9580 // TODO: Allow non integers as well.
9581 if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy())
9582 return false;
9583
9584 auto *LHSAA = A.getAAFor<AAValueConstantRange>(
9585 *this, IRPosition::value(*LHS, getCallBaseContext()),
9586 DepClassTy::REQUIRED);
9587 if (!LHSAA)
9588 return false;
9589 QuerriedAAs.push_back(LHSAA);
9590 auto *RHSAA = A.getAAFor<AAValueConstantRange>(
9591 *this, IRPosition::value(*RHS, getCallBaseContext()),
9592 DepClassTy::REQUIRED);
9593 if (!RHSAA)
9594 return false;
9595 QuerriedAAs.push_back(RHSAA);
9596 auto LHSAARange = LHSAA->getAssumedConstantRange(A, CtxI);
9597 auto RHSAARange = RHSAA->getAssumedConstantRange(A, CtxI);
9598
9599 // If one of them is empty set, we can't decide.
9600 if (LHSAARange.isEmptySet() || RHSAARange.isEmptySet())
9601 return true;
9602
9603 bool MustTrue = false, MustFalse = false;
9604
9605 auto AllowedRegion =
9607
9608 if (AllowedRegion.intersectWith(LHSAARange).isEmptySet())
9609 MustFalse = true;
9610
9611 if (LHSAARange.icmp(CmpI->getPredicate(), RHSAARange))
9612 MustTrue = true;
9613
9614 assert((!MustTrue || !MustFalse) &&
9615 "Either MustTrue or MustFalse should be false!");
9616
9617 if (MustTrue)
9618 T.unionAssumed(ConstantRange(APInt(/* numBits */ 1, /* val */ 1)));
9619 else if (MustFalse)
9620 T.unionAssumed(ConstantRange(APInt(/* numBits */ 1, /* val */ 0)));
9621 else
9622 T.unionAssumed(ConstantRange(/* BitWidth */ 1, /* isFullSet */ true));
9623
9624 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] " << *CmpI << " after "
9625 << (MustTrue ? "true" : (MustFalse ? "false" : "unknown"))
9626 << ": " << T << "\n\t" << *LHSAA << "\t<op>\n\t"
9627 << *RHSAA);
9628
9629 // TODO: Track a known state too.
9630 return T.isValidState();
9631 }
9632
9633 /// See AbstractAttribute::updateImpl(...).
9634 ChangeStatus updateImpl(Attributor &A) override {
9635
9636 IntegerRangeState T(getBitWidth());
9637 auto VisitValueCB = [&](Value &V, const Instruction *CtxI) -> bool {
9639 if (!I || isa<CallBase>(I)) {
9640
9641 // Simplify the operand first.
9642 bool UsedAssumedInformation = false;
9643 const auto &SimplifiedOpV = A.getAssumedSimplified(
9644 IRPosition::value(V, getCallBaseContext()), *this,
9645 UsedAssumedInformation, AA::Interprocedural);
9646 if (!SimplifiedOpV.has_value())
9647 return true;
9648 if (!*SimplifiedOpV)
9649 return false;
9650 Value *VPtr = *SimplifiedOpV;
9651
9652 // If the value is not instruction, we query AA to Attributor.
9653 const auto *AA = A.getAAFor<AAValueConstantRange>(
9654 *this, IRPosition::value(*VPtr, getCallBaseContext()),
9655 DepClassTy::REQUIRED);
9656
9657 // Clamp operator is not used to utilize a program point CtxI.
9658 if (AA)
9659 T.unionAssumed(AA->getAssumedConstantRange(A, CtxI));
9660 else
9661 return false;
9662
9663 return T.isValidState();
9664 }
9665
9667 if (auto *BinOp = dyn_cast<BinaryOperator>(I)) {
9668 if (!calculateBinaryOperator(A, BinOp, T, CtxI, QuerriedAAs))
9669 return false;
9670 } else if (auto *CmpI = dyn_cast<CmpInst>(I)) {
9671 if (!calculateCmpInst(A, CmpI, T, CtxI, QuerriedAAs))
9672 return false;
9673 } else if (auto *CastI = dyn_cast<CastInst>(I)) {
9674 if (!calculateCastInst(A, CastI, T, CtxI, QuerriedAAs))
9675 return false;
9676 } else {
9677 // Give up with other instructions.
9678 // TODO: Add other instructions
9679
9680 T.indicatePessimisticFixpoint();
9681 return false;
9682 }
9683
9684 // Catch circular reasoning in a pessimistic way for now.
9685 // TODO: Check how the range evolves and if we stripped anything, see also
9686 // AADereferenceable or AAAlign for similar situations.
9687 for (const AAValueConstantRange *QueriedAA : QuerriedAAs) {
9688 if (QueriedAA != this)
9689 continue;
9690 // If we are in a stady state we do not need to worry.
9691 if (T.getAssumed() == getState().getAssumed())
9692 continue;
9693 T.indicatePessimisticFixpoint();
9694 }
9695
9696 return T.isValidState();
9697 };
9698
9699 if (!VisitValueCB(getAssociatedValue(), getCtxI()))
9700 return indicatePessimisticFixpoint();
9701
9702 // Ensure that long def-use chains can't cause circular reasoning either by
9703 // introducing a cutoff below.
9704 if (clampStateAndIndicateChange(getState(), T) == ChangeStatus::UNCHANGED)
9705 return ChangeStatus::UNCHANGED;
9706 if (++NumChanges > MaxNumChanges) {
9707 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] performed " << NumChanges
9708 << " but only " << MaxNumChanges
9709 << " are allowed to avoid cyclic reasoning.");
9710 return indicatePessimisticFixpoint();
9711 }
9712 return ChangeStatus::CHANGED;
9713 }
9714
9715 /// See AbstractAttribute::trackStatistics()
9716 void trackStatistics() const override {
9718 }
9719
9720 /// Tracker to bail after too many widening steps of the constant range.
9721 int NumChanges = 0;
9722
9723 /// Upper bound for the number of allowed changes (=widening steps) for the
9724 /// constant range before we give up.
9725 static constexpr int MaxNumChanges = 5;
9726};
9727
9728struct AAValueConstantRangeFunction : AAValueConstantRangeImpl {
9729 AAValueConstantRangeFunction(const IRPosition &IRP, Attributor &A)
9730 : AAValueConstantRangeImpl(IRP, A) {}
9731
9732 /// See AbstractAttribute::initialize(...).
9733 ChangeStatus updateImpl(Attributor &A) override {
9734 llvm_unreachable("AAValueConstantRange(Function|CallSite)::updateImpl will "
9735 "not be called");
9736 }
9737
9738 /// See AbstractAttribute::trackStatistics()
9739 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(value_range) }
9740};
9741
9742struct AAValueConstantRangeCallSite : AAValueConstantRangeFunction {
9743 AAValueConstantRangeCallSite(const IRPosition &IRP, Attributor &A)
9744 : AAValueConstantRangeFunction(IRP, A) {}
9745
9746 /// See AbstractAttribute::trackStatistics()
9747 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(value_range) }
9748};
9749
9750struct AAValueConstantRangeCallSiteReturned
9751 : AACalleeToCallSite<AAValueConstantRange, AAValueConstantRangeImpl,
9752 AAValueConstantRangeImpl::StateType,
9753 /* IntroduceCallBaseContext */ true> {
9754 AAValueConstantRangeCallSiteReturned(const IRPosition &IRP, Attributor &A)
9755 : AACalleeToCallSite<AAValueConstantRange, AAValueConstantRangeImpl,
9756 AAValueConstantRangeImpl::StateType,
9757 /* IntroduceCallBaseContext */ true>(IRP, A) {}
9758
9759 /// See AbstractAttribute::initialize(...).
9760 void initialize(Attributor &A) override {
9761 // If it is a call instruction with range attribute, use the range.
9762 if (CallInst *CI = dyn_cast<CallInst>(&getAssociatedValue())) {
9763 if (std::optional<ConstantRange> Range = CI->getRange())
9764 intersectKnown(*Range);
9765 }
9766
9767 AAValueConstantRangeImpl::initialize(A);
9768 }
9769
9770 /// See AbstractAttribute::trackStatistics()
9771 void trackStatistics() const override {
9772 STATS_DECLTRACK_CSRET_ATTR(value_range)
9773 }
9774};
9775struct AAValueConstantRangeCallSiteArgument : AAValueConstantRangeFloating {
9776 AAValueConstantRangeCallSiteArgument(const IRPosition &IRP, Attributor &A)
9777 : AAValueConstantRangeFloating(IRP, A) {}
9778
9779 /// See AbstractAttribute::manifest()
9780 ChangeStatus manifest(Attributor &A) override {
9781 return ChangeStatus::UNCHANGED;
9782 }
9783
9784 /// See AbstractAttribute::trackStatistics()
9785 void trackStatistics() const override {
9786 STATS_DECLTRACK_CSARG_ATTR(value_range)
9787 }
9788};
9789} // namespace
9790
9791/// ------------------ Potential Values Attribute -------------------------
9792
9793namespace {
9794struct AAPotentialConstantValuesImpl : AAPotentialConstantValues {
9795 using StateType = PotentialConstantIntValuesState;
9796
9797 AAPotentialConstantValuesImpl(const IRPosition &IRP, Attributor &A)
9798 : AAPotentialConstantValues(IRP, A) {}
9799
9800 /// See AbstractAttribute::initialize(..).
9801 void initialize(Attributor &A) override {
9802 if (A.hasSimplificationCallback(getIRPosition()))
9803 indicatePessimisticFixpoint();
9804 else
9805 AAPotentialConstantValues::initialize(A);
9806 }
9807
9808 bool fillSetWithConstantValues(Attributor &A, const IRPosition &IRP, SetTy &S,
9809 bool &ContainsUndef, bool ForSelf) {
9811 bool UsedAssumedInformation = false;
9812 if (!A.getAssumedSimplifiedValues(IRP, *this, Values, AA::Interprocedural,
9813 UsedAssumedInformation)) {
9814 // Avoid recursion when the caller is computing constant values for this
9815 // IRP itself.
9816 if (ForSelf)
9817 return false;
9818 if (!IRP.getAssociatedType()->isIntegerTy())
9819 return false;
9820 auto *PotentialValuesAA = A.getAAFor<AAPotentialConstantValues>(
9821 *this, IRP, DepClassTy::REQUIRED);
9822 if (!PotentialValuesAA || !PotentialValuesAA->getState().isValidState())
9823 return false;
9824 ContainsUndef = PotentialValuesAA->getState().undefIsContained();
9825 S = PotentialValuesAA->getState().getAssumedSet();
9826 return true;
9827 }
9828
9829 // Copy all the constant values, except UndefValue. ContainsUndef is true
9830 // iff Values contains only UndefValue instances. If there are other known
9831 // constants, then UndefValue is dropped.
9832 ContainsUndef = false;
9833 for (auto &It : Values) {
9834 if (isa<UndefValue>(It.getValue())) {
9835 ContainsUndef = true;
9836 continue;
9837 }
9838 auto *CI = dyn_cast<ConstantInt>(It.getValue());
9839 if (!CI)
9840 return false;
9841 S.insert(CI->getValue());
9842 }
9843 ContainsUndef &= S.empty();
9844
9845 return true;
9846 }
9847
9848 /// See AbstractAttribute::getAsStr().
9849 const std::string getAsStr(Attributor *A) const override {
9850 std::string Str;
9851 llvm::raw_string_ostream OS(Str);
9852 OS << getState();
9853 return Str;
9854 }
9855
9856 /// See AbstractAttribute::updateImpl(...).
9857 ChangeStatus updateImpl(Attributor &A) override {
9858 return indicatePessimisticFixpoint();
9859 }
9860};
9861
9862struct AAPotentialConstantValuesArgument final
9863 : AAArgumentFromCallSiteArguments<AAPotentialConstantValues,
9864 AAPotentialConstantValuesImpl,
9865 PotentialConstantIntValuesState> {
9866 using Base = AAArgumentFromCallSiteArguments<AAPotentialConstantValues,
9867 AAPotentialConstantValuesImpl,
9869 AAPotentialConstantValuesArgument(const IRPosition &IRP, Attributor &A)
9870 : Base(IRP, A) {}
9871
9872 /// See AbstractAttribute::trackStatistics()
9873 void trackStatistics() const override {
9874 STATS_DECLTRACK_ARG_ATTR(potential_values)
9875 }
9876};
9877
9878struct AAPotentialConstantValuesReturned
9879 : AAReturnedFromReturnedValues<AAPotentialConstantValues,
9880 AAPotentialConstantValuesImpl> {
9881 using Base = AAReturnedFromReturnedValues<AAPotentialConstantValues,
9882 AAPotentialConstantValuesImpl>;
9883 AAPotentialConstantValuesReturned(const IRPosition &IRP, Attributor &A)
9884 : Base(IRP, A) {}
9885
9886 void initialize(Attributor &A) override {
9887 if (!A.isFunctionIPOAmendable(*getAssociatedFunction()))
9888 indicatePessimisticFixpoint();
9889 Base::initialize(A);
9890 }
9891
9892 /// See AbstractAttribute::trackStatistics()
9893 void trackStatistics() const override {
9894 STATS_DECLTRACK_FNRET_ATTR(potential_values)
9895 }
9896};
9897
9898struct AAPotentialConstantValuesFloating : AAPotentialConstantValuesImpl {
9899 AAPotentialConstantValuesFloating(const IRPosition &IRP, Attributor &A)
9900 : AAPotentialConstantValuesImpl(IRP, A) {}
9901
9902 /// See AbstractAttribute::initialize(..).
9903 void initialize(Attributor &A) override {
9904 AAPotentialConstantValuesImpl::initialize(A);
9905 if (isAtFixpoint())
9906 return;
9907
9908 Value &V = getAssociatedValue();
9909
9910 if (auto *C = dyn_cast<ConstantInt>(&V)) {
9911 unionAssumed(C->getValue());
9912 indicateOptimisticFixpoint();
9913 return;
9914 }
9915
9916 if (isa<UndefValue>(&V)) {
9917 unionAssumedWithUndef();
9918 indicateOptimisticFixpoint();
9919 return;
9920 }
9921
9922 if (isa<BinaryOperator>(&V) || isa<ICmpInst>(&V) || isa<CastInst>(&V))
9923 return;
9924
9925 if (isa<SelectInst>(V) || isa<PHINode>(V) || isa<LoadInst>(V))
9926 return;
9927
9928 indicatePessimisticFixpoint();
9929
9930 LLVM_DEBUG(dbgs() << "[AAPotentialConstantValues] We give up: "
9931 << getAssociatedValue() << "\n");
9932 }
9933
9934 static bool calculateICmpInst(const ICmpInst *ICI, const APInt &LHS,
9935 const APInt &RHS) {
9936 return ICmpInst::compare(LHS, RHS, ICI->getPredicate());
9937 }
9938
9939 static APInt calculateCastInst(const CastInst *CI, const APInt &Src,
9940 uint32_t ResultBitWidth) {
9941 Instruction::CastOps CastOp = CI->getOpcode();
9942 switch (CastOp) {
9943 default:
9944 llvm_unreachable("unsupported or not integer cast");
9945 case Instruction::Trunc:
9946 return Src.trunc(ResultBitWidth);
9947 case Instruction::SExt:
9948 return Src.sext(ResultBitWidth);
9949 case Instruction::ZExt:
9950 return Src.zext(ResultBitWidth);
9951 case Instruction::BitCast:
9952 return Src;
9953 }
9954 }
9955
9956 static APInt calculateBinaryOperator(const BinaryOperator *BinOp,
9957 const APInt &LHS, const APInt &RHS,
9958 bool &SkipOperation, bool &Unsupported) {
9959 Instruction::BinaryOps BinOpcode = BinOp->getOpcode();
9960 // Unsupported is set to true when the binary operator is not supported.
9961 // SkipOperation is set to true when UB occur with the given operand pair
9962 // (LHS, RHS).
9963 // TODO: we should look at nsw and nuw keywords to handle operations
9964 // that create poison or undef value.
9965 switch (BinOpcode) {
9966 default:
9967 Unsupported = true;
9968 return LHS;
9969 case Instruction::Add:
9970 return LHS + RHS;
9971 case Instruction::Sub:
9972 return LHS - RHS;
9973 case Instruction::Mul:
9974 return LHS * RHS;
9975 case Instruction::UDiv:
9976 if (RHS.isZero()) {
9977 SkipOperation = true;
9978 return LHS;
9979 }
9980 return LHS.udiv(RHS);
9981 case Instruction::SDiv:
9982 if (RHS.isZero()) {
9983 SkipOperation = true;
9984 return LHS;
9985 }
9986 return LHS.sdiv(RHS);
9987 case Instruction::URem:
9988 if (RHS.isZero()) {
9989 SkipOperation = true;
9990 return LHS;
9991 }
9992 return LHS.urem(RHS);
9993 case Instruction::SRem:
9994 if (RHS.isZero()) {
9995 SkipOperation = true;
9996 return LHS;
9997 }
9998 return LHS.srem(RHS);
9999 case Instruction::Shl:
10000 return LHS.shl(RHS);
10001 case Instruction::LShr:
10002 return LHS.lshr(RHS);
10003 case Instruction::AShr:
10004 return LHS.ashr(RHS);
10005 case Instruction::And:
10006 return LHS & RHS;
10007 case Instruction::Or:
10008 return LHS | RHS;
10009 case Instruction::Xor:
10010 return LHS ^ RHS;
10011 }
10012 }
10013
10014 bool calculateBinaryOperatorAndTakeUnion(const BinaryOperator *BinOp,
10015 const APInt &LHS, const APInt &RHS) {
10016 bool SkipOperation = false;
10017 bool Unsupported = false;
10018 APInt Result =
10019 calculateBinaryOperator(BinOp, LHS, RHS, SkipOperation, Unsupported);
10020 if (Unsupported)
10021 return false;
10022 // If SkipOperation is true, we can ignore this operand pair (L, R).
10023 if (!SkipOperation)
10024 unionAssumed(Result);
10025 return isValidState();
10026 }
10027
10028 ChangeStatus updateWithICmpInst(Attributor &A, ICmpInst *ICI) {
10029 auto AssumedBefore = getAssumed();
10030 Value *LHS = ICI->getOperand(0);
10031 Value *RHS = ICI->getOperand(1);
10032
10033 bool LHSContainsUndef = false, RHSContainsUndef = false;
10034 SetTy LHSAAPVS, RHSAAPVS;
10035 if (!fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS,
10036 LHSContainsUndef, /* ForSelf */ false) ||
10037 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS,
10038 RHSContainsUndef, /* ForSelf */ false))
10039 return indicatePessimisticFixpoint();
10040
10041 // TODO: make use of undef flag to limit potential values aggressively.
10042 bool MaybeTrue = false, MaybeFalse = false;
10043 const APInt Zero(RHS->getType()->getIntegerBitWidth(), 0);
10044 if (LHSContainsUndef && RHSContainsUndef) {
10045 // The result of any comparison between undefs can be soundly replaced
10046 // with undef.
10047 unionAssumedWithUndef();
10048 } else if (LHSContainsUndef) {
10049 for (const APInt &R : RHSAAPVS) {
10050 bool CmpResult = calculateICmpInst(ICI, Zero, R);
10051 MaybeTrue |= CmpResult;
10052 MaybeFalse |= !CmpResult;
10053 if (MaybeTrue & MaybeFalse)
10054 return indicatePessimisticFixpoint();
10055 }
10056 } else if (RHSContainsUndef) {
10057 for (const APInt &L : LHSAAPVS) {
10058 bool CmpResult = calculateICmpInst(ICI, L, Zero);
10059 MaybeTrue |= CmpResult;
10060 MaybeFalse |= !CmpResult;
10061 if (MaybeTrue & MaybeFalse)
10062 return indicatePessimisticFixpoint();
10063 }
10064 } else {
10065 for (const APInt &L : LHSAAPVS) {
10066 for (const APInt &R : RHSAAPVS) {
10067 bool CmpResult = calculateICmpInst(ICI, L, R);
10068 MaybeTrue |= CmpResult;
10069 MaybeFalse |= !CmpResult;
10070 if (MaybeTrue & MaybeFalse)
10071 return indicatePessimisticFixpoint();
10072 }
10073 }
10074 }
10075 if (MaybeTrue)
10076 unionAssumed(APInt(/* numBits */ 1, /* val */ 1));
10077 if (MaybeFalse)
10078 unionAssumed(APInt(/* numBits */ 1, /* val */ 0));
10079 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10080 : ChangeStatus::CHANGED;
10081 }
10082
10083 ChangeStatus updateWithSelectInst(Attributor &A, SelectInst *SI) {
10084 auto AssumedBefore = getAssumed();
10085 Value *LHS = SI->getTrueValue();
10086 Value *RHS = SI->getFalseValue();
10087
10088 bool UsedAssumedInformation = false;
10089 std::optional<Constant *> C = A.getAssumedConstant(
10090 *SI->getCondition(), *this, UsedAssumedInformation);
10091
10092 // Check if we only need one operand.
10093 bool OnlyLeft = false, OnlyRight = false;
10094 if (C && *C && (*C)->isOneValue())
10095 OnlyLeft = true;
10096 else if (C && *C && (*C)->isNullValue())
10097 OnlyRight = true;
10098
10099 bool LHSContainsUndef = false, RHSContainsUndef = false;
10100 SetTy LHSAAPVS, RHSAAPVS;
10101 if (!OnlyRight &&
10102 !fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS,
10103 LHSContainsUndef, /* ForSelf */ false))
10104 return indicatePessimisticFixpoint();
10105
10106 if (!OnlyLeft &&
10107 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS,
10108 RHSContainsUndef, /* ForSelf */ false))
10109 return indicatePessimisticFixpoint();
10110
10111 if (OnlyLeft || OnlyRight) {
10112 // select (true/false), lhs, rhs
10113 auto *OpAA = OnlyLeft ? &LHSAAPVS : &RHSAAPVS;
10114 auto Undef = OnlyLeft ? LHSContainsUndef : RHSContainsUndef;
10115
10116 if (Undef)
10117 unionAssumedWithUndef();
10118 else {
10119 for (const auto &It : *OpAA)
10120 unionAssumed(It);
10121 }
10122
10123 } else if (LHSContainsUndef && RHSContainsUndef) {
10124 // select i1 *, undef , undef => undef
10125 unionAssumedWithUndef();
10126 } else {
10127 for (const auto &It : LHSAAPVS)
10128 unionAssumed(It);
10129 for (const auto &It : RHSAAPVS)
10130 unionAssumed(It);
10131 }
10132 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10133 : ChangeStatus::CHANGED;
10134 }
10135
10136 ChangeStatus updateWithCastInst(Attributor &A, CastInst *CI) {
10137 auto AssumedBefore = getAssumed();
10138 if (!CI->isIntegerCast())
10139 return indicatePessimisticFixpoint();
10140 assert(CI->getNumOperands() == 1 && "Expected cast to be unary!");
10141 uint32_t ResultBitWidth = CI->getDestTy()->getIntegerBitWidth();
10142 Value *Src = CI->getOperand(0);
10143
10144 bool SrcContainsUndef = false;
10145 SetTy SrcPVS;
10146 if (!fillSetWithConstantValues(A, IRPosition::value(*Src), SrcPVS,
10147 SrcContainsUndef, /* ForSelf */ false))
10148 return indicatePessimisticFixpoint();
10149
10150 if (SrcContainsUndef)
10151 unionAssumedWithUndef();
10152 else {
10153 for (const APInt &S : SrcPVS) {
10154 APInt T = calculateCastInst(CI, S, ResultBitWidth);
10155 unionAssumed(T);
10156 }
10157 }
10158 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10159 : ChangeStatus::CHANGED;
10160 }
10161
10162 ChangeStatus updateWithBinaryOperator(Attributor &A, BinaryOperator *BinOp) {
10163 auto AssumedBefore = getAssumed();
10164 Value *LHS = BinOp->getOperand(0);
10165 Value *RHS = BinOp->getOperand(1);
10166
10167 bool LHSContainsUndef = false, RHSContainsUndef = false;
10168 SetTy LHSAAPVS, RHSAAPVS;
10169 if (!fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS,
10170 LHSContainsUndef, /* ForSelf */ false) ||
10171 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS,
10172 RHSContainsUndef, /* ForSelf */ false))
10173 return indicatePessimisticFixpoint();
10174
10175 const APInt Zero = APInt(LHS->getType()->getIntegerBitWidth(), 0);
10176
10177 // TODO: make use of undef flag to limit potential values aggressively.
10178 if (LHSContainsUndef && RHSContainsUndef) {
10179 if (!calculateBinaryOperatorAndTakeUnion(BinOp, Zero, Zero))
10180 return indicatePessimisticFixpoint();
10181 } else if (LHSContainsUndef) {
10182 for (const APInt &R : RHSAAPVS) {
10183 if (!calculateBinaryOperatorAndTakeUnion(BinOp, Zero, R))
10184 return indicatePessimisticFixpoint();
10185 }
10186 } else if (RHSContainsUndef) {
10187 for (const APInt &L : LHSAAPVS) {
10188 if (!calculateBinaryOperatorAndTakeUnion(BinOp, L, Zero))
10189 return indicatePessimisticFixpoint();
10190 }
10191 } else {
10192 for (const APInt &L : LHSAAPVS) {
10193 for (const APInt &R : RHSAAPVS) {
10194 if (!calculateBinaryOperatorAndTakeUnion(BinOp, L, R))
10195 return indicatePessimisticFixpoint();
10196 }
10197 }
10198 }
10199 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10200 : ChangeStatus::CHANGED;
10201 }
10202
10203 ChangeStatus updateWithInstruction(Attributor &A, Instruction *Inst) {
10204 auto AssumedBefore = getAssumed();
10205 SetTy Incoming;
10206 bool ContainsUndef;
10207 if (!fillSetWithConstantValues(A, IRPosition::value(*Inst), Incoming,
10208 ContainsUndef, /* ForSelf */ true))
10209 return indicatePessimisticFixpoint();
10210 if (ContainsUndef) {
10211 unionAssumedWithUndef();
10212 } else {
10213 for (const auto &It : Incoming)
10214 unionAssumed(It);
10215 }
10216 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10217 : ChangeStatus::CHANGED;
10218 }
10219
10220 /// See AbstractAttribute::updateImpl(...).
10221 ChangeStatus updateImpl(Attributor &A) override {
10222 Value &V = getAssociatedValue();
10224
10225 if (auto *ICI = dyn_cast<ICmpInst>(I))
10226 return updateWithICmpInst(A, ICI);
10227
10228 if (auto *SI = dyn_cast<SelectInst>(I))
10229 return updateWithSelectInst(A, SI);
10230
10231 if (auto *CI = dyn_cast<CastInst>(I))
10232 return updateWithCastInst(A, CI);
10233
10234 if (auto *BinOp = dyn_cast<BinaryOperator>(I))
10235 return updateWithBinaryOperator(A, BinOp);
10236
10237 if (isa<PHINode>(I) || isa<LoadInst>(I))
10238 return updateWithInstruction(A, I);
10239
10240 return indicatePessimisticFixpoint();
10241 }
10242
10243 /// See AbstractAttribute::trackStatistics()
10244 void trackStatistics() const override {
10245 STATS_DECLTRACK_FLOATING_ATTR(potential_values)
10246 }
10247};
10248
10249struct AAPotentialConstantValuesFunction : AAPotentialConstantValuesImpl {
10250 AAPotentialConstantValuesFunction(const IRPosition &IRP, Attributor &A)
10251 : AAPotentialConstantValuesImpl(IRP, A) {}
10252
10253 /// See AbstractAttribute::initialize(...).
10254 ChangeStatus updateImpl(Attributor &A) override {
10256 "AAPotentialConstantValues(Function|CallSite)::updateImpl will "
10257 "not be called");
10258 }
10259
10260 /// See AbstractAttribute::trackStatistics()
10261 void trackStatistics() const override {
10262 STATS_DECLTRACK_FN_ATTR(potential_values)
10263 }
10264};
10265
10266struct AAPotentialConstantValuesCallSite : AAPotentialConstantValuesFunction {
10267 AAPotentialConstantValuesCallSite(const IRPosition &IRP, Attributor &A)
10268 : AAPotentialConstantValuesFunction(IRP, A) {}
10269
10270 /// See AbstractAttribute::trackStatistics()
10271 void trackStatistics() const override {
10272 STATS_DECLTRACK_CS_ATTR(potential_values)
10273 }
10274};
10275
10276struct AAPotentialConstantValuesCallSiteReturned
10277 : AACalleeToCallSite<AAPotentialConstantValues,
10278 AAPotentialConstantValuesImpl> {
10279 AAPotentialConstantValuesCallSiteReturned(const IRPosition &IRP,
10280 Attributor &A)
10281 : AACalleeToCallSite<AAPotentialConstantValues,
10282 AAPotentialConstantValuesImpl>(IRP, A) {}
10283
10284 /// See AbstractAttribute::trackStatistics()
10285 void trackStatistics() const override {
10286 STATS_DECLTRACK_CSRET_ATTR(potential_values)
10287 }
10288};
10289
10290struct AAPotentialConstantValuesCallSiteArgument
10291 : AAPotentialConstantValuesFloating {
10292 AAPotentialConstantValuesCallSiteArgument(const IRPosition &IRP,
10293 Attributor &A)
10294 : AAPotentialConstantValuesFloating(IRP, A) {}
10295
10296 /// See AbstractAttribute::initialize(..).
10297 void initialize(Attributor &A) override {
10298 AAPotentialConstantValuesImpl::initialize(A);
10299 if (isAtFixpoint())
10300 return;
10301
10302 Value &V = getAssociatedValue();
10303
10304 if (auto *C = dyn_cast<ConstantInt>(&V)) {
10305 unionAssumed(C->getValue());
10306 indicateOptimisticFixpoint();
10307 return;
10308 }
10309
10310 if (isa<UndefValue>(&V)) {
10311 unionAssumedWithUndef();
10312 indicateOptimisticFixpoint();
10313 return;
10314 }
10315 }
10316
10317 /// See AbstractAttribute::updateImpl(...).
10318 ChangeStatus updateImpl(Attributor &A) override {
10319 Value &V = getAssociatedValue();
10320 auto AssumedBefore = getAssumed();
10321 auto *AA = A.getAAFor<AAPotentialConstantValues>(
10322 *this, IRPosition::value(V), DepClassTy::REQUIRED);
10323 if (!AA)
10324 return indicatePessimisticFixpoint();
10325 const auto &S = AA->getAssumed();
10326 unionAssumed(S);
10327 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10328 : ChangeStatus::CHANGED;
10329 }
10330
10331 /// See AbstractAttribute::trackStatistics()
10332 void trackStatistics() const override {
10333 STATS_DECLTRACK_CSARG_ATTR(potential_values)
10334 }
10335};
10336} // namespace
10337
10338/// ------------------------ NoUndef Attribute ---------------------------------
10340 Attribute::AttrKind ImpliedAttributeKind,
10341 bool IgnoreSubsumingPositions) {
10342 assert(ImpliedAttributeKind == Attribute::NoUndef &&
10343 "Unexpected attribute kind");
10344 if (A.hasAttr(IRP, {Attribute::NoUndef}, IgnoreSubsumingPositions,
10345 Attribute::NoUndef))
10346 return true;
10347
10348 Value &Val = IRP.getAssociatedValue();
10351 LLVMContext &Ctx = Val.getContext();
10352 A.manifestAttrs(IRP, Attribute::get(Ctx, Attribute::NoUndef));
10353 return true;
10354 }
10355
10356 return false;
10357}
10358
10359namespace {
10360struct AANoUndefImpl : AANoUndef {
10361 AANoUndefImpl(const IRPosition &IRP, Attributor &A) : AANoUndef(IRP, A) {}
10362
10363 /// See AbstractAttribute::initialize(...).
10364 void initialize(Attributor &A) override {
10365 Value &V = getAssociatedValue();
10366 if (isa<UndefValue>(V))
10367 indicatePessimisticFixpoint();
10368 assert(!isImpliedByIR(A, getIRPosition(), Attribute::NoUndef));
10369 }
10370
10371 /// See followUsesInMBEC
10372 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
10373 AANoUndef::StateType &State) {
10374 const Value *UseV = U->get();
10375 const DominatorTree *DT = nullptr;
10376 AssumptionCache *AC = nullptr;
10377 InformationCache &InfoCache = A.getInfoCache();
10378 if (Function *F = getAnchorScope()) {
10379 DT = InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F);
10380 AC = InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F);
10381 }
10382 State.setKnown(isGuaranteedNotToBeUndefOrPoison(UseV, AC, I, DT));
10383 bool TrackUse = false;
10384 // Track use for instructions which must produce undef or poison bits when
10385 // at least one operand contains such bits.
10387 TrackUse = true;
10388 return TrackUse;
10389 }
10390
10391 /// See AbstractAttribute::getAsStr().
10392 const std::string getAsStr(Attributor *A) const override {
10393 return getAssumed() ? "noundef" : "may-undef-or-poison";
10394 }
10395
10396 ChangeStatus manifest(Attributor &A) override {
10397 // We don't manifest noundef attribute for dead positions because the
10398 // associated values with dead positions would be replaced with undef
10399 // values.
10400 bool UsedAssumedInformation = false;
10401 if (A.isAssumedDead(getIRPosition(), nullptr, nullptr,
10402 UsedAssumedInformation))
10403 return ChangeStatus::UNCHANGED;
10404 // A position whose simplified value does not have any value is
10405 // considered to be dead. We don't manifest noundef in such positions for
10406 // the same reason above.
10407 if (!A.getAssumedSimplified(getIRPosition(), *this, UsedAssumedInformation,
10409 .has_value())
10410 return ChangeStatus::UNCHANGED;
10411 return AANoUndef::manifest(A);
10412 }
10413};
10414
10415struct AANoUndefFloating : public AANoUndefImpl {
10416 AANoUndefFloating(const IRPosition &IRP, Attributor &A)
10417 : AANoUndefImpl(IRP, A) {}
10418
10419 /// See AbstractAttribute::initialize(...).
10420 void initialize(Attributor &A) override {
10421 AANoUndefImpl::initialize(A);
10422 if (!getState().isAtFixpoint() && getAnchorScope() &&
10423 !getAnchorScope()->isDeclaration())
10424 if (Instruction *CtxI = getCtxI())
10425 followUsesInMBEC(*this, A, getState(), *CtxI);
10426 }
10427
10428 /// See AbstractAttribute::updateImpl(...).
10429 ChangeStatus updateImpl(Attributor &A) override {
10430 auto VisitValueCB = [&](const IRPosition &IRP) -> bool {
10431 bool IsKnownNoUndef;
10433 A, this, IRP, DepClassTy::REQUIRED, IsKnownNoUndef);
10434 };
10435
10436 bool Stripped;
10437 bool UsedAssumedInformation = false;
10438 Value *AssociatedValue = &getAssociatedValue();
10440 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
10441 AA::AnyScope, UsedAssumedInformation))
10442 Stripped = false;
10443 else
10444 Stripped =
10445 Values.size() != 1 || Values.front().getValue() != AssociatedValue;
10446
10447 if (!Stripped) {
10448 // If we haven't stripped anything we might still be able to use a
10449 // different AA, but only if the IRP changes. Effectively when we
10450 // interpret this not as a call site value but as a floating/argument
10451 // value.
10452 const IRPosition AVIRP = IRPosition::value(*AssociatedValue);
10453 if (AVIRP == getIRPosition() || !VisitValueCB(AVIRP))
10454 return indicatePessimisticFixpoint();
10455 return ChangeStatus::UNCHANGED;
10456 }
10457
10458 for (const auto &VAC : Values)
10459 if (!VisitValueCB(IRPosition::value(*VAC.getValue())))
10460 return indicatePessimisticFixpoint();
10461
10462 return ChangeStatus::UNCHANGED;
10463 }
10464
10465 /// See AbstractAttribute::trackStatistics()
10466 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noundef) }
10467};
10468
10469struct AANoUndefReturned final
10470 : AAReturnedFromReturnedValues<AANoUndef, AANoUndefImpl> {
10471 AANoUndefReturned(const IRPosition &IRP, Attributor &A)
10472 : AAReturnedFromReturnedValues<AANoUndef, AANoUndefImpl>(IRP, A) {}
10473
10474 /// See AbstractAttribute::trackStatistics()
10475 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noundef) }
10476};
10477
10478struct AANoUndefArgument final
10479 : AAArgumentFromCallSiteArguments<AANoUndef, AANoUndefImpl> {
10480 AANoUndefArgument(const IRPosition &IRP, Attributor &A)
10481 : AAArgumentFromCallSiteArguments<AANoUndef, AANoUndefImpl>(IRP, A) {}
10482
10483 /// See AbstractAttribute::trackStatistics()
10484 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noundef) }
10485};
10486
10487struct AANoUndefCallSiteArgument final : AANoUndefFloating {
10488 AANoUndefCallSiteArgument(const IRPosition &IRP, Attributor &A)
10489 : AANoUndefFloating(IRP, A) {}
10490
10491 /// See AbstractAttribute::trackStatistics()
10492 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(noundef) }
10493};
10494
10495struct AANoUndefCallSiteReturned final
10496 : AACalleeToCallSite<AANoUndef, AANoUndefImpl> {
10497 AANoUndefCallSiteReturned(const IRPosition &IRP, Attributor &A)
10498 : AACalleeToCallSite<AANoUndef, AANoUndefImpl>(IRP, A) {}
10499
10500 /// See AbstractAttribute::trackStatistics()
10501 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(noundef) }
10502};
10503
10504/// ------------------------ NoFPClass Attribute -------------------------------
10505
10506struct AANoFPClassImpl : AANoFPClass {
10507 AANoFPClassImpl(const IRPosition &IRP, Attributor &A) : AANoFPClass(IRP, A) {}
10508
10509 void initialize(Attributor &A) override {
10510 const IRPosition &IRP = getIRPosition();
10511
10512 Value &V = IRP.getAssociatedValue();
10513 if (isa<UndefValue>(V)) {
10514 indicateOptimisticFixpoint();
10515 return;
10516 }
10517
10519 A.getAttrs(getIRPosition(), {Attribute::NoFPClass}, Attrs, false);
10520 for (const auto &Attr : Attrs) {
10521 addKnownBits(Attr.getNoFPClass());
10522 }
10523
10524 Instruction *CtxI = getCtxI();
10525
10526 if (getPositionKind() != IRPosition::IRP_RETURNED) {
10527 const DataLayout &DL = A.getDataLayout();
10528 InformationCache &InfoCache = A.getInfoCache();
10529
10530 const DominatorTree *DT = nullptr;
10531 AssumptionCache *AC = nullptr;
10532 const TargetLibraryInfo *TLI = nullptr;
10533 Function *F = getAnchorScope();
10534 if (F) {
10535 TLI = InfoCache.getTargetLibraryInfoForFunction(*F);
10536 if (!F->isDeclaration()) {
10537 DT =
10538 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F);
10539 AC = InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F);
10540 }
10541 }
10542
10543 SimplifyQuery Q(DL, TLI, DT, AC, CtxI);
10544
10545 KnownFPClass KnownFPClass = computeKnownFPClass(&V, fcAllFlags, Q);
10546 addKnownBits(~KnownFPClass.getKnownFPClasses());
10547 }
10548
10549 if (CtxI)
10550 followUsesInMBEC(*this, A, getState(), *CtxI);
10551 }
10552
10553 /// See followUsesInMBEC
10554 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
10555 AANoFPClass::StateType &State) {
10556 // TODO: Determine what instructions can be looked through.
10557 auto *CB = dyn_cast<CallBase>(I);
10558 if (!CB)
10559 return false;
10560
10561 if (!CB->isArgOperand(U))
10562 return false;
10563
10564 unsigned ArgNo = CB->getArgOperandNo(U);
10565 IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo);
10566 if (auto *NoFPAA = A.getAAFor<AANoFPClass>(*this, IRP, DepClassTy::NONE))
10567 State.addKnownBits(NoFPAA->getState().getKnown());
10568 return false;
10569 }
10570
10571 const std::string getAsStr(Attributor *A) const override {
10572 std::string Result = "nofpclass";
10573 raw_string_ostream OS(Result);
10574 OS << getKnownNoFPClass() << '/' << getAssumedNoFPClass();
10575 return Result;
10576 }
10577
10578 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
10579 SmallVectorImpl<Attribute> &Attrs) const override {
10580 Attrs.emplace_back(Attribute::getWithNoFPClass(Ctx, getAssumedNoFPClass()));
10581 }
10582};
10583
10584struct AANoFPClassFloating : public AANoFPClassImpl {
10585 AANoFPClassFloating(const IRPosition &IRP, Attributor &A)
10586 : AANoFPClassImpl(IRP, A) {}
10587
10588 /// See AbstractAttribute::updateImpl(...).
10589 ChangeStatus updateImpl(Attributor &A) override {
10591 bool UsedAssumedInformation = false;
10592 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
10593 AA::AnyScope, UsedAssumedInformation)) {
10594 Values.push_back({getAssociatedValue(), getCtxI()});
10595 }
10596
10597 StateType T;
10598 auto VisitValueCB = [&](Value &V, const Instruction *CtxI) -> bool {
10599 const auto *AA = A.getAAFor<AANoFPClass>(*this, IRPosition::value(V),
10600 DepClassTy::REQUIRED);
10601 if (!AA || this == AA) {
10602 T.indicatePessimisticFixpoint();
10603 } else {
10604 const AANoFPClass::StateType &S =
10605 static_cast<const AANoFPClass::StateType &>(AA->getState());
10606 T ^= S;
10607 }
10608 return T.isValidState();
10609 };
10610
10611 for (const auto &VAC : Values)
10612 if (!VisitValueCB(*VAC.getValue(), VAC.getCtxI()))
10613 return indicatePessimisticFixpoint();
10614
10615 return clampStateAndIndicateChange(getState(), T);
10616 }
10617
10618 /// See AbstractAttribute::trackStatistics()
10619 void trackStatistics() const override {
10621 }
10622};
10623
10624struct AANoFPClassReturned final
10625 : AAReturnedFromReturnedValues<AANoFPClass, AANoFPClassImpl,
10626 AANoFPClassImpl::StateType, false,
10627 Attribute::None, false> {
10628 AANoFPClassReturned(const IRPosition &IRP, Attributor &A)
10629 : AAReturnedFromReturnedValues<AANoFPClass, AANoFPClassImpl,
10630 AANoFPClassImpl::StateType, false,
10631 Attribute::None, false>(IRP, A) {}
10632
10633 /// See AbstractAttribute::trackStatistics()
10634 void trackStatistics() const override {
10636 }
10637};
10638
10639struct AANoFPClassArgument final
10640 : AAArgumentFromCallSiteArguments<AANoFPClass, AANoFPClassImpl> {
10641 AANoFPClassArgument(const IRPosition &IRP, Attributor &A)
10642 : AAArgumentFromCallSiteArguments<AANoFPClass, AANoFPClassImpl>(IRP, A) {}
10643
10644 /// See AbstractAttribute::trackStatistics()
10645 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nofpclass) }
10646};
10647
10648struct AANoFPClassCallSiteArgument final : AANoFPClassFloating {
10649 AANoFPClassCallSiteArgument(const IRPosition &IRP, Attributor &A)
10650 : AANoFPClassFloating(IRP, A) {}
10651
10652 /// See AbstractAttribute::trackStatistics()
10653 void trackStatistics() const override {
10655 }
10656};
10657
10658struct AANoFPClassCallSiteReturned final
10659 : AACalleeToCallSite<AANoFPClass, AANoFPClassImpl> {
10660 AANoFPClassCallSiteReturned(const IRPosition &IRP, Attributor &A)
10661 : AACalleeToCallSite<AANoFPClass, AANoFPClassImpl>(IRP, A) {}
10662
10663 /// See AbstractAttribute::trackStatistics()
10664 void trackStatistics() const override {
10666 }
10667};
10668
10669struct AACallEdgesImpl : public AACallEdges {
10670 AACallEdgesImpl(const IRPosition &IRP, Attributor &A) : AACallEdges(IRP, A) {}
10671
10672 const SetVector<Function *> &getOptimisticEdges() const override {
10673 return CalledFunctions;
10674 }
10675
10676 bool hasUnknownCallee() const override { return HasUnknownCallee; }
10677
10678 bool hasNonAsmUnknownCallee() const override {
10679 return HasUnknownCalleeNonAsm;
10680 }
10681
10682 const std::string getAsStr(Attributor *A) const override {
10683 return "CallEdges[" + std::to_string(HasUnknownCallee) + "," +
10684 std::to_string(CalledFunctions.size()) + "]";
10685 }
10686
10687 void trackStatistics() const override {}
10688
10689protected:
10690 void addCalledFunction(Function *Fn, ChangeStatus &Change) {
10691 if (CalledFunctions.insert(Fn)) {
10692 Change = ChangeStatus::CHANGED;
10693 LLVM_DEBUG(dbgs() << "[AACallEdges] New call edge: " << Fn->getName()
10694 << "\n");
10695 }
10696 }
10697
10698 void setHasUnknownCallee(bool NonAsm, ChangeStatus &Change) {
10699 if (!HasUnknownCallee)
10700 Change = ChangeStatus::CHANGED;
10701 if (NonAsm && !HasUnknownCalleeNonAsm)
10702 Change = ChangeStatus::CHANGED;
10703 HasUnknownCalleeNonAsm |= NonAsm;
10704 HasUnknownCallee = true;
10705 }
10706
10707private:
10708 /// Optimistic set of functions that might be called by this position.
10709 SetVector<Function *> CalledFunctions;
10710
10711 /// Is there any call with a unknown callee.
10712 bool HasUnknownCallee = false;
10713
10714 /// Is there any call with a unknown callee, excluding any inline asm.
10715 bool HasUnknownCalleeNonAsm = false;
10716};
10717
10718struct AACallEdgesCallSite : public AACallEdgesImpl {
10719 AACallEdgesCallSite(const IRPosition &IRP, Attributor &A)
10720 : AACallEdgesImpl(IRP, A) {}
10721 /// See AbstractAttribute::updateImpl(...).
10722 ChangeStatus updateImpl(Attributor &A) override {
10723 ChangeStatus Change = ChangeStatus::UNCHANGED;
10724
10725 auto VisitValue = [&](Value &V, const Instruction *CtxI) -> bool {
10726 if (Function *Fn = dyn_cast<Function>(&V)) {
10727 addCalledFunction(Fn, Change);
10728 } else {
10729 LLVM_DEBUG(dbgs() << "[AACallEdges] Unrecognized value: " << V << "\n");
10730 setHasUnknownCallee(true, Change);
10731 }
10732
10733 // Explore all values.
10734 return true;
10735 };
10736
10738 // Process any value that we might call.
10739 auto ProcessCalledOperand = [&](Value *V, Instruction *CtxI) {
10740 if (isa<Constant>(V)) {
10741 VisitValue(*V, CtxI);
10742 return;
10743 }
10744
10745 bool UsedAssumedInformation = false;
10746 Values.clear();
10747 if (!A.getAssumedSimplifiedValues(IRPosition::value(*V), *this, Values,
10748 AA::AnyScope, UsedAssumedInformation)) {
10749 Values.push_back({*V, CtxI});
10750 }
10751 for (auto &VAC : Values)
10752 VisitValue(*VAC.getValue(), VAC.getCtxI());
10753 };
10754
10755 CallBase *CB = cast<CallBase>(getCtxI());
10756
10757 if (auto *IA = dyn_cast<InlineAsm>(CB->getCalledOperand())) {
10758 if (IA->hasSideEffects() &&
10759 !hasAssumption(*CB->getCaller(), "ompx_no_call_asm") &&
10760 !hasAssumption(*CB, "ompx_no_call_asm")) {
10761 setHasUnknownCallee(false, Change);
10762 }
10763 return Change;
10764 }
10765
10766 if (CB->isIndirectCall())
10767 if (auto *IndirectCallAA = A.getAAFor<AAIndirectCallInfo>(
10768 *this, getIRPosition(), DepClassTy::OPTIONAL))
10769 if (IndirectCallAA->foreachCallee(
10770 [&](Function *Fn) { return VisitValue(*Fn, CB); }))
10771 return Change;
10772
10773 // The most simple case.
10774 ProcessCalledOperand(CB->getCalledOperand(), CB);
10775
10776 // Process callback functions.
10777 SmallVector<const Use *, 4u> CallbackUses;
10778 AbstractCallSite::getCallbackUses(*CB, CallbackUses);
10779 for (const Use *U : CallbackUses)
10780 ProcessCalledOperand(U->get(), CB);
10781
10782 return Change;
10783 }
10784};
10785
10786struct AACallEdgesFunction : public AACallEdgesImpl {
10787 AACallEdgesFunction(const IRPosition &IRP, Attributor &A)
10788 : AACallEdgesImpl(IRP, A) {}
10789
10790 /// See AbstractAttribute::updateImpl(...).
10791 ChangeStatus updateImpl(Attributor &A) override {
10792 ChangeStatus Change = ChangeStatus::UNCHANGED;
10793
10794 auto ProcessCallInst = [&](Instruction &Inst) {
10795 CallBase &CB = cast<CallBase>(Inst);
10796
10797 auto *CBEdges = A.getAAFor<AACallEdges>(
10798 *this, IRPosition::callsite_function(CB), DepClassTy::REQUIRED);
10799 if (!CBEdges)
10800 return false;
10801 if (CBEdges->hasNonAsmUnknownCallee())
10802 setHasUnknownCallee(true, Change);
10803 if (CBEdges->hasUnknownCallee())
10804 setHasUnknownCallee(false, Change);
10805
10806 for (Function *F : CBEdges->getOptimisticEdges())
10807 addCalledFunction(F, Change);
10808
10809 return true;
10810 };
10811
10812 // Visit all callable instructions.
10813 bool UsedAssumedInformation = false;
10814 if (!A.checkForAllCallLikeInstructions(ProcessCallInst, *this,
10815 UsedAssumedInformation,
10816 /* CheckBBLivenessOnly */ true)) {
10817 // If we haven't looked at all call like instructions, assume that there
10818 // are unknown callees.
10819 setHasUnknownCallee(true, Change);
10820 }
10821
10822 return Change;
10823 }
10824};
10825
10826/// -------------------AAInterFnReachability Attribute--------------------------
10827
10828struct AAInterFnReachabilityFunction
10829 : public CachedReachabilityAA<AAInterFnReachability, Function> {
10830 using Base = CachedReachabilityAA<AAInterFnReachability, Function>;
10831 AAInterFnReachabilityFunction(const IRPosition &IRP, Attributor &A)
10832 : Base(IRP, A) {}
10833
10834 bool instructionCanReach(
10835 Attributor &A, const Instruction &From, const Function &To,
10836 const AA::InstExclusionSetTy *ExclusionSet) const override {
10837 assert(From.getFunction() == getAnchorScope() && "Queried the wrong AA!");
10838 auto *NonConstThis = const_cast<AAInterFnReachabilityFunction *>(this);
10839
10840 RQITy StackRQI(A, From, To, ExclusionSet, false);
10841 RQITy::Reachable Result;
10842 if (!NonConstThis->checkQueryCache(A, StackRQI, Result))
10843 return NonConstThis->isReachableImpl(A, StackRQI,
10844 /*IsTemporaryRQI=*/true);
10845 return Result == RQITy::Reachable::Yes;
10846 }
10847
10848 bool isReachableImpl(Attributor &A, RQITy &RQI,
10849 bool IsTemporaryRQI) override {
10850 const Instruction *EntryI =
10851 &RQI.From->getFunction()->getEntryBlock().front();
10852 if (EntryI != RQI.From &&
10853 !instructionCanReach(A, *EntryI, *RQI.To, nullptr))
10854 return rememberResult(A, RQITy::Reachable::No, RQI, false,
10855 IsTemporaryRQI);
10856
10857 auto CheckReachableCallBase = [&](CallBase *CB) {
10858 auto *CBEdges = A.getAAFor<AACallEdges>(
10859 *this, IRPosition::callsite_function(*CB), DepClassTy::OPTIONAL);
10860 if (!CBEdges || !CBEdges->getState().isValidState())
10861 return false;
10862 // TODO Check To backwards in this case.
10863 if (CBEdges->hasUnknownCallee())
10864 return false;
10865
10866 for (Function *Fn : CBEdges->getOptimisticEdges()) {
10867 if (Fn == RQI.To)
10868 return false;
10869
10870 if (Fn->isDeclaration()) {
10871 if (Fn->hasFnAttribute(Attribute::NoCallback))
10872 continue;
10873 // TODO Check To backwards in this case.
10874 return false;
10875 }
10876
10877 if (Fn == getAnchorScope()) {
10878 if (EntryI == RQI.From)
10879 continue;
10880 return false;
10881 }
10882
10883 const AAInterFnReachability *InterFnReachability =
10884 A.getAAFor<AAInterFnReachability>(*this, IRPosition::function(*Fn),
10885 DepClassTy::OPTIONAL);
10886
10887 const Instruction &FnFirstInst = Fn->getEntryBlock().front();
10888 if (!InterFnReachability ||
10889 InterFnReachability->instructionCanReach(A, FnFirstInst, *RQI.To,
10890 RQI.ExclusionSet))
10891 return false;
10892 }
10893 return true;
10894 };
10895
10896 const auto *IntraFnReachability = A.getAAFor<AAIntraFnReachability>(
10897 *this, IRPosition::function(*RQI.From->getFunction()),
10898 DepClassTy::OPTIONAL);
10899
10900 // Determine call like instructions that we can reach from the inst.
10901 auto CheckCallBase = [&](Instruction &CBInst) {
10902 // There are usually less nodes in the call graph, check inter function
10903 // reachability first.
10904 if (CheckReachableCallBase(cast<CallBase>(&CBInst)))
10905 return true;
10906 return IntraFnReachability && !IntraFnReachability->isAssumedReachable(
10907 A, *RQI.From, CBInst, RQI.ExclusionSet);
10908 };
10909
10910 bool UsedExclusionSet = /* conservative */ true;
10911 bool UsedAssumedInformation = false;
10912 if (!A.checkForAllCallLikeInstructions(CheckCallBase, *this,
10913 UsedAssumedInformation,
10914 /* CheckBBLivenessOnly */ true))
10915 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
10916 IsTemporaryRQI);
10917
10918 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
10919 IsTemporaryRQI);
10920 }
10921
10922 void trackStatistics() const override {}
10923};
10924} // namespace
10925
10926template <typename AAType>
10927static std::optional<Constant *>
10929 const IRPosition &IRP, Type &Ty) {
10930 if (!Ty.isIntegerTy())
10931 return nullptr;
10932
10933 // This will also pass the call base context.
10934 const auto *AA = A.getAAFor<AAType>(QueryingAA, IRP, DepClassTy::NONE);
10935 if (!AA)
10936 return nullptr;
10937
10938 std::optional<Constant *> COpt = AA->getAssumedConstant(A);
10939
10940 if (!COpt.has_value()) {
10941 A.recordDependence(*AA, QueryingAA, DepClassTy::OPTIONAL);
10942 return std::nullopt;
10943 }
10944 if (auto *C = *COpt) {
10945 A.recordDependence(*AA, QueryingAA, DepClassTy::OPTIONAL);
10946 return C;
10947 }
10948 return nullptr;
10949}
10950
10952 Attributor &A, const AbstractAttribute &AA, const IRPosition &IRP,
10954 Type &Ty = *IRP.getAssociatedType();
10955 std::optional<Value *> V;
10956 for (auto &It : Values) {
10957 V = AA::combineOptionalValuesInAAValueLatice(V, It.getValue(), &Ty);
10958 if (V.has_value() && !*V)
10959 break;
10960 }
10961 if (!V.has_value())
10962 return UndefValue::get(&Ty);
10963 return *V;
10964}
10965
10966namespace {
10967struct AAPotentialValuesImpl : AAPotentialValues {
10968 using StateType = PotentialLLVMValuesState;
10969
10970 AAPotentialValuesImpl(const IRPosition &IRP, Attributor &A)
10971 : AAPotentialValues(IRP, A) {}
10972
10973 /// See AbstractAttribute::initialize(..).
10974 void initialize(Attributor &A) override {
10975 if (A.hasSimplificationCallback(getIRPosition())) {
10976 indicatePessimisticFixpoint();
10977 return;
10978 }
10979 Value *Stripped = getAssociatedValue().stripPointerCasts();
10980 if (isa<Constant>(Stripped) && !isa<ConstantExpr>(Stripped)) {
10981 addValue(A, getState(), *Stripped, getCtxI(), AA::AnyScope,
10982 getAnchorScope());
10983 indicateOptimisticFixpoint();
10984 return;
10985 }
10986 AAPotentialValues::initialize(A);
10987 }
10988
10989 /// See AbstractAttribute::getAsStr().
10990 const std::string getAsStr(Attributor *A) const override {
10991 std::string Str;
10992 llvm::raw_string_ostream OS(Str);
10993 OS << getState();
10994 return Str;
10995 }
10996
10997 template <typename AAType>
10998 static std::optional<Value *> askOtherAA(Attributor &A,
10999 const AbstractAttribute &AA,
11000 const IRPosition &IRP, Type &Ty) {
11002 return &IRP.getAssociatedValue();
11003 std::optional<Constant *> C = askForAssumedConstant<AAType>(A, AA, IRP, Ty);
11004 if (!C)
11005 return std::nullopt;
11006 if (*C)
11007 if (auto *CC = AA::getWithType(**C, Ty))
11008 return CC;
11009 return nullptr;
11010 }
11011
11012 virtual void addValue(Attributor &A, StateType &State, Value &V,
11013 const Instruction *CtxI, AA::ValueScope S,
11014 Function *AnchorScope) const {
11015
11016 IRPosition ValIRP = IRPosition::value(V);
11017 if (auto *CB = dyn_cast_or_null<CallBase>(CtxI)) {
11018 for (const auto &U : CB->args()) {
11019 if (U.get() != &V)
11020 continue;
11021 ValIRP = IRPosition::callsite_argument(*CB, CB->getArgOperandNo(&U));
11022 break;
11023 }
11024 }
11025
11026 Value *VPtr = &V;
11027 if (ValIRP.getAssociatedType()->isIntegerTy()) {
11028 Type &Ty = *getAssociatedType();
11029 std::optional<Value *> SimpleV =
11030 askOtherAA<AAValueConstantRange>(A, *this, ValIRP, Ty);
11031 if (SimpleV.has_value() && !*SimpleV) {
11032 auto *PotentialConstantsAA = A.getAAFor<AAPotentialConstantValues>(
11033 *this, ValIRP, DepClassTy::OPTIONAL);
11034 if (PotentialConstantsAA && PotentialConstantsAA->isValidState()) {
11035 for (const auto &It : PotentialConstantsAA->getAssumedSet())
11036 State.unionAssumed({{*ConstantInt::get(&Ty, It), nullptr}, S});
11037 if (PotentialConstantsAA->undefIsContained())
11038 State.unionAssumed({{*UndefValue::get(&Ty), nullptr}, S});
11039 return;
11040 }
11041 }
11042 if (!SimpleV.has_value())
11043 return;
11044
11045 if (*SimpleV)
11046 VPtr = *SimpleV;
11047 }
11048
11049 if (isa<ConstantInt>(VPtr))
11050 CtxI = nullptr;
11051 if (!AA::isValidInScope(*VPtr, AnchorScope))
11053
11054 State.unionAssumed({{*VPtr, CtxI}, S});
11055 }
11056
11057 /// Helper struct to tie a value+context pair together with the scope for
11058 /// which this is the simplified version.
11059 struct ItemInfo {
11060 AA::ValueAndContext I;
11062
11063 bool operator==(const ItemInfo &II) const {
11064 return II.I == I && II.S == S;
11065 };
11066 bool operator<(const ItemInfo &II) const {
11067 return std::tie(I, S) < std::tie(II.I, II.S);
11068 };
11069 };
11070
11071 bool recurseForValue(Attributor &A, const IRPosition &IRP, AA::ValueScope S) {
11072 SmallMapVector<AA::ValueAndContext, int, 8> ValueScopeMap;
11073 for (auto CS : {AA::Intraprocedural, AA::Interprocedural}) {
11074 if (!(CS & S))
11075 continue;
11076
11077 bool UsedAssumedInformation = false;
11079 if (!A.getAssumedSimplifiedValues(IRP, this, Values, CS,
11080 UsedAssumedInformation))
11081 return false;
11082
11083 for (auto &It : Values)
11084 ValueScopeMap[It] += CS;
11085 }
11086 for (auto &It : ValueScopeMap)
11087 addValue(A, getState(), *It.first.getValue(), It.first.getCtxI(),
11088 AA::ValueScope(It.second), getAnchorScope());
11089
11090 return true;
11091 }
11092
11093 void giveUpOnIntraprocedural(Attributor &A) {
11094 auto NewS = StateType::getBestState(getState());
11095 for (const auto &It : getAssumedSet()) {
11096 if (It.second == AA::Intraprocedural)
11097 continue;
11098 addValue(A, NewS, *It.first.getValue(), It.first.getCtxI(),
11099 AA::Interprocedural, getAnchorScope());
11100 }
11101 assert(!undefIsContained() && "Undef should be an explicit value!");
11102 addValue(A, NewS, getAssociatedValue(), getCtxI(), AA::Intraprocedural,
11103 getAnchorScope());
11104 getState() = NewS;
11105 }
11106
11107 /// See AbstractState::indicatePessimisticFixpoint(...).
11108 ChangeStatus indicatePessimisticFixpoint() override {
11109 getState() = StateType::getBestState(getState());
11110 getState().unionAssumed({{getAssociatedValue(), getCtxI()}, AA::AnyScope});
11111 AAPotentialValues::indicateOptimisticFixpoint();
11112 return ChangeStatus::CHANGED;
11113 }
11114
11115 /// See AbstractAttribute::updateImpl(...).
11116 ChangeStatus updateImpl(Attributor &A) override {
11117 return indicatePessimisticFixpoint();
11118 }
11119
11120 /// See AbstractAttribute::manifest(...).
11121 ChangeStatus manifest(Attributor &A) override {
11124 Values.clear();
11125 if (!getAssumedSimplifiedValues(A, Values, S))
11126 continue;
11127 Value &OldV = getAssociatedValue();
11128 if (isa<UndefValue>(OldV))
11129 continue;
11130 Value *NewV = getSingleValue(A, *this, getIRPosition(), Values);
11131 if (!NewV || NewV == &OldV)
11132 continue;
11133 if (getCtxI() &&
11134 !AA::isValidAtPosition({*NewV, *getCtxI()}, A.getInfoCache()))
11135 continue;
11136 if (A.changeAfterManifest(getIRPosition(), *NewV))
11137 return ChangeStatus::CHANGED;
11138 }
11139 return ChangeStatus::UNCHANGED;
11140 }
11141
11142 bool getAssumedSimplifiedValues(
11143 Attributor &A, SmallVectorImpl<AA::ValueAndContext> &Values,
11144 AA::ValueScope S, bool RecurseForSelectAndPHI = false) const override {
11145 if (!isValidState())
11146 return false;
11147 bool UsedAssumedInformation = false;
11148 for (const auto &It : getAssumedSet())
11149 if (It.second & S) {
11150 if (RecurseForSelectAndPHI && (isa<PHINode>(It.first.getValue()) ||
11151 isa<SelectInst>(It.first.getValue()))) {
11152 if (A.getAssumedSimplifiedValues(
11153 IRPosition::inst(*cast<Instruction>(It.first.getValue())),
11154 this, Values, S, UsedAssumedInformation))
11155 continue;
11156 }
11157 Values.push_back(It.first);
11158 }
11159 assert(!undefIsContained() && "Undef should be an explicit value!");
11160 return true;
11161 }
11162};
11163
11164struct AAPotentialValuesFloating : AAPotentialValuesImpl {
11165 AAPotentialValuesFloating(const IRPosition &IRP, Attributor &A)
11166 : AAPotentialValuesImpl(IRP, A) {}
11167
11168 /// See AbstractAttribute::updateImpl(...).
11169 ChangeStatus updateImpl(Attributor &A) override {
11170 auto AssumedBefore = getAssumed();
11171
11172 genericValueTraversal(A, &getAssociatedValue());
11173
11174 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
11175 : ChangeStatus::CHANGED;
11176 }
11177
11178 /// Helper struct to remember which AAIsDead instances we actually used.
11179 struct LivenessInfo {
11180 const AAIsDead *LivenessAA = nullptr;
11181 bool AnyDead = false;
11182 };
11183
11184 /// Check if \p Cmp is a comparison we can simplify.
11185 ///
11186 /// We handle multiple cases, one in which at least one operand is an
11187 /// (assumed) nullptr. If so, try to simplify it using AANonNull on the other
11188 /// operand. Return true if successful, in that case Worklist will be updated.
11189 bool handleCmp(Attributor &A, Value &Cmp, Value *LHS, Value *RHS,
11190 CmpInst::Predicate Pred, ItemInfo II,
11191 SmallVectorImpl<ItemInfo> &Worklist) {
11192
11193 // Simplify the operands first.
11194 bool UsedAssumedInformation = false;
11195 SmallVector<AA::ValueAndContext> LHSValues, RHSValues;
11196 auto GetSimplifiedValues = [&](Value &V,
11198 if (!A.getAssumedSimplifiedValues(
11199 IRPosition::value(V, getCallBaseContext()), this, Values,
11200 AA::Intraprocedural, UsedAssumedInformation)) {
11201 Values.clear();
11202 Values.push_back(AA::ValueAndContext{V, II.I.getCtxI()});
11203 }
11204 return Values.empty();
11205 };
11206 if (GetSimplifiedValues(*LHS, LHSValues))
11207 return true;
11208 if (GetSimplifiedValues(*RHS, RHSValues))
11209 return true;
11210
11211 LLVMContext &Ctx = LHS->getContext();
11212
11213 InformationCache &InfoCache = A.getInfoCache();
11214 Instruction *CmpI = dyn_cast<Instruction>(&Cmp);
11215 Function *F = CmpI ? CmpI->getFunction() : nullptr;
11216 const auto *DT =
11217 F ? InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F)
11218 : nullptr;
11219 const auto *TLI =
11220 F ? A.getInfoCache().getTargetLibraryInfoForFunction(*F) : nullptr;
11221 auto *AC =
11222 F ? InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F)
11223 : nullptr;
11224
11225 const DataLayout &DL = A.getDataLayout();
11226 SimplifyQuery Q(DL, TLI, DT, AC, CmpI);
11227
11228 auto CheckPair = [&](Value &LHSV, Value &RHSV) {
11229 if (isa<UndefValue>(LHSV) || isa<UndefValue>(RHSV)) {
11230 addValue(A, getState(), *UndefValue::get(Cmp.getType()),
11231 /* CtxI */ nullptr, II.S, getAnchorScope());
11232 return true;
11233 }
11234
11235 // Handle the trivial case first in which we don't even need to think
11236 // about null or non-null.
11237 if (&LHSV == &RHSV &&
11239 Constant *NewV = ConstantInt::get(Type::getInt1Ty(Ctx),
11241 addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S,
11242 getAnchorScope());
11243 return true;
11244 }
11245
11246 auto *TypedLHS = AA::getWithType(LHSV, *LHS->getType());
11247 auto *TypedRHS = AA::getWithType(RHSV, *RHS->getType());
11248 if (TypedLHS && TypedRHS) {
11249 Value *NewV = simplifyCmpInst(Pred, TypedLHS, TypedRHS, Q);
11250 if (NewV && NewV != &Cmp) {
11251 addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S,
11252 getAnchorScope());
11253 return true;
11254 }
11255 }
11256
11257 // From now on we only handle equalities (==, !=).
11258 if (!CmpInst::isEquality(Pred))
11259 return false;
11260
11261 bool LHSIsNull = isa<ConstantPointerNull>(LHSV);
11262 bool RHSIsNull = isa<ConstantPointerNull>(RHSV);
11263 if (!LHSIsNull && !RHSIsNull)
11264 return false;
11265
11266 // Left is the nullptr ==/!= non-nullptr case. We'll use AANonNull on the
11267 // non-nullptr operand and if we assume it's non-null we can conclude the
11268 // result of the comparison.
11269 assert((LHSIsNull || RHSIsNull) &&
11270 "Expected nullptr versus non-nullptr comparison at this point");
11271
11272 // The index is the operand that we assume is not null.
11273 unsigned PtrIdx = LHSIsNull;
11274 bool IsKnownNonNull;
11275 bool IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>(
11276 A, this, IRPosition::value(*(PtrIdx ? &RHSV : &LHSV)),
11277 DepClassTy::REQUIRED, IsKnownNonNull);
11278 if (!IsAssumedNonNull)
11279 return false;
11280
11281 // The new value depends on the predicate, true for != and false for ==.
11282 Constant *NewV =
11283 ConstantInt::get(Type::getInt1Ty(Ctx), Pred == CmpInst::ICMP_NE);
11284 addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S,
11285 getAnchorScope());
11286 return true;
11287 };
11288
11289 for (auto &LHSValue : LHSValues)
11290 for (auto &RHSValue : RHSValues)
11291 if (!CheckPair(*LHSValue.getValue(), *RHSValue.getValue()))
11292 return false;
11293 return true;
11294 }
11295
11296 bool handleSelectInst(Attributor &A, SelectInst &SI, ItemInfo II,
11297 SmallVectorImpl<ItemInfo> &Worklist) {
11298 const Instruction *CtxI = II.I.getCtxI();
11299 bool UsedAssumedInformation = false;
11300
11301 std::optional<Constant *> C =
11302 A.getAssumedConstant(*SI.getCondition(), *this, UsedAssumedInformation);
11303 bool NoValueYet = !C.has_value();
11304 if (NoValueYet || isa_and_nonnull<UndefValue>(*C))
11305 return true;
11306 if (auto *CI = dyn_cast_or_null<ConstantInt>(*C)) {
11307 if (CI->isZero())
11308 Worklist.push_back({{*SI.getFalseValue(), CtxI}, II.S});
11309 else
11310 Worklist.push_back({{*SI.getTrueValue(), CtxI}, II.S});
11311 } else if (&SI == &getAssociatedValue()) {
11312 // We could not simplify the condition, assume both values.
11313 Worklist.push_back({{*SI.getTrueValue(), CtxI}, II.S});
11314 Worklist.push_back({{*SI.getFalseValue(), CtxI}, II.S});
11315 } else {
11316 std::optional<Value *> SimpleV = A.getAssumedSimplified(
11317 IRPosition::inst(SI), *this, UsedAssumedInformation, II.S);
11318 if (!SimpleV.has_value())
11319 return true;
11320 if (*SimpleV) {
11321 addValue(A, getState(), **SimpleV, CtxI, II.S, getAnchorScope());
11322 return true;
11323 }
11324 return false;
11325 }
11326 return true;
11327 }
11328
11329 bool handleLoadInst(Attributor &A, LoadInst &LI, ItemInfo II,
11330 SmallVectorImpl<ItemInfo> &Worklist) {
11331 SmallSetVector<Value *, 4> PotentialCopies;
11332 SmallSetVector<Instruction *, 4> PotentialValueOrigins;
11333 bool UsedAssumedInformation = false;
11334 if (!AA::getPotentiallyLoadedValues(A, LI, PotentialCopies,
11335 PotentialValueOrigins, *this,
11336 UsedAssumedInformation,
11337 /* OnlyExact */ true)) {
11338 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Failed to get potentially "
11339 "loaded values for load instruction "
11340 << LI << "\n");
11341 return false;
11342 }
11343
11344 // Do not simplify loads that are only used in llvm.assume if we cannot also
11345 // remove all stores that may feed into the load. The reason is that the
11346 // assume is probably worth something as long as the stores are around.
11347 InformationCache &InfoCache = A.getInfoCache();
11348 if (InfoCache.isOnlyUsedByAssume(LI)) {
11349 if (!llvm::all_of(PotentialValueOrigins, [&](Instruction *I) {
11350 if (!I || isa<AssumeInst>(I))
11351 return true;
11352 if (auto *SI = dyn_cast<StoreInst>(I))
11353 return A.isAssumedDead(SI->getOperandUse(0), this,
11354 /* LivenessAA */ nullptr,
11355 UsedAssumedInformation,
11356 /* CheckBBLivenessOnly */ false);
11357 return A.isAssumedDead(*I, this, /* LivenessAA */ nullptr,
11358 UsedAssumedInformation,
11359 /* CheckBBLivenessOnly */ false);
11360 })) {
11361 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Load is onl used by assumes "
11362 "and we cannot delete all the stores: "
11363 << LI << "\n");
11364 return false;
11365 }
11366 }
11367
11368 // Values have to be dynamically unique or we loose the fact that a
11369 // single llvm::Value might represent two runtime values (e.g.,
11370 // stack locations in different recursive calls).
11371 const Instruction *CtxI = II.I.getCtxI();
11372 bool ScopeIsLocal = (II.S & AA::Intraprocedural);
11373 bool AllLocal = ScopeIsLocal;
11374 bool DynamicallyUnique = llvm::all_of(PotentialCopies, [&](Value *PC) {
11375 AllLocal &= AA::isValidInScope(*PC, getAnchorScope());
11376 return AA::isDynamicallyUnique(A, *this, *PC);
11377 });
11378 if (!DynamicallyUnique) {
11379 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Not all potentially loaded "
11380 "values are dynamically unique: "
11381 << LI << "\n");
11382 return false;
11383 }
11384
11385 for (auto *PotentialCopy : PotentialCopies) {
11386 if (AllLocal) {
11387 Worklist.push_back({{*PotentialCopy, CtxI}, II.S});
11388 } else {
11389 Worklist.push_back({{*PotentialCopy, CtxI}, AA::Interprocedural});
11390 }
11391 }
11392 if (!AllLocal && ScopeIsLocal)
11393 addValue(A, getState(), LI, CtxI, AA::Intraprocedural, getAnchorScope());
11394 return true;
11395 }
11396
11397 bool handlePHINode(
11398 Attributor &A, PHINode &PHI, ItemInfo II,
11399 SmallVectorImpl<ItemInfo> &Worklist,
11400 SmallMapVector<const Function *, LivenessInfo, 4> &LivenessAAs) {
11401 auto GetLivenessInfo = [&](const Function &F) -> LivenessInfo & {
11402 LivenessInfo &LI = LivenessAAs[&F];
11403 if (!LI.LivenessAA)
11404 LI.LivenessAA = A.getAAFor<AAIsDead>(*this, IRPosition::function(F),
11405 DepClassTy::NONE);
11406 return LI;
11407 };
11408
11409 if (&PHI == &getAssociatedValue()) {
11410 LivenessInfo &LI = GetLivenessInfo(*PHI.getFunction());
11411 const auto *CI =
11412 A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>(
11413 *PHI.getFunction());
11414
11415 CycleRef C;
11416 bool CyclePHI = mayBeInCycle(CI, &PHI, /* HeaderOnly */ true, &C);
11417 for (unsigned u = 0, e = PHI.getNumIncomingValues(); u < e; u++) {
11418 BasicBlock *IncomingBB = PHI.getIncomingBlock(u);
11419 if (LI.LivenessAA &&
11420 LI.LivenessAA->isEdgeDead(IncomingBB, PHI.getParent())) {
11421 LI.AnyDead = true;
11422 continue;
11423 }
11424 Value *V = PHI.getIncomingValue(u);
11425 if (V == &PHI)
11426 continue;
11427
11428 // If the incoming value is not the PHI but an instruction in the same
11429 // cycle we might have multiple versions of it flying around.
11430 if (CyclePHI && isa<Instruction>(V) &&
11431 (!C || CI->contains(C, cast<Instruction>(V)->getParent())))
11432 return false;
11433
11434 Worklist.push_back({{*V, IncomingBB->getTerminator()}, II.S});
11435 }
11436 return true;
11437 }
11438
11439 bool UsedAssumedInformation = false;
11440 std::optional<Value *> SimpleV = A.getAssumedSimplified(
11441 IRPosition::inst(PHI), *this, UsedAssumedInformation, II.S);
11442 if (!SimpleV.has_value())
11443 return true;
11444 if (!(*SimpleV))
11445 return false;
11446 addValue(A, getState(), **SimpleV, &PHI, II.S, getAnchorScope());
11447 return true;
11448 }
11449
11450 /// Use the generic, non-optimistic InstSimplfy functionality if we managed to
11451 /// simplify any operand of the instruction \p I. Return true if successful,
11452 /// in that case Worklist will be updated.
11453 bool handleGenericInst(Attributor &A, Instruction &I, ItemInfo II,
11454 SmallVectorImpl<ItemInfo> &Worklist) {
11455 bool SomeSimplified = false;
11456 bool UsedAssumedInformation = false;
11457
11458 SmallVector<Value *, 8> NewOps(I.getNumOperands());
11459 int Idx = 0;
11460 for (Value *Op : I.operands()) {
11461 const auto &SimplifiedOp = A.getAssumedSimplified(
11462 IRPosition::value(*Op, getCallBaseContext()), *this,
11463 UsedAssumedInformation, AA::Intraprocedural);
11464 // If we are not sure about any operand we are not sure about the entire
11465 // instruction, we'll wait.
11466 if (!SimplifiedOp.has_value())
11467 return true;
11468
11469 if (*SimplifiedOp)
11470 NewOps[Idx] = *SimplifiedOp;
11471 else
11472 NewOps[Idx] = Op;
11473
11474 SomeSimplified |= (NewOps[Idx] != Op);
11475 ++Idx;
11476 }
11477
11478 // We won't bother with the InstSimplify interface if we didn't simplify any
11479 // operand ourselves.
11480 if (!SomeSimplified)
11481 return false;
11482
11483 InformationCache &InfoCache = A.getInfoCache();
11484 Function *F = I.getFunction();
11485 const auto *DT =
11486 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F);
11487 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
11488 auto *AC = InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F);
11489
11490 const DataLayout &DL = I.getDataLayout();
11491 SimplifyQuery Q(DL, TLI, DT, AC, &I);
11492 Value *NewV = simplifyInstructionWithOperands(&I, NewOps, Q);
11493 if (!NewV || NewV == &I)
11494 return false;
11495
11496 LLVM_DEBUG(dbgs() << "Generic inst " << I << " assumed simplified to "
11497 << *NewV << "\n");
11498 Worklist.push_back({{*NewV, II.I.getCtxI()}, II.S});
11499 return true;
11500 }
11501
11503 Attributor &A, Instruction &I, ItemInfo II,
11504 SmallVectorImpl<ItemInfo> &Worklist,
11505 SmallMapVector<const Function *, LivenessInfo, 4> &LivenessAAs) {
11506 if (auto *CI = dyn_cast<CmpInst>(&I))
11507 return handleCmp(A, *CI, CI->getOperand(0), CI->getOperand(1),
11508 CI->getPredicate(), II, Worklist);
11509
11510 switch (I.getOpcode()) {
11511 case Instruction::Select:
11512 return handleSelectInst(A, cast<SelectInst>(I), II, Worklist);
11513 case Instruction::PHI:
11514 return handlePHINode(A, cast<PHINode>(I), II, Worklist, LivenessAAs);
11515 case Instruction::Load:
11516 return handleLoadInst(A, cast<LoadInst>(I), II, Worklist);
11517 default:
11518 return handleGenericInst(A, I, II, Worklist);
11519 };
11520 return false;
11521 }
11522
11523 void genericValueTraversal(Attributor &A, Value *InitialV) {
11524 SmallMapVector<const Function *, LivenessInfo, 4> LivenessAAs;
11525
11526 SmallSet<ItemInfo, 16> Visited;
11528 Worklist.push_back({{*InitialV, getCtxI()}, AA::AnyScope});
11529
11530 int Iteration = 0;
11531 do {
11532 ItemInfo II = Worklist.pop_back_val();
11533 Value *V = II.I.getValue();
11534 assert(V);
11535 const Instruction *CtxI = II.I.getCtxI();
11536 AA::ValueScope S = II.S;
11537
11538 // Check if we should process the current value. To prevent endless
11539 // recursion keep a record of the values we followed!
11540 if (!Visited.insert(II).second)
11541 continue;
11542
11543 // Make sure we limit the compile time for complex expressions.
11544 if (Iteration++ >= MaxPotentialValuesIterations) {
11545 LLVM_DEBUG(dbgs() << "Generic value traversal reached iteration limit: "
11546 << Iteration << "!\n");
11547 addValue(A, getState(), *V, CtxI, S, getAnchorScope());
11548 continue;
11549 }
11550
11551 // Explicitly look through calls with a "returned" attribute if we do
11552 // not have a pointer as stripPointerCasts only works on them.
11553 Value *NewV = nullptr;
11554 if (V->getType()->isPointerTy()) {
11555 NewV = AA::getWithType(*V->stripPointerCasts(), *V->getType());
11556 } else {
11557 if (auto *CB = dyn_cast<CallBase>(V))
11558 if (auto *Callee =
11560 for (Argument &Arg : Callee->args())
11561 if (Arg.hasReturnedAttr()) {
11562 NewV = CB->getArgOperand(Arg.getArgNo());
11563 break;
11564 }
11565 }
11566 }
11567 if (NewV && NewV != V) {
11568 Worklist.push_back({{*NewV, CtxI}, S});
11569 continue;
11570 }
11571
11572 if (auto *I = dyn_cast<Instruction>(V)) {
11573 if (simplifyInstruction(A, *I, II, Worklist, LivenessAAs))
11574 continue;
11575 }
11576
11577 if (V != InitialV || isa<Argument>(V))
11578 if (recurseForValue(A, IRPosition::value(*V), II.S))
11579 continue;
11580
11581 // If we haven't stripped anything we give up.
11582 if (V == InitialV && CtxI == getCtxI()) {
11583 indicatePessimisticFixpoint();
11584 return;
11585 }
11586
11587 addValue(A, getState(), *V, CtxI, S, getAnchorScope());
11588 } while (!Worklist.empty());
11589
11590 // If we actually used liveness information so we have to record a
11591 // dependence.
11592 for (auto &It : LivenessAAs)
11593 if (It.second.AnyDead)
11594 A.recordDependence(*It.second.LivenessAA, *this, DepClassTy::OPTIONAL);
11595 }
11596
11597 /// See AbstractAttribute::trackStatistics()
11598 void trackStatistics() const override {
11599 STATS_DECLTRACK_FLOATING_ATTR(potential_values)
11600 }
11601};
11602
11603struct AAPotentialValuesArgument final : AAPotentialValuesImpl {
11604 using Base = AAPotentialValuesImpl;
11605 AAPotentialValuesArgument(const IRPosition &IRP, Attributor &A)
11606 : Base(IRP, A) {}
11607
11608 /// See AbstractAttribute::initialize(..).
11609 void initialize(Attributor &A) override {
11610 auto &Arg = cast<Argument>(getAssociatedValue());
11612 indicatePessimisticFixpoint();
11613 }
11614
11615 /// See AbstractAttribute::updateImpl(...).
11616 ChangeStatus updateImpl(Attributor &A) override {
11617 auto AssumedBefore = getAssumed();
11618
11619 unsigned ArgNo = getCalleeArgNo();
11620
11621 bool UsedAssumedInformation = false;
11623 auto CallSitePred = [&](AbstractCallSite ACS) {
11624 const auto CSArgIRP = IRPosition::callsite_argument(ACS, ArgNo);
11625 if (CSArgIRP.getPositionKind() == IRP_INVALID)
11626 return false;
11627
11628 if (!A.getAssumedSimplifiedValues(CSArgIRP, this, Values,
11630 UsedAssumedInformation))
11631 return false;
11632
11633 return isValidState();
11634 };
11635
11636 if (!A.checkForAllCallSites(CallSitePred, *this,
11637 /* RequireAllCallSites */ true,
11638 UsedAssumedInformation))
11639 return indicatePessimisticFixpoint();
11640
11641 Function *Fn = getAssociatedFunction();
11642 bool AnyNonLocal = false;
11643 for (auto &It : Values) {
11644 if (isa<Constant>(It.getValue())) {
11645 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::AnyScope,
11646 getAnchorScope());
11647 continue;
11648 }
11649 if (!AA::isDynamicallyUnique(A, *this, *It.getValue()))
11650 return indicatePessimisticFixpoint();
11651
11652 if (auto *Arg = dyn_cast<Argument>(It.getValue()))
11653 if (Arg->getParent() == Fn) {
11654 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::AnyScope,
11655 getAnchorScope());
11656 continue;
11657 }
11658 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::Interprocedural,
11659 getAnchorScope());
11660 AnyNonLocal = true;
11661 }
11662 assert(!undefIsContained() && "Undef should be an explicit value!");
11663 if (AnyNonLocal)
11664 giveUpOnIntraprocedural(A);
11665
11666 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
11667 : ChangeStatus::CHANGED;
11668 }
11669
11670 /// See AbstractAttribute::trackStatistics()
11671 void trackStatistics() const override {
11672 STATS_DECLTRACK_ARG_ATTR(potential_values)
11673 }
11674};
11675
11676struct AAPotentialValuesReturned : public AAPotentialValuesFloating {
11677 using Base = AAPotentialValuesFloating;
11678 AAPotentialValuesReturned(const IRPosition &IRP, Attributor &A)
11679 : Base(IRP, A) {}
11680
11681 /// See AbstractAttribute::initialize(..).
11682 void initialize(Attributor &A) override {
11683 Function *F = getAssociatedFunction();
11684 if (!F || F->isDeclaration() || F->getReturnType()->isVoidTy()) {
11685 indicatePessimisticFixpoint();
11686 return;
11687 }
11688
11689 for (Argument &Arg : F->args())
11690 if (Arg.hasReturnedAttr()) {
11691 addValue(A, getState(), Arg, nullptr, AA::AnyScope, F);
11692 ReturnedArg = &Arg;
11693 break;
11694 }
11695 if (!A.isFunctionIPOAmendable(*F) ||
11696 A.hasSimplificationCallback(getIRPosition())) {
11697 if (!ReturnedArg)
11698 indicatePessimisticFixpoint();
11699 else
11700 indicateOptimisticFixpoint();
11701 }
11702 }
11703
11704 /// See AbstractAttribute::updateImpl(...).
11705 ChangeStatus updateImpl(Attributor &A) override {
11706 auto AssumedBefore = getAssumed();
11707 bool UsedAssumedInformation = false;
11708
11710 Function *AnchorScope = getAnchorScope();
11711 auto HandleReturnedValue = [&](Value &V, Instruction *CtxI,
11712 bool AddValues) {
11714 Values.clear();
11715 if (!A.getAssumedSimplifiedValues(IRPosition::value(V), this, Values, S,
11716 UsedAssumedInformation,
11717 /* RecurseForSelectAndPHI */ true))
11718 return false;
11719 if (!AddValues)
11720 continue;
11721
11722 bool AllInterAreIntra = false;
11723 if (S == AA::Interprocedural)
11724 AllInterAreIntra =
11725 llvm::all_of(Values, [&](const AA::ValueAndContext &VAC) {
11726 return AA::isValidInScope(*VAC.getValue(), AnchorScope);
11727 });
11728
11729 for (const AA::ValueAndContext &VAC : Values) {
11730 addValue(A, getState(), *VAC.getValue(),
11731 VAC.getCtxI() ? VAC.getCtxI() : CtxI,
11732 AllInterAreIntra ? AA::AnyScope : S, AnchorScope);
11733 }
11734 if (AllInterAreIntra)
11735 break;
11736 }
11737 return true;
11738 };
11739
11740 if (ReturnedArg) {
11741 HandleReturnedValue(*ReturnedArg, nullptr, true);
11742 } else {
11743 auto RetInstPred = [&](Instruction &RetI) {
11744 bool AddValues = true;
11745 if (isa<PHINode>(RetI.getOperand(0)) ||
11746 isa<SelectInst>(RetI.getOperand(0))) {
11747 addValue(A, getState(), *RetI.getOperand(0), &RetI, AA::AnyScope,
11748 AnchorScope);
11749 AddValues = false;
11750 }
11751 return HandleReturnedValue(*RetI.getOperand(0), &RetI, AddValues);
11752 };
11753
11754 if (!A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret},
11755 UsedAssumedInformation,
11756 /* CheckBBLivenessOnly */ true))
11757 return indicatePessimisticFixpoint();
11758 }
11759
11760 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
11761 : ChangeStatus::CHANGED;
11762 }
11763
11764 ChangeStatus manifest(Attributor &A) override {
11765 if (ReturnedArg)
11766 return ChangeStatus::UNCHANGED;
11768 if (!getAssumedSimplifiedValues(A, Values, AA::ValueScope::Intraprocedural,
11769 /* RecurseForSelectAndPHI */ true))
11770 return ChangeStatus::UNCHANGED;
11771 Value *NewVal = getSingleValue(A, *this, getIRPosition(), Values);
11772 if (!NewVal)
11773 return ChangeStatus::UNCHANGED;
11774
11775 ChangeStatus Changed = ChangeStatus::UNCHANGED;
11776 if (auto *Arg = dyn_cast<Argument>(NewVal)) {
11777 STATS_DECLTRACK(UniqueReturnValue, FunctionReturn,
11778 "Number of function with unique return");
11779 Changed |= A.manifestAttrs(
11781 {Attribute::get(Arg->getContext(), Attribute::Returned)});
11782 STATS_DECLTRACK_ARG_ATTR(returned);
11783 }
11784
11785 auto RetInstPred = [&](Instruction &RetI) {
11786 Value *RetOp = RetI.getOperand(0);
11787 if (isa<UndefValue>(RetOp) || RetOp == NewVal)
11788 return true;
11789 if (AA::isValidAtPosition({*NewVal, RetI}, A.getInfoCache()))
11790 if (A.changeUseAfterManifest(RetI.getOperandUse(0), *NewVal))
11791 Changed = ChangeStatus::CHANGED;
11792 return true;
11793 };
11794 bool UsedAssumedInformation = false;
11795 (void)A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret},
11796 UsedAssumedInformation,
11797 /* CheckBBLivenessOnly */ true);
11798 return Changed;
11799 }
11800
11801 ChangeStatus indicatePessimisticFixpoint() override {
11802 return AAPotentialValues::indicatePessimisticFixpoint();
11803 }
11804
11805 /// See AbstractAttribute::trackStatistics()
11806 void trackStatistics() const override{
11807 STATS_DECLTRACK_FNRET_ATTR(potential_values)}
11808
11809 /// The argumented with an existing `returned` attribute.
11810 Argument *ReturnedArg = nullptr;
11811};
11812
11813struct AAPotentialValuesFunction : AAPotentialValuesImpl {
11814 AAPotentialValuesFunction(const IRPosition &IRP, Attributor &A)
11815 : AAPotentialValuesImpl(IRP, A) {}
11816
11817 /// See AbstractAttribute::updateImpl(...).
11818 ChangeStatus updateImpl(Attributor &A) override {
11819 llvm_unreachable("AAPotentialValues(Function|CallSite)::updateImpl will "
11820 "not be called");
11821 }
11822
11823 /// See AbstractAttribute::trackStatistics()
11824 void trackStatistics() const override {
11825 STATS_DECLTRACK_FN_ATTR(potential_values)
11826 }
11827};
11828
11829struct AAPotentialValuesCallSite : AAPotentialValuesFunction {
11830 AAPotentialValuesCallSite(const IRPosition &IRP, Attributor &A)
11831 : AAPotentialValuesFunction(IRP, A) {}
11832
11833 /// See AbstractAttribute::trackStatistics()
11834 void trackStatistics() const override {
11835 STATS_DECLTRACK_CS_ATTR(potential_values)
11836 }
11837};
11838
11839struct AAPotentialValuesCallSiteReturned : AAPotentialValuesImpl {
11840 AAPotentialValuesCallSiteReturned(const IRPosition &IRP, Attributor &A)
11841 : AAPotentialValuesImpl(IRP, A) {}
11842
11843 /// See AbstractAttribute::updateImpl(...).
11844 ChangeStatus updateImpl(Attributor &A) override {
11845 auto AssumedBefore = getAssumed();
11846
11847 Function *Callee = getAssociatedFunction();
11848 if (!Callee)
11849 return indicatePessimisticFixpoint();
11850
11851 bool UsedAssumedInformation = false;
11852 auto *CB = cast<CallBase>(getCtxI());
11853 if (CB->isMustTailCall() &&
11854 !A.isAssumedDead(IRPosition::inst(*CB), this, nullptr,
11855 UsedAssumedInformation))
11856 return indicatePessimisticFixpoint();
11857
11858 Function *Caller = CB->getCaller();
11859
11860 auto AddScope = [&](AA::ValueScope S) {
11862 if (!A.getAssumedSimplifiedValues(IRPosition::returned(*Callee), this,
11863 Values, S, UsedAssumedInformation))
11864 return false;
11865
11866 for (auto &It : Values) {
11867 Value *V = It.getValue();
11868 std::optional<Value *> CallerV = A.translateArgumentToCallSiteContent(
11869 V, *CB, *this, UsedAssumedInformation);
11870 if (!CallerV.has_value()) {
11871 // Nothing to do as long as no value was determined.
11872 continue;
11873 }
11874 V = *CallerV ? *CallerV : V;
11875 if (*CallerV && AA::isDynamicallyUnique(A, *this, *V)) {
11876 if (recurseForValue(A, IRPosition::value(*V), S))
11877 continue;
11878 }
11879 if (S == AA::Intraprocedural && !AA::isValidInScope(*V, Caller)) {
11880 giveUpOnIntraprocedural(A);
11881 return true;
11882 }
11883 addValue(A, getState(), *V, CB, S, getAnchorScope());
11884 }
11885 return true;
11886 };
11887 if (!AddScope(AA::Intraprocedural))
11888 return indicatePessimisticFixpoint();
11889 if (!AddScope(AA::Interprocedural))
11890 return indicatePessimisticFixpoint();
11891 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
11892 : ChangeStatus::CHANGED;
11893 }
11894
11895 ChangeStatus indicatePessimisticFixpoint() override {
11896 return AAPotentialValues::indicatePessimisticFixpoint();
11897 }
11898
11899 /// See AbstractAttribute::trackStatistics()
11900 void trackStatistics() const override {
11901 STATS_DECLTRACK_CSRET_ATTR(potential_values)
11902 }
11903};
11904
11905struct AAPotentialValuesCallSiteArgument : AAPotentialValuesFloating {
11906 AAPotentialValuesCallSiteArgument(const IRPosition &IRP, Attributor &A)
11907 : AAPotentialValuesFloating(IRP, A) {}
11908
11909 /// See AbstractAttribute::trackStatistics()
11910 void trackStatistics() const override {
11911 STATS_DECLTRACK_CSARG_ATTR(potential_values)
11912 }
11913};
11914} // namespace
11915
11916/// ---------------------- Assumption Propagation ------------------------------
11917namespace {
11918struct AAAssumptionInfoImpl : public AAAssumptionInfo {
11919 AAAssumptionInfoImpl(const IRPosition &IRP, Attributor &A,
11920 const DenseSet<StringRef> &Known)
11921 : AAAssumptionInfo(IRP, A, Known) {}
11922
11923 /// See AbstractAttribute::manifest(...).
11924 ChangeStatus manifest(Attributor &A) override {
11925 // Don't manifest a universal set if it somehow made it here.
11926 if (getKnown().isUniversal())
11927 return ChangeStatus::UNCHANGED;
11928
11929 const IRPosition &IRP = getIRPosition();
11930 SmallVector<StringRef, 0> Set(getAssumed().getSet().begin(),
11931 getAssumed().getSet().end());
11932 llvm::sort(Set);
11933 return A.manifestAttrs(IRP,
11934 Attribute::get(IRP.getAnchorValue().getContext(),
11936 llvm::join(Set, ",")),
11937 /*ForceReplace=*/true);
11938 }
11939
11940 bool hasAssumption(const StringRef Assumption) const override {
11941 return isValidState() && setContains(Assumption);
11942 }
11943
11944 /// See AbstractAttribute::getAsStr()
11945 const std::string getAsStr(Attributor *A) const override {
11946 const SetContents &Known = getKnown();
11947 const SetContents &Assumed = getAssumed();
11948
11949 SmallVector<StringRef, 0> Set(Known.getSet().begin(), Known.getSet().end());
11950 llvm::sort(Set);
11951 const std::string KnownStr = llvm::join(Set, ",");
11952
11953 std::string AssumedStr = "Universal";
11954 if (!Assumed.isUniversal()) {
11955 Set.assign(Assumed.getSet().begin(), Assumed.getSet().end());
11956 AssumedStr = llvm::join(Set, ",");
11957 }
11958 return "Known [" + KnownStr + "]," + " Assumed [" + AssumedStr + "]";
11959 }
11960};
11961
11962/// Propagates assumption information from parent functions to all of their
11963/// successors. An assumption can be propagated if the containing function
11964/// dominates the called function.
11965///
11966/// We start with a "known" set of assumptions already valid for the associated
11967/// function and an "assumed" set that initially contains all possible
11968/// assumptions. The assumed set is inter-procedurally updated by narrowing its
11969/// contents as concrete values are known. The concrete values are seeded by the
11970/// first nodes that are either entries into the call graph, or contains no
11971/// assumptions. Each node is updated as the intersection of the assumed state
11972/// with all of its predecessors.
11973struct AAAssumptionInfoFunction final : AAAssumptionInfoImpl {
11974 AAAssumptionInfoFunction(const IRPosition &IRP, Attributor &A)
11975 : AAAssumptionInfoImpl(IRP, A,
11976 getAssumptions(*IRP.getAssociatedFunction())) {}
11977
11978 /// See AbstractAttribute::updateImpl(...).
11979 ChangeStatus updateImpl(Attributor &A) override {
11980 bool Changed = false;
11981
11982 auto CallSitePred = [&](AbstractCallSite ACS) {
11983 const auto *AssumptionAA = A.getAAFor<AAAssumptionInfo>(
11984 *this, IRPosition::callsite_function(*ACS.getInstruction()),
11985 DepClassTy::REQUIRED);
11986 if (!AssumptionAA)
11987 return false;
11988 // Get the set of assumptions shared by all of this function's callers.
11989 Changed |= getIntersection(AssumptionAA->getAssumed());
11990 return !getAssumed().empty() || !getKnown().empty();
11991 };
11992
11993 bool UsedAssumedInformation = false;
11994 // Get the intersection of all assumptions held by this node's predecessors.
11995 // If we don't know all the call sites then this is either an entry into the
11996 // call graph or an empty node. This node is known to only contain its own
11997 // assumptions and can be propagated to its successors.
11998 if (!A.checkForAllCallSites(CallSitePred, *this, true,
11999 UsedAssumedInformation))
12000 return indicatePessimisticFixpoint();
12001
12002 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
12003 }
12004
12005 void trackStatistics() const override {}
12006};
12007
12008/// Assumption Info defined for call sites.
12009struct AAAssumptionInfoCallSite final : AAAssumptionInfoImpl {
12010
12011 AAAssumptionInfoCallSite(const IRPosition &IRP, Attributor &A)
12012 : AAAssumptionInfoImpl(IRP, A, getInitialAssumptions(IRP)) {}
12013
12014 /// See AbstractAttribute::initialize(...).
12015 void initialize(Attributor &A) override {
12016 const IRPosition &FnPos = IRPosition::function(*getAnchorScope());
12017 A.getAAFor<AAAssumptionInfo>(*this, FnPos, DepClassTy::REQUIRED);
12018 }
12019
12020 /// See AbstractAttribute::updateImpl(...).
12021 ChangeStatus updateImpl(Attributor &A) override {
12022 const IRPosition &FnPos = IRPosition::function(*getAnchorScope());
12023 auto *AssumptionAA =
12024 A.getAAFor<AAAssumptionInfo>(*this, FnPos, DepClassTy::REQUIRED);
12025 if (!AssumptionAA)
12026 return indicatePessimisticFixpoint();
12027 bool Changed = getIntersection(AssumptionAA->getAssumed());
12028 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
12029 }
12030
12031 /// See AbstractAttribute::trackStatistics()
12032 void trackStatistics() const override {}
12033
12034private:
12035 /// Helper to initialized the known set as all the assumptions this call and
12036 /// the callee contain.
12037 DenseSet<StringRef> getInitialAssumptions(const IRPosition &IRP) {
12038 const CallBase &CB = cast<CallBase>(IRP.getAssociatedValue());
12039 auto Assumptions = getAssumptions(CB);
12040 if (const Function *F = CB.getCaller())
12041 set_union(Assumptions, getAssumptions(*F));
12042 if (Function *F = IRP.getAssociatedFunction())
12043 set_union(Assumptions, getAssumptions(*F));
12044 return Assumptions;
12045 }
12046};
12047} // namespace
12048
12050 return static_cast<AACallGraphNode *>(const_cast<AACallEdges *>(
12051 A.getOrCreateAAFor<AACallEdges>(IRPosition::function(**I))));
12052}
12053
12055
12056/// ------------------------ UnderlyingObjects ---------------------------------
12057
12058namespace {
12059struct AAUnderlyingObjectsImpl
12060 : StateWrapper<BooleanState, AAUnderlyingObjects> {
12062 AAUnderlyingObjectsImpl(const IRPosition &IRP, Attributor &A) : BaseTy(IRP) {}
12063
12064 /// See AbstractAttribute::getAsStr().
12065 const std::string getAsStr(Attributor *A) const override {
12066 if (!isValidState())
12067 return "<invalid>";
12068 std::string Str;
12070 OS << "underlying objects: inter " << InterAssumedUnderlyingObjects.size()
12071 << " objects, intra " << IntraAssumedUnderlyingObjects.size()
12072 << " objects.\n";
12073 if (!InterAssumedUnderlyingObjects.empty()) {
12074 OS << "inter objects:\n";
12075 for (auto *Obj : InterAssumedUnderlyingObjects)
12076 OS << *Obj << '\n';
12077 }
12078 if (!IntraAssumedUnderlyingObjects.empty()) {
12079 OS << "intra objects:\n";
12080 for (auto *Obj : IntraAssumedUnderlyingObjects)
12081 OS << *Obj << '\n';
12082 }
12083 return Str;
12084 }
12085
12086 /// See AbstractAttribute::trackStatistics()
12087 void trackStatistics() const override {}
12088
12089 /// See AbstractAttribute::updateImpl(...).
12090 ChangeStatus updateImpl(Attributor &A) override {
12091 auto &Ptr = getAssociatedValue();
12092
12093 bool UsedAssumedInformation = false;
12094 auto DoUpdate = [&](SmallSetVector<Value *, 8> &UnderlyingObjects,
12096 SmallPtrSet<Value *, 8> SeenObjects;
12098
12099 if (!A.getAssumedSimplifiedValues(IRPosition::value(Ptr), *this, Values,
12100 Scope, UsedAssumedInformation))
12101 return UnderlyingObjects.insert(&Ptr);
12102
12103 bool Changed = false;
12104
12105 for (unsigned I = 0; I < Values.size(); ++I) {
12106 auto &VAC = Values[I];
12107 auto *Obj = VAC.getValue();
12108 Value *UO = getUnderlyingObject(Obj);
12109 if (!SeenObjects.insert(UO ? UO : Obj).second)
12110 continue;
12111 if (UO && UO != Obj) {
12112 if (isa<AllocaInst>(UO) || isa<GlobalValue>(UO)) {
12113 Changed |= UnderlyingObjects.insert(UO);
12114 continue;
12115 }
12116
12117 const auto *OtherAA = A.getAAFor<AAUnderlyingObjects>(
12118 *this, IRPosition::value(*UO), DepClassTy::OPTIONAL);
12119 auto Pred = [&](Value &V) {
12120 if (&V == UO)
12121 Changed |= UnderlyingObjects.insert(UO);
12122 else
12123 Values.emplace_back(V, nullptr);
12124 return true;
12125 };
12126
12127 if (!OtherAA || !OtherAA->forallUnderlyingObjects(Pred, Scope))
12129 "The forall call should not return false at this position");
12130 UsedAssumedInformation |= !OtherAA->getState().isAtFixpoint();
12131 continue;
12132 }
12133
12134 if (isa<SelectInst>(Obj)) {
12135 Changed |= handleIndirect(A, *Obj, UnderlyingObjects, Scope,
12136 UsedAssumedInformation);
12137 continue;
12138 }
12139 if (auto *PHI = dyn_cast<PHINode>(Obj)) {
12140 // Explicitly look through PHIs as we do not care about dynamically
12141 // uniqueness.
12142 for (unsigned u = 0, e = PHI->getNumIncomingValues(); u < e; u++) {
12143 Changed |=
12144 handleIndirect(A, *PHI->getIncomingValue(u), UnderlyingObjects,
12145 Scope, UsedAssumedInformation);
12146 }
12147 continue;
12148 }
12149
12150 Changed |= UnderlyingObjects.insert(Obj);
12151 }
12152
12153 return Changed;
12154 };
12155
12156 bool Changed = false;
12157 Changed |= DoUpdate(IntraAssumedUnderlyingObjects, AA::Intraprocedural);
12158 Changed |= DoUpdate(InterAssumedUnderlyingObjects, AA::Interprocedural);
12159 if (!UsedAssumedInformation)
12160 indicateOptimisticFixpoint();
12161 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
12162 }
12163
12164 bool forallUnderlyingObjects(
12165 function_ref<bool(Value &)> Pred,
12166 AA::ValueScope Scope = AA::Interprocedural) const override {
12167 if (!isValidState())
12168 return Pred(getAssociatedValue());
12169
12170 auto &AssumedUnderlyingObjects = Scope == AA::Intraprocedural
12171 ? IntraAssumedUnderlyingObjects
12172 : InterAssumedUnderlyingObjects;
12173 for (Value *Obj : AssumedUnderlyingObjects)
12174 if (!Pred(*Obj))
12175 return false;
12176
12177 return true;
12178 }
12179
12180private:
12181 /// Handle the case where the value is not the actual underlying value, such
12182 /// as a phi node or a select instruction.
12183 bool handleIndirect(Attributor &A, Value &V,
12184 SmallSetVector<Value *, 8> &UnderlyingObjects,
12185 AA::ValueScope Scope, bool &UsedAssumedInformation) {
12186 bool Changed = false;
12187 const auto *AA = A.getAAFor<AAUnderlyingObjects>(
12188 *this, IRPosition::value(V), DepClassTy::OPTIONAL);
12189 auto Pred = [&](Value &V) {
12190 Changed |= UnderlyingObjects.insert(&V);
12191 return true;
12192 };
12193 if (!AA || !AA->forallUnderlyingObjects(Pred, Scope))
12195 "The forall call should not return false at this position");
12196 UsedAssumedInformation |= !AA->getState().isAtFixpoint();
12197 return Changed;
12198 }
12199
12200 /// All the underlying objects collected so far via intra procedural scope.
12201 SmallSetVector<Value *, 8> IntraAssumedUnderlyingObjects;
12202 /// All the underlying objects collected so far via inter procedural scope.
12203 SmallSetVector<Value *, 8> InterAssumedUnderlyingObjects;
12204};
12205
12206struct AAUnderlyingObjectsFloating final : AAUnderlyingObjectsImpl {
12207 AAUnderlyingObjectsFloating(const IRPosition &IRP, Attributor &A)
12208 : AAUnderlyingObjectsImpl(IRP, A) {}
12209};
12210
12211struct AAUnderlyingObjectsArgument final : AAUnderlyingObjectsImpl {
12212 AAUnderlyingObjectsArgument(const IRPosition &IRP, Attributor &A)
12213 : AAUnderlyingObjectsImpl(IRP, A) {}
12214};
12215
12216struct AAUnderlyingObjectsCallSite final : AAUnderlyingObjectsImpl {
12217 AAUnderlyingObjectsCallSite(const IRPosition &IRP, Attributor &A)
12218 : AAUnderlyingObjectsImpl(IRP, A) {}
12219};
12220
12221struct AAUnderlyingObjectsCallSiteArgument final : AAUnderlyingObjectsImpl {
12222 AAUnderlyingObjectsCallSiteArgument(const IRPosition &IRP, Attributor &A)
12223 : AAUnderlyingObjectsImpl(IRP, A) {}
12224};
12225
12226struct AAUnderlyingObjectsReturned final : AAUnderlyingObjectsImpl {
12227 AAUnderlyingObjectsReturned(const IRPosition &IRP, Attributor &A)
12228 : AAUnderlyingObjectsImpl(IRP, A) {}
12229};
12230
12231struct AAUnderlyingObjectsCallSiteReturned final : AAUnderlyingObjectsImpl {
12232 AAUnderlyingObjectsCallSiteReturned(const IRPosition &IRP, Attributor &A)
12233 : AAUnderlyingObjectsImpl(IRP, A) {}
12234};
12235
12236struct AAUnderlyingObjectsFunction final : AAUnderlyingObjectsImpl {
12237 AAUnderlyingObjectsFunction(const IRPosition &IRP, Attributor &A)
12238 : AAUnderlyingObjectsImpl(IRP, A) {}
12239};
12240} // namespace
12241
12242/// ------------------------ Global Value Info -------------------------------
12243namespace {
12244struct AAGlobalValueInfoFloating : public AAGlobalValueInfo {
12245 AAGlobalValueInfoFloating(const IRPosition &IRP, Attributor &A)
12246 : AAGlobalValueInfo(IRP, A) {}
12247
12248 /// See AbstractAttribute::initialize(...).
12249 void initialize(Attributor &A) override {}
12250
12251 bool checkUse(Attributor &A, const Use &U, bool &Follow,
12252 SmallVectorImpl<const Value *> &Worklist) {
12253 Instruction *UInst = dyn_cast<Instruction>(U.getUser());
12254 if (!UInst) {
12255 // Outside a closed world, code outside the module can read an
12256 // externally visible global, so the value escapes through it.
12257 if (auto *GV = dyn_cast<GlobalValue>(U.getUser()))
12258 if (!GV->hasLocalLinkage() && !A.isClosedWorldModule())
12259 return false;
12260 Follow = true;
12261 return true;
12262 }
12263
12264 LLVM_DEBUG(dbgs() << "[AAGlobalValueInfo] Check use: " << *U.get() << " in "
12265 << *UInst << "\n");
12266
12267 if (auto *Cmp = dyn_cast<ICmpInst>(U.getUser())) {
12268 int Idx = &Cmp->getOperandUse(0) == &U;
12269 if (isa<Constant>(Cmp->getOperand(Idx)))
12270 return true;
12271 return U == &getAnchorValue();
12272 }
12273
12274 // Explicitly catch return instructions.
12275 if (isa<ReturnInst>(UInst)) {
12276 auto CallSitePred = [&](AbstractCallSite ACS) {
12277 Worklist.push_back(ACS.getInstruction());
12278 return true;
12279 };
12280 bool UsedAssumedInformation = false;
12281 // TODO: We should traverse the uses or add a "non-call-site" CB.
12282 if (!A.checkForAllCallSites(CallSitePred, *UInst->getFunction(),
12283 /*RequireAllCallSites=*/true, this,
12284 UsedAssumedInformation))
12285 return false;
12286 return true;
12287 }
12288
12289 // For now we only use special logic for call sites. However, the tracker
12290 // itself knows about a lot of other non-capturing cases already.
12291 auto *CB = dyn_cast<CallBase>(UInst);
12292 if (!CB)
12293 return false;
12294 // Direct calls are OK uses.
12295 if (CB->isCallee(&U))
12296 return true;
12297 // Non-argument uses are scary.
12298 if (!CB->isArgOperand(&U))
12299 return false;
12300 // TODO: Iterate callees.
12301 auto *Fn = dyn_cast<Function>(CB->getCalledOperand());
12302 if (!Fn || !A.isFunctionIPOAmendable(*Fn))
12303 return false;
12304
12305 unsigned ArgNo = CB->getArgOperandNo(&U);
12306 Worklist.push_back(Fn->getArg(ArgNo));
12307 return true;
12308 }
12309
12310 ChangeStatus updateImpl(Attributor &A) override {
12311 unsigned NumUsesBefore = Uses.size();
12312
12313 SmallPtrSet<const Value *, 8> Visited;
12315 Worklist.push_back(&getAnchorValue());
12316
12317 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
12318 Uses.insert(&U);
12319 // TODO(captures): Make this more precise.
12320 UseCaptureInfo CI = DetermineUseCaptureKind(U, /*Base=*/nullptr);
12321 if (CI.isPassthrough()) {
12322 Follow = true;
12323 return true;
12324 }
12325 return checkUse(A, U, Follow, Worklist);
12326 };
12327 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) {
12328 Uses.insert(&OldU);
12329 return true;
12330 };
12331
12332 while (!Worklist.empty()) {
12333 const Value *V = Worklist.pop_back_val();
12334 if (!Visited.insert(V).second)
12335 continue;
12336 if (!A.checkForAllUses(UsePred, *this, *V,
12337 /* CheckBBLivenessOnly */ true,
12338 DepClassTy::OPTIONAL,
12339 /* IgnoreDroppableUses */ true, EquivalentUseCB)) {
12340 return indicatePessimisticFixpoint();
12341 }
12342 }
12343
12344 return Uses.size() == NumUsesBefore ? ChangeStatus::UNCHANGED
12345 : ChangeStatus::CHANGED;
12346 }
12347
12348 bool isPotentialUse(const Use &U) const override {
12349 return !isValidState() || Uses.contains(&U);
12350 }
12351
12352 /// See AbstractAttribute::manifest(...).
12353 ChangeStatus manifest(Attributor &A) override {
12354 return ChangeStatus::UNCHANGED;
12355 }
12356
12357 /// See AbstractAttribute::getAsStr().
12358 const std::string getAsStr(Attributor *A) const override {
12359 return "[" + std::to_string(Uses.size()) + " uses]";
12360 }
12361
12362 void trackStatistics() const override {
12363 STATS_DECLTRACK_FLOATING_ATTR(GlobalValuesTracked);
12364 }
12365
12366private:
12367 /// Set of (transitive) uses of this GlobalValue.
12368 SmallPtrSet<const Use *, 8> Uses;
12369};
12370} // namespace
12371
12372/// ------------------------ Indirect Call Info -------------------------------
12373namespace {
12374struct AAIndirectCallInfoCallSite : public AAIndirectCallInfo {
12375 AAIndirectCallInfoCallSite(const IRPosition &IRP, Attributor &A)
12376 : AAIndirectCallInfo(IRP, A) {}
12377
12378 /// See AbstractAttribute::initialize(...).
12379 void initialize(Attributor &A) override {
12380 auto *MD = getCtxI()->getMetadata(LLVMContext::MD_callees);
12381 if (!MD && !A.isClosedWorldModule())
12382 return;
12383
12384 if (MD) {
12385 for (const auto &Op : MD->operands())
12387 PotentialCallees.insert(Callee);
12388 } else if (A.isClosedWorldModule()) {
12389 ArrayRef<Function *> IndirectlyCallableFunctions =
12390 A.getInfoCache().getIndirectlyCallableFunctions(A);
12391 PotentialCallees.insert_range(IndirectlyCallableFunctions);
12392 }
12393
12394 if (PotentialCallees.empty())
12395 indicateOptimisticFixpoint();
12396 }
12397
12398 ChangeStatus updateImpl(Attributor &A) override {
12399 CallBase *CB = cast<CallBase>(getCtxI());
12400 const Use &CalleeUse = CB->getCalledOperandUse();
12401 Value *FP = CB->getCalledOperand();
12402
12403 SmallSetVector<Function *, 4> AssumedCalleesNow;
12404 bool AllCalleesKnownNow = AllCalleesKnown;
12405
12406 auto CheckPotentialCalleeUse = [&](Function &PotentialCallee,
12407 bool &UsedAssumedInformation) {
12408 const auto *GIAA = A.getAAFor<AAGlobalValueInfo>(
12409 *this, IRPosition::value(PotentialCallee), DepClassTy::OPTIONAL);
12410 if (!GIAA || GIAA->isPotentialUse(CalleeUse))
12411 return true;
12412 UsedAssumedInformation = !GIAA->isAtFixpoint();
12413 return false;
12414 };
12415
12416 auto AddPotentialCallees = [&]() {
12417 for (auto *PotentialCallee : PotentialCallees) {
12418 bool UsedAssumedInformation = false;
12419 if (CheckPotentialCalleeUse(*PotentialCallee, UsedAssumedInformation))
12420 AssumedCalleesNow.insert(PotentialCallee);
12421 }
12422 };
12423
12424 // Use simplification to find potential callees, if !callees was present,
12425 // fallback to that set if necessary.
12426 bool UsedAssumedInformation = false;
12428 if (!A.getAssumedSimplifiedValues(IRPosition::value(*FP), this, Values,
12429 AA::ValueScope::AnyScope,
12430 UsedAssumedInformation)) {
12431 if (PotentialCallees.empty())
12432 return indicatePessimisticFixpoint();
12433 AddPotentialCallees();
12434 }
12435
12436 // Try to find a reason for \p Fn not to be a potential callee. If none was
12437 // found, add it to the assumed callees set.
12438 auto CheckPotentialCallee = [&](Function &Fn) {
12439 if (!PotentialCallees.empty() && !PotentialCallees.count(&Fn))
12440 return false;
12441
12442 auto &CachedResult = FilterResults[&Fn];
12443 if (CachedResult.has_value())
12444 return CachedResult.value();
12445
12446 bool UsedAssumedInformation = false;
12447 if (!CheckPotentialCalleeUse(Fn, UsedAssumedInformation)) {
12448 if (!UsedAssumedInformation)
12449 CachedResult = false;
12450 return false;
12451 }
12452
12453 int NumFnArgs = Fn.arg_size();
12454 int NumCBArgs = CB->arg_size();
12455
12456 // Check if any excess argument (which we fill up with poison) is known to
12457 // be UB on undef.
12458 for (int I = NumCBArgs; I < NumFnArgs; ++I) {
12459 bool IsKnown = false;
12461 A, this, IRPosition::argument(*Fn.getArg(I)),
12462 DepClassTy::OPTIONAL, IsKnown)) {
12463 if (IsKnown)
12464 CachedResult = false;
12465 return false;
12466 }
12467 }
12468
12469 CachedResult = true;
12470 return true;
12471 };
12472
12473 // Check simplification result, prune known UB callees, also restrict it to
12474 // the !callees set, if present.
12475 for (auto &VAC : Values) {
12476 if (isa<UndefValue>(VAC.getValue()))
12477 continue;
12479 VAC.getValue()->getType()->getPointerAddressSpace() == 0)
12480 continue;
12481 // TODO: Check for known UB, e.g., poison + noundef.
12482 if (auto *VACFn = dyn_cast<Function>(VAC.getValue())) {
12483 if (CheckPotentialCallee(*VACFn))
12484 AssumedCalleesNow.insert(VACFn);
12485 continue;
12486 }
12487 if (!PotentialCallees.empty()) {
12488 AddPotentialCallees();
12489 break;
12490 }
12491 AllCalleesKnownNow = false;
12492 }
12493
12494 if (AssumedCalleesNow == AssumedCallees &&
12495 AllCalleesKnown == AllCalleesKnownNow)
12496 return ChangeStatus::UNCHANGED;
12497
12498 std::swap(AssumedCallees, AssumedCalleesNow);
12499 AllCalleesKnown = AllCalleesKnownNow;
12500 return ChangeStatus::CHANGED;
12501 }
12502
12503 /// See AbstractAttribute::manifest(...).
12504 ChangeStatus manifest(Attributor &A) override {
12505 // If we can't specialize at all, give up now.
12506 if (!AllCalleesKnown && AssumedCallees.empty())
12507 return ChangeStatus::UNCHANGED;
12508
12509 CallBase *CB = cast<CallBase>(getCtxI());
12510 bool UsedAssumedInformation = false;
12511 if (A.isAssumedDead(*CB, this, /*LivenessAA=*/nullptr,
12512 UsedAssumedInformation))
12513 return ChangeStatus::UNCHANGED;
12514
12515 ChangeStatus Changed = ChangeStatus::UNCHANGED;
12516 unsigned ProgramAS = CB->getDataLayout().getProgramAddressSpace();
12517 Value *FP = CB->getCalledOperand();
12518 if (FP->getType()->getPointerAddressSpace() != ProgramAS)
12519 FP = new AddrSpaceCastInst(
12520 FP, PointerType::get(FP->getContext(), ProgramAS),
12521 FP->getName() + ".as" + Twine(ProgramAS), CB->getIterator());
12522
12523 bool CBIsVoid = CB->getType()->isVoidTy();
12525 FunctionType *CSFT = CB->getFunctionType();
12526 SmallVector<Value *> CSArgs(CB->args());
12527
12528 // If we know all callees and there are none, the call site is (effectively)
12529 // dead (or UB).
12530 if (AssumedCallees.empty()) {
12531 assert(AllCalleesKnown &&
12532 "Expected all callees to be known if there are none.");
12533 A.changeToUnreachableAfterManifest(CB);
12534 return ChangeStatus::CHANGED;
12535 }
12536
12537 // Special handling for the single callee case.
12538 if (AllCalleesKnown && AssumedCallees.size() == 1) {
12539 auto *NewCallee = AssumedCallees.front();
12540 if (isLegalToPromote(*CB, NewCallee)) {
12541 promoteCall(*CB, NewCallee, nullptr);
12542 NumIndirectCallsPromoted++;
12543 return ChangeStatus::CHANGED;
12544 }
12545 Instruction *NewCall =
12546 CallInst::Create(FunctionCallee(CSFT, NewCallee), CSArgs,
12547 CB->getName(), CB->getIterator());
12548 if (!CBIsVoid)
12549 A.changeAfterManifest(IRPosition::callsite_returned(*CB), *NewCall);
12550 A.deleteAfterManifest(*CB);
12551 return ChangeStatus::CHANGED;
12552 }
12553
12554 // For each potential value we create a conditional
12555 //
12556 // ```
12557 // if (ptr == value) value(args);
12558 // else ...
12559 // ```
12560 //
12561 bool SpecializedForAnyCallees = false;
12562 bool SpecializedForAllCallees = AllCalleesKnown;
12563 ICmpInst *LastCmp = nullptr;
12564 SmallVector<Function *, 8> SkippedAssumedCallees;
12566 for (Function *NewCallee : AssumedCallees) {
12567 if (!A.shouldSpecializeCallSiteForCallee(*this, *CB, *NewCallee,
12568 AssumedCallees.size())) {
12569 SkippedAssumedCallees.push_back(NewCallee);
12570 SpecializedForAllCallees = false;
12571 continue;
12572 }
12573 SpecializedForAnyCallees = true;
12574
12575 LastCmp = new ICmpInst(IP, llvm::CmpInst::ICMP_EQ, FP, NewCallee);
12576 Instruction *ThenTI =
12577 SplitBlockAndInsertIfThen(LastCmp, IP, /* Unreachable */ false);
12578 BasicBlock *CBBB = CB->getParent();
12579 A.registerManifestAddedBasicBlock(*ThenTI->getParent());
12580 A.registerManifestAddedBasicBlock(*IP->getParent());
12581 auto *SplitTI = cast<CondBrInst>(LastCmp->getNextNode());
12582 BasicBlock *ElseBB;
12583 if (&*IP == CB) {
12584 ElseBB = BasicBlock::Create(ThenTI->getContext(), "",
12585 ThenTI->getFunction(), CBBB);
12586 A.registerManifestAddedBasicBlock(*ElseBB);
12587 IP = UncondBrInst::Create(CBBB, ElseBB)->getIterator();
12588 SplitTI->replaceUsesOfWith(CBBB, ElseBB);
12589 } else {
12590 ElseBB = IP->getParent();
12591 ThenTI->replaceUsesOfWith(ElseBB, CBBB);
12592 }
12593 CastInst *RetBC = nullptr;
12594 CallInst *NewCall = nullptr;
12595 if (isLegalToPromote(*CB, NewCallee)) {
12596 auto *CBClone = cast<CallBase>(CB->clone());
12597 CBClone->insertBefore(ThenTI->getIterator());
12598 NewCall = &cast<CallInst>(promoteCall(*CBClone, NewCallee, &RetBC));
12599 NumIndirectCallsPromoted++;
12600 } else {
12601 NewCall = CallInst::Create(FunctionCallee(CSFT, NewCallee), CSArgs,
12602 CB->getName(), ThenTI->getIterator());
12603 }
12604 NewCalls.push_back({NewCall, RetBC});
12605 }
12606
12607 auto AttachCalleeMetadata = [&](CallBase &IndirectCB) {
12608 if (!AllCalleesKnown)
12609 return ChangeStatus::UNCHANGED;
12610 MDBuilder MDB(IndirectCB.getContext());
12611 MDNode *Callees = MDB.createCallees(SkippedAssumedCallees);
12612 IndirectCB.setMetadata(LLVMContext::MD_callees, Callees);
12613 return ChangeStatus::CHANGED;
12614 };
12615
12616 if (!SpecializedForAnyCallees)
12617 return AttachCalleeMetadata(*CB);
12618
12619 // Check if we need the fallback indirect call still.
12620 if (SpecializedForAllCallees) {
12622 LastCmp->eraseFromParent();
12623 new UnreachableInst(IP->getContext(), IP);
12624 IP->eraseFromParent();
12625 } else {
12626 auto *CBClone = cast<CallInst>(CB->clone());
12627 CBClone->setName(CB->getName());
12628 CBClone->insertBefore(*IP->getParent(), IP);
12629 NewCalls.push_back({CBClone, nullptr});
12630 AttachCalleeMetadata(*CBClone);
12631 }
12632
12633 // Check if we need a PHI to merge the results.
12634 if (!CBIsVoid) {
12635 auto *PHI = PHINode::Create(CB->getType(), NewCalls.size(),
12636 CB->getName() + ".phi",
12637 CB->getParent()->getFirstInsertionPt());
12638 for (auto &It : NewCalls) {
12639 CallBase *NewCall = It.first;
12640 Instruction *CallRet = It.second ? It.second : It.first;
12641 if (CallRet->getType() == CB->getType())
12642 PHI->addIncoming(CallRet, CallRet->getParent());
12643 else if (NewCall->getType()->isVoidTy())
12644 PHI->addIncoming(PoisonValue::get(CB->getType()),
12645 NewCall->getParent());
12646 else
12647 llvm_unreachable("Call return should match or be void!");
12648 }
12649 A.changeAfterManifest(IRPosition::callsite_returned(*CB), *PHI);
12650 }
12651
12652 A.deleteAfterManifest(*CB);
12653 Changed = ChangeStatus::CHANGED;
12654
12655 return Changed;
12656 }
12657
12658 /// See AbstractAttribute::getAsStr().
12659 const std::string getAsStr(Attributor *A) const override {
12660 return std::string(AllCalleesKnown ? "eliminate" : "specialize") +
12661 " indirect call site with " + std::to_string(AssumedCallees.size()) +
12662 " functions";
12663 }
12664
12665 void trackStatistics() const override {
12666 if (AllCalleesKnown) {
12668 Eliminated, CallSites,
12669 "Number of indirect call sites eliminated via specialization")
12670 } else {
12671 STATS_DECLTRACK(Specialized, CallSites,
12672 "Number of indirect call sites specialized")
12673 }
12674 }
12675
12676 bool foreachCallee(function_ref<bool(Function *)> CB) const override {
12677 return isValidState() && AllCalleesKnown && all_of(AssumedCallees, CB);
12678 }
12679
12680private:
12681 /// Map to remember filter results.
12682 DenseMap<Function *, std::optional<bool>> FilterResults;
12683
12684 /// If the !callee metadata was present, this set will contain all potential
12685 /// callees (superset).
12686 SmallSetVector<Function *, 4> PotentialCallees;
12687
12688 /// This set contains all currently assumed calllees, which might grow over
12689 /// time.
12690 SmallSetVector<Function *, 4> AssumedCallees;
12691
12692 /// Flag to indicate if all possible callees are in the AssumedCallees set or
12693 /// if there could be others.
12694 bool AllCalleesKnown = true;
12695};
12696} // namespace
12697
12698/// --------------------- Invariant Load Pointer -------------------------------
12699namespace {
12700
12701struct AAInvariantLoadPointerImpl
12702 : public StateWrapper<BitIntegerState<uint8_t, 15>,
12703 AAInvariantLoadPointer> {
12704
12705 enum {
12706 // pointer does not alias within the bounds of the function
12707 IS_NOALIAS = 1 << 0,
12708 // pointer is not involved in any effectful instructions within the bounds
12709 // of the function
12710 IS_NOEFFECT = 1 << 1,
12711 // loads are invariant within the bounds of the function
12712 IS_LOCALLY_INVARIANT = 1 << 2,
12713 // memory lifetime is constrained within the bounds of the function
12714 IS_LOCALLY_CONSTRAINED = 1 << 3,
12715
12716 IS_BEST_STATE = IS_NOALIAS | IS_NOEFFECT | IS_LOCALLY_INVARIANT |
12717 IS_LOCALLY_CONSTRAINED,
12718 };
12719 static_assert(getBestState() == IS_BEST_STATE, "Unexpected best state");
12720
12721 using Base =
12722 StateWrapper<BitIntegerState<uint8_t, 15>, AAInvariantLoadPointer>;
12723
12724 // the BitIntegerState is optimistic about IS_NOALIAS and IS_NOEFFECT, but
12725 // pessimistic about IS_KNOWN_INVARIANT
12726 AAInvariantLoadPointerImpl(const IRPosition &IRP, Attributor &A)
12727 : Base(IRP) {}
12728
12729 bool isKnownInvariant() const final {
12730 return isKnownLocallyInvariant() && isKnown(IS_LOCALLY_CONSTRAINED);
12731 }
12732
12733 bool isKnownLocallyInvariant() const final {
12734 if (isKnown(IS_LOCALLY_INVARIANT))
12735 return true;
12736 return isKnown(IS_NOALIAS | IS_NOEFFECT);
12737 }
12738
12739 bool isAssumedInvariant() const final {
12740 return isAssumedLocallyInvariant() && isAssumed(IS_LOCALLY_CONSTRAINED);
12741 }
12742
12743 bool isAssumedLocallyInvariant() const final {
12744 if (isAssumed(IS_LOCALLY_INVARIANT))
12745 return true;
12746 return isAssumed(IS_NOALIAS | IS_NOEFFECT);
12747 }
12748
12749 ChangeStatus updateImpl(Attributor &A) override {
12750 ChangeStatus Changed = ChangeStatus::UNCHANGED;
12751
12752 Changed |= updateNoAlias(A);
12753 if (requiresNoAlias() && !isAssumed(IS_NOALIAS))
12754 return indicatePessimisticFixpoint();
12755
12756 Changed |= updateNoEffect(A);
12757
12758 Changed |= updateLocalInvariance(A);
12759
12760 return Changed;
12761 }
12762
12763 ChangeStatus manifest(Attributor &A) override {
12764 if (!isKnownInvariant())
12765 return ChangeStatus::UNCHANGED;
12766
12767 ChangeStatus Changed = ChangeStatus::UNCHANGED;
12768 const Value *Ptr = &getAssociatedValue();
12769 const auto TagInvariantLoads = [&](const Use &U, bool &) {
12770 if (U.get() != Ptr)
12771 return true;
12772 auto *I = dyn_cast<Instruction>(U.getUser());
12773 if (!I)
12774 return true;
12775
12776 // Ensure that we are only changing uses from the corresponding callgraph
12777 // SSC in the case that the AA isn't run on the entire module
12778 if (!A.isRunOn(I->getFunction()))
12779 return true;
12780
12781 if (I->hasMetadata(LLVMContext::MD_invariant_load))
12782 return true;
12783
12784 if (auto *LI = dyn_cast<LoadInst>(I)) {
12785 LI->setMetadata(LLVMContext::MD_invariant_load,
12786 MDNode::get(LI->getContext(), {}));
12787 Changed = ChangeStatus::CHANGED;
12788 }
12789 return true;
12790 };
12791
12792 (void)A.checkForAllUses(TagInvariantLoads, *this, *Ptr);
12793 return Changed;
12794 }
12795
12796 /// See AbstractAttribute::getAsStr().
12797 const std::string getAsStr(Attributor *) const override {
12798 if (isKnownInvariant())
12799 return "load-invariant pointer";
12800 return "non-invariant pointer";
12801 }
12802
12803 /// See AbstractAttribute::trackStatistics().
12804 void trackStatistics() const override {}
12805
12806private:
12807 /// Indicate that noalias is required for the pointer to be invariant.
12808 bool requiresNoAlias() const {
12809 switch (getPositionKind()) {
12810 default:
12811 // Conservatively default to require noalias.
12812 return true;
12813 case IRP_FLOAT:
12814 case IRP_RETURNED:
12815 case IRP_CALL_SITE:
12816 return false;
12817 case IRP_CALL_SITE_RETURNED: {
12818 const auto &CB = cast<CallBase>(getAnchorValue());
12820 &CB, /*MustPreserveOffset=*/false);
12821 }
12822 case IRP_ARGUMENT: {
12823 const Function *F = getAssociatedFunction();
12824 assert(F && "no associated function for argument");
12825 return !isCallableCC(F->getCallingConv());
12826 }
12827 }
12828 }
12829
12830 bool isExternal() const {
12831 const Function *F = getAssociatedFunction();
12832 if (!F)
12833 return true;
12834 return isCallableCC(F->getCallingConv()) &&
12835 getPositionKind() != IRP_CALL_SITE_RETURNED;
12836 }
12837
12838 ChangeStatus updateNoAlias(Attributor &A) {
12839 if (isKnown(IS_NOALIAS) || !isAssumed(IS_NOALIAS))
12840 return ChangeStatus::UNCHANGED;
12841
12842 // Try to use AANoAlias.
12843 if (const auto *ANoAlias = A.getOrCreateAAFor<AANoAlias>(
12844 getIRPosition(), this, DepClassTy::REQUIRED)) {
12845 if (ANoAlias->isKnownNoAlias()) {
12846 addKnownBits(IS_NOALIAS);
12847 return ChangeStatus::CHANGED;
12848 }
12849
12850 if (!ANoAlias->isAssumedNoAlias()) {
12851 removeAssumedBits(IS_NOALIAS);
12852 return ChangeStatus::CHANGED;
12853 }
12854
12855 return ChangeStatus::UNCHANGED;
12856 }
12857
12858 // Try to infer noalias from argument attribute, since it is applicable for
12859 // the duration of the function.
12860 if (const Argument *Arg = getAssociatedArgument()) {
12861 if (Arg->hasNoAliasAttr()) {
12862 addKnownBits(IS_NOALIAS);
12863 return ChangeStatus::UNCHANGED;
12864 }
12865
12866 // Noalias information is not provided, and cannot be inferred,
12867 // so we conservatively assume the pointer aliases.
12868 removeAssumedBits(IS_NOALIAS);
12869 return ChangeStatus::CHANGED;
12870 }
12871
12872 return ChangeStatus::UNCHANGED;
12873 }
12874
12875 ChangeStatus updateNoEffect(Attributor &A) {
12876 if (isKnown(IS_NOEFFECT) || !isAssumed(IS_NOEFFECT))
12877 return ChangeStatus::UNCHANGED;
12878
12879 if (!getAssociatedFunction())
12880 return indicatePessimisticFixpoint();
12881
12882 if (isa<AllocaInst>(&getAssociatedValue()))
12883 return indicatePessimisticFixpoint();
12884
12885 const auto HasNoEffectLoads = [&](const Use &U, bool &) {
12886 const auto *LI = dyn_cast<LoadInst>(U.getUser());
12887 return !LI || !LI->mayHaveSideEffects();
12888 };
12889 if (!A.checkForAllUses(HasNoEffectLoads, *this, getAssociatedValue()))
12890 return indicatePessimisticFixpoint();
12891
12892 if (const auto *AMemoryBehavior = A.getOrCreateAAFor<AAMemoryBehavior>(
12893 getIRPosition(), this, DepClassTy::REQUIRED)) {
12894 // For non-instructions, try to use AAMemoryBehavior to infer the readonly
12895 // attribute
12896 if (!AMemoryBehavior->isAssumedReadOnly())
12897 return indicatePessimisticFixpoint();
12898
12899 if (AMemoryBehavior->isKnownReadOnly()) {
12900 addKnownBits(IS_NOEFFECT);
12901 return ChangeStatus::UNCHANGED;
12902 }
12903
12904 return ChangeStatus::UNCHANGED;
12905 }
12906
12907 if (const Argument *Arg = getAssociatedArgument()) {
12908 if (Arg->onlyReadsMemory()) {
12909 addKnownBits(IS_NOEFFECT);
12910 return ChangeStatus::UNCHANGED;
12911 }
12912
12913 // Readonly information is not provided, and cannot be inferred from
12914 // AAMemoryBehavior.
12915 return indicatePessimisticFixpoint();
12916 }
12917
12918 return ChangeStatus::UNCHANGED;
12919 }
12920
12921 ChangeStatus updateLocalInvariance(Attributor &A) {
12922 if (isKnown(IS_LOCALLY_INVARIANT) || !isAssumed(IS_LOCALLY_INVARIANT))
12923 return ChangeStatus::UNCHANGED;
12924
12925 // try to infer invariance from underlying objects
12926 const auto *AUO = A.getOrCreateAAFor<AAUnderlyingObjects>(
12927 getIRPosition(), this, DepClassTy::REQUIRED);
12928 if (!AUO)
12929 return ChangeStatus::UNCHANGED;
12930
12931 bool UsedAssumedInformation = false;
12932 const auto IsLocallyInvariantLoadIfPointer = [&](const Value &V) {
12933 if (!V.getType()->isPointerTy())
12934 return true;
12935 const auto *IsInvariantLoadPointer =
12936 A.getOrCreateAAFor<AAInvariantLoadPointer>(IRPosition::value(V), this,
12937 DepClassTy::REQUIRED);
12938 // Conservatively fail if invariance cannot be inferred.
12939 if (!IsInvariantLoadPointer)
12940 return false;
12941
12942 if (IsInvariantLoadPointer->isKnownLocallyInvariant())
12943 return true;
12944 if (!IsInvariantLoadPointer->isAssumedLocallyInvariant())
12945 return false;
12946
12947 UsedAssumedInformation = true;
12948 return true;
12949 };
12950 if (!AUO->forallUnderlyingObjects(IsLocallyInvariantLoadIfPointer))
12951 return indicatePessimisticFixpoint();
12952
12953 if (const auto *CB = dyn_cast<CallBase>(&getAnchorValue())) {
12955 CB, /*MustPreserveOffset=*/false)) {
12956 for (const Value *Arg : CB->args()) {
12957 if (!IsLocallyInvariantLoadIfPointer(*Arg))
12958 return indicatePessimisticFixpoint();
12959 }
12960 }
12961 }
12962
12963 if (!UsedAssumedInformation) {
12964 // Pointer is known and not just assumed to be locally invariant.
12965 addKnownBits(IS_LOCALLY_INVARIANT);
12966 return ChangeStatus::CHANGED;
12967 }
12968
12969 return ChangeStatus::UNCHANGED;
12970 }
12971};
12972
12973struct AAInvariantLoadPointerFloating final : AAInvariantLoadPointerImpl {
12974 AAInvariantLoadPointerFloating(const IRPosition &IRP, Attributor &A)
12975 : AAInvariantLoadPointerImpl(IRP, A) {}
12976};
12977
12978struct AAInvariantLoadPointerReturned final : AAInvariantLoadPointerImpl {
12979 AAInvariantLoadPointerReturned(const IRPosition &IRP, Attributor &A)
12980 : AAInvariantLoadPointerImpl(IRP, A) {}
12981
12982 void initialize(Attributor &) override {
12983 removeAssumedBits(IS_LOCALLY_CONSTRAINED);
12984 }
12985};
12986
12987struct AAInvariantLoadPointerCallSiteReturned final
12988 : AAInvariantLoadPointerImpl {
12989 AAInvariantLoadPointerCallSiteReturned(const IRPosition &IRP, Attributor &A)
12990 : AAInvariantLoadPointerImpl(IRP, A) {}
12991
12992 void initialize(Attributor &A) override {
12993 // Nothing is known about the result of an indirect call.
12994 const Function *F = getAssociatedFunction();
12995 if (!F) {
12996 indicatePessimisticFixpoint();
12997 return;
12998 }
12999
13000 if (!F->isDeclaration() && !F->isIntrinsic())
13001 return AAInvariantLoadPointerImpl::initialize(A);
13002
13003 const auto &CB = cast<CallBase>(getAnchorValue());
13005 &CB, /*MustPreserveOffset=*/false))
13006 return AAInvariantLoadPointerImpl::initialize(A);
13007
13008 if (F->onlyReadsMemory() && F->hasNoSync())
13009 return AAInvariantLoadPointerImpl::initialize(A);
13010
13011 // At this point, the function is opaque, so we conservatively assume
13012 // non-invariance.
13013 indicatePessimisticFixpoint();
13014 }
13015};
13016
13017struct AAInvariantLoadPointerArgument final : AAInvariantLoadPointerImpl {
13018 AAInvariantLoadPointerArgument(const IRPosition &IRP, Attributor &A)
13019 : AAInvariantLoadPointerImpl(IRP, A) {}
13020
13021 void initialize(Attributor &) override {
13022 const Function *F = getAssociatedFunction();
13023 assert(F && "no associated function for argument");
13024
13025 if (!isCallableCC(F->getCallingConv())) {
13026 addKnownBits(IS_LOCALLY_CONSTRAINED);
13027 return;
13028 }
13029
13030 if (!F->hasLocalLinkage())
13031 removeAssumedBits(IS_LOCALLY_CONSTRAINED);
13032 }
13033};
13034
13035struct AAInvariantLoadPointerCallSiteArgument final
13036 : AAInvariantLoadPointerImpl {
13037 AAInvariantLoadPointerCallSiteArgument(const IRPosition &IRP, Attributor &A)
13038 : AAInvariantLoadPointerImpl(IRP, A) {}
13039};
13040} // namespace
13041
13042/// ------------------------ Address Space ------------------------------------
13043namespace {
13044
13045template <typename InstType>
13046static bool makeChange(Attributor &A, InstType *MemInst, const Use &U,
13047 Value *OriginalValue, PointerType *NewPtrTy,
13048 bool UseOriginalValue) {
13049 if (U.getOperandNo() != InstType::getPointerOperandIndex())
13050 return false;
13051
13052 if (MemInst->isVolatile()) {
13053 auto *TTI = A.getInfoCache().getAnalysisResultForFunction<TargetIRAnalysis>(
13054 *MemInst->getFunction());
13055 unsigned NewAS = NewPtrTy->getPointerAddressSpace();
13056 if (!TTI || !TTI->hasVolatileVariant(MemInst, NewAS))
13057 return false;
13058 }
13059
13060 if (UseOriginalValue) {
13061 A.changeUseAfterManifest(const_cast<Use &>(U), *OriginalValue);
13062 return true;
13063 }
13064
13065 Instruction *CastInst = new AddrSpaceCastInst(OriginalValue, NewPtrTy);
13066 CastInst->insertBefore(MemInst->getIterator());
13067 A.changeUseAfterManifest(const_cast<Use &>(U), *CastInst);
13068 return true;
13069}
13070
13071struct AAAddressSpaceImpl : public AAAddressSpace {
13072 AAAddressSpaceImpl(const IRPosition &IRP, Attributor &A)
13073 : AAAddressSpace(IRP, A) {}
13074
13075 uint32_t getAddressSpace() const override {
13076 assert(isValidState() && "the AA is invalid");
13077 return AssumedAddressSpace;
13078 }
13079
13080 /// See AbstractAttribute::initialize(...).
13081 void initialize(Attributor &A) override {
13082 assert(getAssociatedType()->isPtrOrPtrVectorTy() &&
13083 "Associated value is not a pointer");
13084
13085 if (!A.getInfoCache().getFlatAddressSpace().has_value()) {
13086 indicatePessimisticFixpoint();
13087 return;
13088 }
13089
13090 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13091 unsigned AS = getAssociatedType()->getPointerAddressSpace();
13092 if (AS != FlatAS) {
13093 [[maybe_unused]] bool R = takeAddressSpace(AS);
13094 assert(R && "The take should happen");
13095 indicateOptimisticFixpoint();
13096 }
13097 }
13098
13099 ChangeStatus updateImpl(Attributor &A) override {
13100 uint32_t OldAddressSpace = AssumedAddressSpace;
13101 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13102
13103 auto CheckAddressSpace = [&](Value &Obj) {
13104 // Ignore undef.
13105 if (isa<UndefValue>(&Obj))
13106 return true;
13107
13108 // If the object already has a non-flat address space, we simply take it.
13109 unsigned ObjAS = Obj.getType()->getPointerAddressSpace();
13110 if (ObjAS != FlatAS)
13111 return takeAddressSpace(ObjAS);
13112
13113 // At this point, we know Obj is in the flat address space. For a final
13114 // attempt, we want to use getAssumedAddrSpace, but first we must get the
13115 // associated function, if possible.
13116 Function *F = nullptr;
13117 if (auto *Arg = dyn_cast<Argument>(&Obj))
13118 F = Arg->getParent();
13119 else if (auto *I = dyn_cast<Instruction>(&Obj))
13120 F = I->getFunction();
13121
13122 // Use getAssumedAddrSpace if the associated function exists.
13123 if (F) {
13124 auto *TTI =
13125 A.getInfoCache().getAnalysisResultForFunction<TargetIRAnalysis>(*F);
13126 unsigned AssumedAS = TTI->getAssumedAddrSpace(&Obj);
13127 if (AssumedAS != ~0U)
13128 return takeAddressSpace(AssumedAS);
13129 }
13130
13131 // Now we can't do anything else but to take the flat AS.
13132 return takeAddressSpace(FlatAS);
13133 };
13134
13135 auto *AUO = A.getOrCreateAAFor<AAUnderlyingObjects>(getIRPosition(), this,
13136 DepClassTy::REQUIRED);
13137 if (!AUO->forallUnderlyingObjects(CheckAddressSpace))
13138 return indicatePessimisticFixpoint();
13139
13140 return OldAddressSpace == AssumedAddressSpace ? ChangeStatus::UNCHANGED
13141 : ChangeStatus::CHANGED;
13142 }
13143
13144 /// See AbstractAttribute::manifest(...).
13145 ChangeStatus manifest(Attributor &A) override {
13146 unsigned NewAS = getAddressSpace();
13147
13148 if (NewAS == InvalidAddressSpace ||
13149 NewAS == getAssociatedType()->getPointerAddressSpace())
13150 return ChangeStatus::UNCHANGED;
13151
13152 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13153
13154 Value *AssociatedValue = &getAssociatedValue();
13155 Value *OriginalValue = peelAddrspacecast(AssociatedValue, FlatAS);
13156
13157 PointerType *NewPtrTy =
13158 PointerType::get(getAssociatedType()->getContext(), NewAS);
13159 bool UseOriginalValue =
13160 OriginalValue->getType()->getPointerAddressSpace() == NewAS;
13161
13162 bool Changed = false;
13163
13164 auto Pred = [&](const Use &U, bool &) {
13165 if (U.get() != AssociatedValue)
13166 return true;
13167 auto *Inst = dyn_cast<Instruction>(U.getUser());
13168 if (!Inst)
13169 return true;
13170 // This is a WA to make sure we only change uses from the corresponding
13171 // CGSCC if the AA is run on CGSCC instead of the entire module.
13172 if (!A.isRunOn(Inst->getFunction()))
13173 return true;
13174 if (auto *LI = dyn_cast<LoadInst>(Inst)) {
13175 Changed |=
13176 makeChange(A, LI, U, OriginalValue, NewPtrTy, UseOriginalValue);
13177 } else if (auto *SI = dyn_cast<StoreInst>(Inst)) {
13178 Changed |=
13179 makeChange(A, SI, U, OriginalValue, NewPtrTy, UseOriginalValue);
13180 } else if (auto *RMW = dyn_cast<AtomicRMWInst>(Inst)) {
13181 Changed |=
13182 makeChange(A, RMW, U, OriginalValue, NewPtrTy, UseOriginalValue);
13183 } else if (auto *CmpX = dyn_cast<AtomicCmpXchgInst>(Inst)) {
13184 Changed |=
13185 makeChange(A, CmpX, U, OriginalValue, NewPtrTy, UseOriginalValue);
13186 }
13187 return true;
13188 };
13189
13190 // It doesn't matter if we can't check all uses as we can simply
13191 // conservatively ignore those that can not be visited.
13192 (void)A.checkForAllUses(Pred, *this, getAssociatedValue(),
13193 /* CheckBBLivenessOnly */ true);
13194
13195 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
13196 }
13197
13198 /// See AbstractAttribute::getAsStr().
13199 const std::string getAsStr(Attributor *A) const override {
13200 if (!isValidState())
13201 return "addrspace(<invalid>)";
13202 return "addrspace(" +
13203 (AssumedAddressSpace == InvalidAddressSpace
13204 ? "none"
13205 : std::to_string(AssumedAddressSpace)) +
13206 ")";
13207 }
13208
13209private:
13210 uint32_t AssumedAddressSpace = InvalidAddressSpace;
13211
13212 bool takeAddressSpace(uint32_t AS) {
13213 if (AssumedAddressSpace == InvalidAddressSpace) {
13214 AssumedAddressSpace = AS;
13215 return true;
13216 }
13217 return AssumedAddressSpace == AS;
13218 }
13219
13220 static Value *peelAddrspacecast(Value *V, unsigned FlatAS) {
13221 if (auto *I = dyn_cast<AddrSpaceCastInst>(V)) {
13222 assert(I->getSrcAddressSpace() != FlatAS &&
13223 "there should not be flat AS -> non-flat AS");
13224 return I->getPointerOperand();
13225 }
13226 if (auto *C = dyn_cast<ConstantExpr>(V))
13227 if (C->getOpcode() == Instruction::AddrSpaceCast) {
13228 assert(C->getOperand(0)->getType()->getPointerAddressSpace() !=
13229 FlatAS &&
13230 "there should not be flat AS -> non-flat AS X");
13231 return C->getOperand(0);
13232 }
13233 return V;
13234 }
13235};
13236
13237struct AAAddressSpaceFloating final : AAAddressSpaceImpl {
13238 AAAddressSpaceFloating(const IRPosition &IRP, Attributor &A)
13239 : AAAddressSpaceImpl(IRP, A) {}
13240
13241 void trackStatistics() const override {
13243 }
13244};
13245
13246struct AAAddressSpaceReturned final : AAAddressSpaceImpl {
13247 AAAddressSpaceReturned(const IRPosition &IRP, Attributor &A)
13248 : AAAddressSpaceImpl(IRP, A) {}
13249
13250 /// See AbstractAttribute::initialize(...).
13251 void initialize(Attributor &A) override {
13252 // TODO: we don't rewrite function argument for now because it will need to
13253 // rewrite the function signature and all call sites.
13254 (void)indicatePessimisticFixpoint();
13255 }
13256
13257 void trackStatistics() const override {
13258 STATS_DECLTRACK_FNRET_ATTR(addrspace);
13259 }
13260};
13261
13262struct AAAddressSpaceCallSiteReturned final : AAAddressSpaceImpl {
13263 AAAddressSpaceCallSiteReturned(const IRPosition &IRP, Attributor &A)
13264 : AAAddressSpaceImpl(IRP, A) {}
13265
13266 void trackStatistics() const override {
13267 STATS_DECLTRACK_CSRET_ATTR(addrspace);
13268 }
13269};
13270
13271struct AAAddressSpaceArgument final : AAAddressSpaceImpl {
13272 AAAddressSpaceArgument(const IRPosition &IRP, Attributor &A)
13273 : AAAddressSpaceImpl(IRP, A) {}
13274
13275 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(addrspace); }
13276};
13277
13278struct AAAddressSpaceCallSiteArgument final : AAAddressSpaceImpl {
13279 AAAddressSpaceCallSiteArgument(const IRPosition &IRP, Attributor &A)
13280 : AAAddressSpaceImpl(IRP, A) {}
13281
13282 /// See AbstractAttribute::initialize(...).
13283 void initialize(Attributor &A) override {
13284 // TODO: we don't rewrite call site argument for now because it will need to
13285 // rewrite the function signature of the callee.
13286 (void)indicatePessimisticFixpoint();
13287 }
13288
13289 void trackStatistics() const override {
13290 STATS_DECLTRACK_CSARG_ATTR(addrspace);
13291 }
13292};
13293} // namespace
13294
13295/// ------------------------ No Alias Address Space ---------------------------
13296// This attribute assumes flat address space can alias all other address space
13297
13298// TODO: this is similar to AAAddressSpace, most of the code should be merged.
13299// But merging it created failing cased on gateway test that cannot be
13300// reproduced locally. So should open a separated PR to handle the merge of
13301// AANoAliasAddrSpace and AAAddressSpace attribute
13302
13303namespace {
13304struct AANoAliasAddrSpaceImpl : public AANoAliasAddrSpace {
13305 AANoAliasAddrSpaceImpl(const IRPosition &IRP, Attributor &A)
13306 : AANoAliasAddrSpace(IRP, A) {}
13307
13308 void initialize(Attributor &A) override {
13309 assert(getAssociatedType()->isPtrOrPtrVectorTy() &&
13310 "Associated value is not a pointer");
13311
13312 resetASRanges(A);
13313
13314 std::optional<unsigned> FlatAS = A.getInfoCache().getFlatAddressSpace();
13315 if (!FlatAS.has_value()) {
13316 indicatePessimisticFixpoint();
13317 return;
13318 }
13319
13320 removeAS(*FlatAS);
13321
13322 unsigned AS = getAssociatedType()->getPointerAddressSpace();
13323 if (AS != *FlatAS) {
13324 removeAS(AS);
13325 indicateOptimisticFixpoint();
13326 }
13327 }
13328
13329 ChangeStatus updateImpl(Attributor &A) override {
13330 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13331 uint32_t OldAssumed = getAssumed();
13332
13333 auto CheckAddressSpace = [&](Value &Obj) {
13334 if (isa<PoisonValue>(&Obj))
13335 return true;
13336
13337 unsigned AS = Obj.getType()->getPointerAddressSpace();
13338 if (AS == FlatAS)
13339 return false;
13340
13341 removeAS(Obj.getType()->getPointerAddressSpace());
13342 return true;
13343 };
13344
13345 const AAUnderlyingObjects *AUO = A.getOrCreateAAFor<AAUnderlyingObjects>(
13346 getIRPosition(), this, DepClassTy::REQUIRED);
13347 if (!AUO->forallUnderlyingObjects(CheckAddressSpace))
13348 return indicatePessimisticFixpoint();
13349
13350 return OldAssumed == getAssumed() ? ChangeStatus::UNCHANGED
13351 : ChangeStatus::CHANGED;
13352 }
13353
13354 /// See AbstractAttribute::manifest(...).
13355 ChangeStatus manifest(Attributor &A) override {
13356 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13357
13358 unsigned AS = getAssociatedType()->getPointerAddressSpace();
13359 if (AS != FlatAS || Map.empty())
13360 return ChangeStatus::UNCHANGED;
13361
13362 LLVMContext &Ctx = getAssociatedValue().getContext();
13363 MDNode *NoAliasASNode = nullptr;
13364 MDBuilder MDB(Ctx);
13365 // Has to use iterator to get the range info.
13366 for (RangeMap::const_iterator I = Map.begin(); I != Map.end(); I++) {
13367 if (!I.value())
13368 continue;
13369 unsigned Upper = I.stop();
13370 unsigned Lower = I.start();
13371 if (!NoAliasASNode) {
13372 NoAliasASNode = MDB.createRange(APInt(32, Lower), APInt(32, Upper + 1));
13373 continue;
13374 }
13375 MDNode *ASRange = MDB.createRange(APInt(32, Lower), APInt(32, Upper + 1));
13376 NoAliasASNode = MDNode::getMostGenericRange(NoAliasASNode, ASRange);
13377 }
13378
13379 Value *AssociatedValue = &getAssociatedValue();
13380 bool Changed = false;
13381
13382 auto AddNoAliasAttr = [&](const Use &U, bool &) {
13383 if (U.get() != AssociatedValue)
13384 return true;
13385 Instruction *Inst = dyn_cast<Instruction>(U.getUser());
13386 if (!Inst || Inst->hasMetadata(LLVMContext::MD_noalias_addrspace))
13387 return true;
13388 if (!isa<LoadInst>(Inst) && !isa<StoreInst>(Inst) &&
13390 return true;
13391 if (!A.isRunOn(Inst->getFunction()))
13392 return true;
13393 Inst->setMetadata(LLVMContext::MD_noalias_addrspace, NoAliasASNode);
13394 Changed = true;
13395 return true;
13396 };
13397 (void)A.checkForAllUses(AddNoAliasAttr, *this, *AssociatedValue,
13398 /*CheckBBLivenessOnly=*/true);
13399 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
13400 }
13401
13402 /// See AbstractAttribute::getAsStr().
13403 const std::string getAsStr(Attributor *A) const override {
13404 if (!isValidState())
13405 return "<invalid>";
13406 std::string Str;
13407 raw_string_ostream OS(Str);
13408 OS << "CanNotBeAddrSpace(";
13409 for (RangeMap::const_iterator I = Map.begin(); I != Map.end(); I++) {
13410 unsigned Upper = I.stop();
13411 unsigned Lower = I.start();
13412 OS << ' ' << '[' << Upper << ',' << Lower + 1 << ')';
13413 }
13414 OS << " )";
13415 return OS.str();
13416 }
13417
13418private:
13419 void removeAS(unsigned AS) {
13420 RangeMap::iterator I = Map.find(AS);
13421
13422 if (I != Map.end()) {
13423 unsigned Upper = I.stop();
13424 unsigned Lower = I.start();
13425 I.erase();
13426 if (Upper == Lower)
13427 return;
13428 if (AS != ~((unsigned)0) && AS + 1 <= Upper)
13429 Map.insert(AS + 1, Upper, /*what ever this variable name is=*/true);
13430 if (AS != 0 && Lower <= AS - 1)
13431 Map.insert(Lower, AS - 1, true);
13432 }
13433 }
13434
13435 void resetASRanges(Attributor &A) {
13436 Map.clear();
13437 Map.insert(0, A.getInfoCache().getMaxAddrSpace(), true);
13438 }
13439};
13440
13441struct AANoAliasAddrSpaceFloating final : AANoAliasAddrSpaceImpl {
13442 AANoAliasAddrSpaceFloating(const IRPosition &IRP, Attributor &A)
13443 : AANoAliasAddrSpaceImpl(IRP, A) {}
13444
13445 void trackStatistics() const override {
13446 STATS_DECLTRACK_FLOATING_ATTR(noaliasaddrspace);
13447 }
13448};
13449
13450struct AANoAliasAddrSpaceReturned final : AANoAliasAddrSpaceImpl {
13451 AANoAliasAddrSpaceReturned(const IRPosition &IRP, Attributor &A)
13452 : AANoAliasAddrSpaceImpl(IRP, A) {}
13453
13454 void trackStatistics() const override {
13455 STATS_DECLTRACK_FNRET_ATTR(noaliasaddrspace);
13456 }
13457};
13458
13459struct AANoAliasAddrSpaceCallSiteReturned final : AANoAliasAddrSpaceImpl {
13460 AANoAliasAddrSpaceCallSiteReturned(const IRPosition &IRP, Attributor &A)
13461 : AANoAliasAddrSpaceImpl(IRP, A) {}
13462
13463 void trackStatistics() const override {
13464 STATS_DECLTRACK_CSRET_ATTR(noaliasaddrspace);
13465 }
13466};
13467
13468struct AANoAliasAddrSpaceArgument final : AANoAliasAddrSpaceImpl {
13469 AANoAliasAddrSpaceArgument(const IRPosition &IRP, Attributor &A)
13470 : AANoAliasAddrSpaceImpl(IRP, A) {}
13471
13472 void trackStatistics() const override {
13473 STATS_DECLTRACK_ARG_ATTR(noaliasaddrspace);
13474 }
13475};
13476
13477struct AANoAliasAddrSpaceCallSiteArgument final : AANoAliasAddrSpaceImpl {
13478 AANoAliasAddrSpaceCallSiteArgument(const IRPosition &IRP, Attributor &A)
13479 : AANoAliasAddrSpaceImpl(IRP, A) {}
13480
13481 void trackStatistics() const override {
13482 STATS_DECLTRACK_CSARG_ATTR(noaliasaddrspace);
13483 }
13484};
13485} // namespace
13486/// ----------- Allocation Info ----------
13487namespace {
13488struct AAAllocationInfoImpl : public AAAllocationInfo {
13489 AAAllocationInfoImpl(const IRPosition &IRP, Attributor &A)
13490 : AAAllocationInfo(IRP, A) {}
13491
13492 std::optional<TypeSize> getAllocatedSize() const override {
13493 assert(isValidState() && "the AA is invalid");
13494 return AssumedAllocatedSize;
13495 }
13496
13497 std::optional<TypeSize> findInitialAllocationSize(Instruction *I,
13498 const DataLayout &DL) {
13499
13500 // TODO: implement case for malloc like instructions
13501 switch (I->getOpcode()) {
13502 case Instruction::Alloca: {
13503 AllocaInst *AI = cast<AllocaInst>(I);
13504 return AI->getAllocationSize(DL);
13505 }
13506 default:
13507 return std::nullopt;
13508 }
13509 }
13510
13511 ChangeStatus updateImpl(Attributor &A) override {
13512
13513 const IRPosition &IRP = getIRPosition();
13514 Instruction *I = IRP.getCtxI();
13515
13516 // TODO: update check for malloc like calls
13517 if (!isa<AllocaInst>(I))
13518 return indicatePessimisticFixpoint();
13519
13520 bool IsKnownNoCapture;
13522 A, this, IRP, DepClassTy::OPTIONAL, IsKnownNoCapture))
13523 return indicatePessimisticFixpoint();
13524
13525 const AAPointerInfo *PI =
13526 A.getOrCreateAAFor<AAPointerInfo>(IRP, *this, DepClassTy::REQUIRED);
13527
13528 if (!PI)
13529 return indicatePessimisticFixpoint();
13530
13531 if (!PI->getState().isValidState() || PI->reachesReturn())
13532 return indicatePessimisticFixpoint();
13533
13534 const DataLayout &DL = A.getDataLayout();
13535 const auto AllocationSize = findInitialAllocationSize(I, DL);
13536
13537 // If allocation size is nullopt, we give up.
13538 if (!AllocationSize)
13539 return indicatePessimisticFixpoint();
13540
13541 // For zero sized allocations, we give up.
13542 // Since we can't reduce further
13543 if (*AllocationSize == 0)
13544 return indicatePessimisticFixpoint();
13545
13546 int64_t BinSize = PI->numOffsetBins();
13547
13548 // TODO: implement for multiple bins
13549 if (BinSize > 1)
13550 return indicatePessimisticFixpoint();
13551
13552 if (BinSize == 0) {
13553 auto NewAllocationSize = std::make_optional<TypeSize>(0, false);
13554 if (!changeAllocationSize(NewAllocationSize))
13555 return ChangeStatus::UNCHANGED;
13556 return ChangeStatus::CHANGED;
13557 }
13558
13559 // TODO: refactor this to be part of multiple bin case
13560 const auto &It = PI->begin();
13561
13562 // TODO: handle if Offset is not zero
13563 if (It->first.Offset != 0)
13564 return indicatePessimisticFixpoint();
13565
13566 uint64_t SizeOfBin = It->first.Offset + It->first.Size;
13567
13568 if (SizeOfBin >= *AllocationSize)
13569 return indicatePessimisticFixpoint();
13570
13571 auto NewAllocationSize = std::make_optional<TypeSize>(SizeOfBin * 8, false);
13572
13573 if (!changeAllocationSize(NewAllocationSize))
13574 return ChangeStatus::UNCHANGED;
13575
13576 return ChangeStatus::CHANGED;
13577 }
13578
13579 /// See AbstractAttribute::manifest(...).
13580 ChangeStatus manifest(Attributor &A) override {
13581
13582 assert(isValidState() &&
13583 "Manifest should only be called if the state is valid.");
13584
13585 Instruction *I = getIRPosition().getCtxI();
13586
13587 auto FixedAllocatedSizeInBits = getAllocatedSize()->getFixedValue();
13588
13589 unsigned long NumBytesToAllocate = (FixedAllocatedSizeInBits + 7) / 8;
13590
13591 switch (I->getOpcode()) {
13592 // TODO: add case for malloc like calls
13593 case Instruction::Alloca: {
13594
13595 AllocaInst *AI = cast<AllocaInst>(I);
13596
13597 Type *CharType = Type::getInt8Ty(I->getContext());
13598
13599 auto *NumBytesToValue =
13600 ConstantInt::get(I->getContext(), APInt(32, NumBytesToAllocate));
13601
13602 BasicBlock::iterator insertPt = AI->getIterator();
13603 insertPt = std::next(insertPt);
13604 AllocaInst *NewAllocaInst =
13605 new AllocaInst(CharType, AI->getAddressSpace(), NumBytesToValue,
13606 AI->getAlign(), AI->getName(), insertPt);
13607
13608 if (A.changeAfterManifest(IRPosition::inst(*AI), *NewAllocaInst))
13609 return ChangeStatus::CHANGED;
13610
13611 break;
13612 }
13613 default:
13614 break;
13615 }
13616
13617 return ChangeStatus::UNCHANGED;
13618 }
13619
13620 /// See AbstractAttribute::getAsStr().
13621 const std::string getAsStr(Attributor *A) const override {
13622 if (!isValidState())
13623 return "allocationinfo(<invalid>)";
13624 return "allocationinfo(" +
13625 (AssumedAllocatedSize == HasNoAllocationSize
13626 ? "none"
13627 : std::to_string(AssumedAllocatedSize->getFixedValue())) +
13628 ")";
13629 }
13630
13631private:
13632 std::optional<TypeSize> AssumedAllocatedSize = HasNoAllocationSize;
13633
13634 // Maintain the computed allocation size of the object.
13635 // Returns (bool) weather the size of the allocation was modified or not.
13636 bool changeAllocationSize(std::optional<TypeSize> Size) {
13637 if (AssumedAllocatedSize == HasNoAllocationSize ||
13638 AssumedAllocatedSize != Size) {
13639 AssumedAllocatedSize = Size;
13640 return true;
13641 }
13642 return false;
13643 }
13644};
13645
13646struct AAAllocationInfoFloating : AAAllocationInfoImpl {
13647 AAAllocationInfoFloating(const IRPosition &IRP, Attributor &A)
13648 : AAAllocationInfoImpl(IRP, A) {}
13649
13650 void trackStatistics() const override {
13651 STATS_DECLTRACK_FLOATING_ATTR(allocationinfo);
13652 }
13653};
13654
13655struct AAAllocationInfoReturned : AAAllocationInfoImpl {
13656 AAAllocationInfoReturned(const IRPosition &IRP, Attributor &A)
13657 : AAAllocationInfoImpl(IRP, A) {}
13658
13659 /// See AbstractAttribute::initialize(...).
13660 void initialize(Attributor &A) override {
13661 // TODO: we don't rewrite function argument for now because it will need to
13662 // rewrite the function signature and all call sites
13663 (void)indicatePessimisticFixpoint();
13664 }
13665
13666 void trackStatistics() const override {
13667 STATS_DECLTRACK_FNRET_ATTR(allocationinfo);
13668 }
13669};
13670
13671struct AAAllocationInfoCallSiteReturned : AAAllocationInfoImpl {
13672 AAAllocationInfoCallSiteReturned(const IRPosition &IRP, Attributor &A)
13673 : AAAllocationInfoImpl(IRP, A) {}
13674
13675 void trackStatistics() const override {
13676 STATS_DECLTRACK_CSRET_ATTR(allocationinfo);
13677 }
13678};
13679
13680struct AAAllocationInfoArgument : AAAllocationInfoImpl {
13681 AAAllocationInfoArgument(const IRPosition &IRP, Attributor &A)
13682 : AAAllocationInfoImpl(IRP, A) {}
13683
13684 void trackStatistics() const override {
13685 STATS_DECLTRACK_ARG_ATTR(allocationinfo);
13686 }
13687};
13688
13689struct AAAllocationInfoCallSiteArgument : AAAllocationInfoImpl {
13690 AAAllocationInfoCallSiteArgument(const IRPosition &IRP, Attributor &A)
13691 : AAAllocationInfoImpl(IRP, A) {}
13692
13693 /// See AbstractAttribute::initialize(...).
13694 void initialize(Attributor &A) override {
13695
13696 (void)indicatePessimisticFixpoint();
13697 }
13698
13699 void trackStatistics() const override {
13700 STATS_DECLTRACK_CSARG_ATTR(allocationinfo);
13701 }
13702};
13703} // namespace
13704
13705const char AANoUnwind::ID = 0;
13706const char AANoSync::ID = 0;
13707const char AANoFree::ID = 0;
13708const char AANonNull::ID = 0;
13709const char AAMustProgress::ID = 0;
13710const char AANoRecurse::ID = 0;
13711const char AANonConvergent::ID = 0;
13712const char AAWillReturn::ID = 0;
13713const char AAUndefinedBehavior::ID = 0;
13714const char AANoAlias::ID = 0;
13715const char AAIntraFnReachability::ID = 0;
13716const char AANoReturn::ID = 0;
13717const char AAIsDead::ID = 0;
13718const char AADereferenceable::ID = 0;
13719const char AAAlign::ID = 0;
13720const char AAInstanceInfo::ID = 0;
13721const char AANoCapture::ID = 0;
13722const char AAValueSimplify::ID = 0;
13723const char AAHeapToStack::ID = 0;
13724const char AAPrivatizablePtr::ID = 0;
13725const char AAMemoryBehavior::ID = 0;
13726const char AAMemoryLocation::ID = 0;
13727const char AAValueConstantRange::ID = 0;
13728const char AAPotentialConstantValues::ID = 0;
13729const char AAPotentialValues::ID = 0;
13730const char AANoUndef::ID = 0;
13731const char AANoFPClass::ID = 0;
13732const char AACallEdges::ID = 0;
13733const char AAInterFnReachability::ID = 0;
13734const char AAPointerInfo::ID = 0;
13735const char AAAssumptionInfo::ID = 0;
13736const char AAUnderlyingObjects::ID = 0;
13737const char AAInvariantLoadPointer::ID = 0;
13738const char AAAddressSpace::ID = 0;
13739const char AANoAliasAddrSpace::ID = 0;
13740const char AAAllocationInfo::ID = 0;
13741const char AAIndirectCallInfo::ID = 0;
13742const char AAGlobalValueInfo::ID = 0;
13743const char AADenormalFPMath::ID = 0;
13744
13745// Macro magic to create the static generator function for attributes that
13746// follow the naming scheme.
13747
13748#define SWITCH_PK_INV(CLASS, PK, POS_NAME) \
13749 case IRPosition::PK: \
13750 llvm_unreachable("Cannot create " #CLASS " for a " POS_NAME " position!");
13751
13752#define SWITCH_PK_CREATE(CLASS, IRP, PK, SUFFIX) \
13753 case IRPosition::PK: \
13754 AA = new (A.Allocator) CLASS##SUFFIX(IRP, A); \
13755 ++NumAAs; \
13756 break;
13757
13758#define CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13759 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13760 CLASS *AA = nullptr; \
13761 switch (IRP.getPositionKind()) { \
13762 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13763 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
13764 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
13765 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
13766 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
13767 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
13768 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
13769 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
13770 } \
13771 return *AA; \
13772 }
13773
13774#define CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13775 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13776 CLASS *AA = nullptr; \
13777 switch (IRP.getPositionKind()) { \
13778 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13779 SWITCH_PK_INV(CLASS, IRP_FUNCTION, "function") \
13780 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
13781 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
13782 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
13783 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
13784 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
13785 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
13786 } \
13787 return *AA; \
13788 }
13789
13790#define CREATE_ABSTRACT_ATTRIBUTE_FOR_ONE_POSITION(POS, SUFFIX, CLASS) \
13791 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13792 CLASS *AA = nullptr; \
13793 switch (IRP.getPositionKind()) { \
13794 SWITCH_PK_CREATE(CLASS, IRP, POS, SUFFIX) \
13795 default: \
13796 llvm_unreachable("Cannot create " #CLASS " for position otherthan " #POS \
13797 " position!"); \
13798 } \
13799 return *AA; \
13800 }
13801
13802#define CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13803 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13804 CLASS *AA = nullptr; \
13805 switch (IRP.getPositionKind()) { \
13806 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13807 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
13808 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
13809 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
13810 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
13811 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
13812 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
13813 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
13814 } \
13815 return *AA; \
13816 }
13817
13818#define CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13819 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13820 CLASS *AA = nullptr; \
13821 switch (IRP.getPositionKind()) { \
13822 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13823 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
13824 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
13825 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
13826 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
13827 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
13828 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
13829 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
13830 } \
13831 return *AA; \
13832 }
13833
13834#define CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13835 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13836 CLASS *AA = nullptr; \
13837 switch (IRP.getPositionKind()) { \
13838 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13839 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
13840 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
13841 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
13842 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
13843 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
13844 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
13845 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
13846 } \
13847 return *AA; \
13848 }
13849
13859
13877
13882
13887
13894
13896
13897#undef CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION
13898#undef CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION
13899#undef CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION
13900#undef CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION
13901#undef CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION
13902#undef CREATE_ABSTRACT_ATTRIBUTE_FOR_ONE_POSITION
13903#undef SWITCH_PK_CREATE
13904#undef SWITCH_PK_INV
#define Success
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
aarch64 promote const
uint64_t uint64_t
AMDGPU Register Bank Select
Rewrite undef for PHI
This file implements a class to represent arbitrary precision integral constant values and operations...
ReachingDefInfo InstSet & ToRemove
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis false
This file contains the simple types necessary to represent the attributes associated with functions a...
#define STATS_DECLTRACK(NAME, TYPE, MSG)
static std::optional< Constant * > askForAssumedConstant(Attributor &A, const AbstractAttribute &QueryingAA, const IRPosition &IRP, Type &Ty)
static cl::opt< unsigned, true > MaxPotentialValues("attributor-max-potential-values", cl::Hidden, cl::desc("Maximum number of potential values to be " "tracked for each position."), cl::location(llvm::PotentialConstantIntValuesState::MaxPotentialValues), cl::init(7))
static void clampReturnedValueStates(Attributor &A, const AAType &QueryingAA, StateType &S, const IRPosition::CallBaseContext *CBContext=nullptr)
Clamp the information known for all returned values of a function (identified by QueryingAA) into S.
#define STATS_DECLTRACK_FN_ATTR(NAME)
#define CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
static cl::opt< int > MaxPotentialValuesIterations("attributor-max-potential-values-iterations", cl::Hidden, cl::desc("Maximum number of iterations we keep dismantling potential values."), cl::init(64))
#define STATS_DECLTRACK_CS_ATTR(NAME)
#define PIPE_OPERATOR(CLASS)
#define 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)
static bool mayBeInCycle(const CycleInfo *CI, const Instruction *I, bool HeaderOnly, CycleRef *CPtr=nullptr)
#define STATS_DECLTRACK_FNRET_ATTR(NAME)
#define STATS_DECLTRACK_CSARG_ATTR(NAME)
#define CREATE_ABSTRACT_ATTRIBUTE_FOR_ONE_POSITION(POS, SUFFIX, CLASS)
#define CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
static cl::opt< int > MaxHeapToStackSize("max-heap-to-stack-size", cl::init(128), cl::Hidden)
#define CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
#define STATS_DECLTRACK_FLOATING_ATTR(NAME)
#define STATS_DECL(NAME, TYPE, MSG)
basic Basic Alias true
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static bool isReachableImpl(SmallVectorImpl< BasicBlock * > &Worklist, const StopSetT &StopSet, const SmallPtrSetImpl< BasicBlock * > *ExclusionSet, const DominatorTree *DT, const LoopInfo *LI, const CycleInfo *CI)
Definition CFG.cpp:145
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file declares an analysis pass that computes CycleInfo for LLVM IR, specialized from GenericCycl...
static uint64_t align(uint64_t Size)
DXIL Forward Handle Accesses
DXIL Resource Access
dxil translate DXIL Translate Metadata
This file defines DenseMapInfo traits for DenseMap.
This file defines the DenseMap class.
#define Check(C,...)
static Value * getCondition(Instruction *I)
Hexagon Common GEP
IRTranslator LLVM IR MI
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
Machine Check Debug Module
This file implements a map that provides insertion order iteration.
#define T
#define T1
static unsigned getAddressSpace(const Value *V, unsigned MaxLookup)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
uint64_t IntrinsicInst * II
if(PassOpts->AAPipeline)
static StringRef getName(Value *V)
Basic Register Allocator
dot regions Print regions of function to dot true view regions View regions of function(with no function bodies)"
Remove Loads Into Fake Uses
This builds on the llvm/ADT/GraphTraits.h file to find the strongly connected components (SCCs) of a ...
bool IsDead
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
std::pair< BasicBlock *, BasicBlock * > Edge
This file contains some templates that are useful if you are working with the STL at all.
BaseType
A given derived pointer can have multiple base pointers through phi/selects.
This file defines generic set operations that may be used on set's of different types,...
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition Statistic.h:171
This file contains some functions that are useful when dealing with strings.
#define LLVM_DEBUG(...)
Definition Debug.h:119
static SymbolRef::Type getType(const Symbol *Sym)
Definition TapiFile.cpp:39
static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, const llvm::StringTable &StandardNames, VectorLibrary VecLib)
Initialize the set of available library functions based on the specified target triple.
This pass exposes codegen information to IR-level passes.
static unsigned getBitWidth(Type *Ty, const DataLayout &DL)
Returns the bitwidth of the given scalar or pointer type.
Value * RHS
Value * LHS
static unsigned getSize(unsigned Kind)
LLVM_ABI AACallGraphNode * operator*() const
bool isNoAlias(const MemoryLocation &LocA, const MemoryLocation &LocB)
A trivial helper function to check to see if the specified pointers are no-alias.
Class for arbitrary precision integers.
Definition APInt.h:78
int64_t getSExtValue() const
Get sign extended value.
Definition APInt.h:1582
CallBase * getInstruction() const
Return the underlying instruction.
bool isCallbackCall() const
Return true if this ACS represents a callback call.
bool isDirectCall() const
Return true if this ACS represents a direct call.
static LLVM_ABI void getCallbackUses(const CallBase &CB, SmallVectorImpl< const Use * > &CallbackUses)
Add operand uses of CB that represent callback uses into CallbackUses.
int getCallArgOperandNo(Argument &Arg) const
Return the operand index of the underlying instruction associated with Arg.
Align getAlign() const
Return the alignment of the memory that is being allocated by the instruction.
unsigned getAddressSpace() const
Return the address space for the allocation.
LLVM_ABI std::optional< TypeSize > getAllocationSize(const DataLayout &DL) const
Get allocation size in bytes.
This class represents an incoming formal argument to a Function.
Definition Argument.h:32
LLVM_ABI bool hasNoAliasAttr() const
Return true if this argument has the noalias attribute.
Definition Function.cpp:266
LLVM_ABI bool onlyReadsMemory() const
Return true if this argument has the readonly or readnone attribute.
Definition Function.cpp:302
LLVM_ABI bool hasPointeeInMemoryValueAttr() const
Return true if this argument has the byval, sret, inalloca, preallocated, or byref attribute.
Definition Function.cpp:169
LLVM_ABI bool hasReturnedAttr() const
Return true if this argument has the returned attribute.
Definition Function.cpp:290
LLVM_ABI bool hasByValAttr() const
Return true if this argument has the byval attribute.
Definition Function.cpp:126
const Function * getParent() const
Definition Argument.h:44
unsigned getArgNo() const
Return the index of this formal argument in its containing function.
Definition Argument.h:50
A function analysis which provides an AssumptionCache.
A cache of @llvm.assume calls within a function.
Functions, function parameters, and return types can have attributes to indicate how they should be t...
Definition Attributes.h:106
static LLVM_ABI Attribute get(LLVMContext &Context, AttrKind Kind, uint64_t Val=0)
Return a uniquified Attribute object.
LLVM_ABI FPClassTest getNoFPClass() const
Return the FPClassTest for nofpclass.
LLVM_ABI Attribute::AttrKind getKindAsEnum() const
Return the attribute's kind as an enum (Attribute::AttrKind).
LLVM_ABI MemoryEffects getMemoryEffects() const
Returns memory effects.
AttrKind
This enumeration lists the attributes that can be associated with parameters, function results,...
Definition Attributes.h:125
static LLVM_ABI Attribute getWithCaptureInfo(LLVMContext &Context, CaptureInfo CI)
static bool isEnumAttrKind(AttrKind Kind)
Definition Attributes.h:139
bool isValid() const
Return true if the attribute is any kind of attribute.
Definition Attributes.h:262
LLVM_ABI CaptureInfo getCaptureInfo() const
Returns information from captures attribute.
LLVM Basic Block Representation.
Definition BasicBlock.h:62
LLVM_ABI const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
const Function * getParent() const
Return the enclosing method, or null if none.
Definition BasicBlock.h:213
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition BasicBlock.h:206
const Instruction & front() const
Definition BasicBlock.h:463
InstListType::iterator iterator
Instruction iterators...
Definition BasicBlock.h:170
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
Definition BasicBlock.h:237
BinaryOps getOpcode() const
Definition InstrTypes.h:409
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
LLVM_ABI bool isMustTailCall() const
Tests if this call site must be tail call optimized.
LLVM_ABI bool isIndirectCall() const
Return true if the callsite is an indirect call.
bool isCallee(Value::const_user_iterator UI) const
Determine whether the passed iterator points to the callee operand's Use.
Value * getCalledOperand() const
const Use & getCalledOperandUse() const
Attribute getFnAttr(StringRef Kind) const
Get the attribute of a given kind for the function.
const Use & getArgOperandUse(unsigned i) const
Wrappers for getting the Use of a call argument.
LLVM_ABI std::optional< ConstantRange > getRange() const
If this return value has a range attribute, return the value range of the argument.
Value * getArgOperand(unsigned i) const
bool isBundleOperand(unsigned Idx) const
Return true if the operand at index Idx is a bundle operand.
bool isConvergent() const
Determine if the invoke is convergent.
FunctionType * getFunctionType() const
LLVM_ABI Intrinsic::ID getIntrinsicID() const
Returns the intrinsic ID of the intrinsic called or Intrinsic::not_intrinsic if the called function i...
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
unsigned getArgOperandNo(const Use *U) const
Given a use for a arg operand, get the arg operand number that corresponds to it.
unsigned arg_size() const
bool isArgOperand(const Use *U) const
LLVM_ABI Function * getCaller()
Helper to get the caller (the parent function).
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
static CaptureInfo none()
Create CaptureInfo that does not capture any components of the pointer.
Definition ModRef.h:427
Instruction::CastOps getOpcode() const
Return the opcode of this CastInst.
Definition InstrTypes.h:674
LLVM_ABI bool isIntegerCast() const
There are several places where we need to know if a cast instruction only deals with integer source a...
Type * getDestTy() const
Return the destination type, as a convenience.
Definition InstrTypes.h:681
bool isEquality() const
Determine if this is an equals/not equals predicate.
Definition InstrTypes.h:978
bool isFalseWhenEqual() const
This is just a convenience.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition InstrTypes.h:740
@ ICMP_NE
not equal
Definition InstrTypes.h:762
bool isTrueWhenEqual() const
This is just a convenience.
Predicate getPredicate() const
Return the predicate for this instruction.
Definition InstrTypes.h:828
Conditional Branch instruction.
Value * getCondition() const
BasicBlock * getSuccessor(unsigned i) const
static ConstantAsMetadata * get(Constant *C)
Definition Metadata.h:548
static LLVM_ABI Constant * getExtractElement(Constant *Vec, Constant *Idx, Type *OnlyIfReducedTy=nullptr)
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
This class represents a range of values.
const APInt & getLower() const
Return the lower value for this range.
LLVM_ABI bool isFullSet() const
Return true if this set contains all of the elements possible for this data-type.
LLVM_ABI bool isEmptySet() const
Return true if this set contains no members.
bool isSingleElement() const
Return true if this set contains exactly one member.
static LLVM_ABI ConstantRange makeAllowedICmpRegion(CmpInst::Predicate Pred, const ConstantRange &Other)
Produce the smallest range such that all values that may satisfy the given predicate with any value c...
const APInt & getUpper() const
Return the upper value for this range.
LLVM_ABI bool contains(const APInt &Val) const
Return true if the specified value is in the set.
Opaque handle to a cycle within a GenericCycleInfo that wraps the cycle's preorder index.
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
unsigned getProgramAddressSpace() const
Definition DataLayout.h:269
bool contains(const_arg_type_t< KeyT > Val) const
Return true if the specified key is in the map, false otherwise.
Definition DenseMap.h:757
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:762
iterator find(const_arg_type_t< KeyT > Val)
Definition DenseMap.h:766
iterator end()
Definition DenseMap.h:686
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition DenseMap.h:827
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
Definition DenseMap.h:856
Analysis pass which computes a DominatorTree.
Definition Dominators.h:241
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition Dominators.h:122
LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
const BasicBlock & getEntryBlock() const
Definition Function.h:794
Argument * arg_iterator
Definition Function.h:73
iterator_range< arg_iterator > args()
Definition Function.h:877
const Function & getFunction() const
Definition Function.h:167
size_t arg_size() const
Definition Function.h:886
Argument * getArg(unsigned i) const
Definition Function.h:871
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition Function.cpp:731
BlockT * getHeader(CycleRef C) const
CycleRef getCycle(const BlockT *Block) const
Find the innermost cycle containing Block.
LLVM_ABI bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
Definition Globals.cpp:408
bool hasLocalLinkage() const
PointerType * getType() const
Global values are always pointers.
static LLVM_ABI bool compare(const APInt &LHS, const APInt &RHS, ICmpInst::Predicate Pred)
Return result of LHS Pred RHS comparison.
Value * CreatePtrAdd(Value *Ptr, Value *Offset, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
Definition IRBuilder.h:2092
ConstantInt * getInt64(uint64_t C)
Get a constant 64-bit value.
Definition IRBuilder.h:470
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2909
LLVM_ABI Instruction * clone() const
Create a copy of 'this' instruction that is identical in all ways except the following:
LLVM_ABI bool isLifetimeStartOrEnd() const LLVM_READONLY
Return true if the instruction is a llvm.lifetime.start or llvm.lifetime.end marker.
bool mayReadOrWriteMemory() const
Return true if this instruction may read or write memory.
LLVM_ABI bool mayWriteToMemory() const LLVM_READONLY
Return true if this instruction may modify memory.
bool hasMetadata() const
Return true if this instruction has any metadata attached to it.
LLVM_ABI void insertBefore(InstListType::iterator InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified position.
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
LLVM_ABI const Function * getFunction() const
Return the function this instruction belongs to.
LLVM_ABI BasicBlock * getSuccessor(unsigned Idx) const LLVM_READONLY
Return the specified successor. This instruction must be a terminator.
LLVM_ABI bool mayHaveSideEffects() const LLVM_READONLY
Return true if the instruction may have side effects.
bool isTerminator() const
LLVM_ABI bool mayReadFromMemory() const LLVM_READONLY
Return true if this instruction may read memory.
iterator_range< user_iterator > users()
LLVM_ABI void setMetadata(unsigned KindID, MDNode *Node)
Set the metadata of the specified kind to the specified node.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this instruction belongs to.
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:76
LLVM_ABI ConstantRange getConstantRange(Value *V, Instruction *CtxI, bool UndefAllowed)
Return the ConstantRange constraint that is known to hold for the specified value at the specified in...
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition Metadata.h:1579
static LLVM_ABI MDNode * getMostGenericRange(MDNode *A, MDNode *B)
bool empty() const
Definition MapVector.h:79
static MemoryEffectsBase readOnly()
Definition ModRef.h:133
bool doesNotAccessMemory() const
Whether this function accesses no memory.
Definition ModRef.h:246
static MemoryEffectsBase argMemOnly(ModRefInfo MR=ModRefInfo::ModRef)
Definition ModRef.h:143
static MemoryEffectsBase inaccessibleMemOnly(ModRefInfo MR=ModRefInfo::ModRef)
Definition ModRef.h:149
bool onlyAccessesInaccessibleMem() const
Whether this function only (at most) accesses inaccessible memory.
Definition ModRef.h:265
ModRefInfo getModRef(Location Loc) const
Get ModRefInfo for the given Location.
Definition ModRef.h:219
bool onlyAccessesArgPointees() const
Whether this function only (at most) accesses argument memory.
Definition ModRef.h:255
bool onlyReadsMemory() const
Whether this function only (at most) reads memory.
Definition ModRef.h:249
static MemoryEffectsBase writeOnly()
Definition ModRef.h:138
static MemoryEffectsBase inaccessibleOrArgMemOnly(ModRefInfo MR=ModRefInfo::ModRef)
Definition ModRef.h:166
static MemoryEffectsBase none()
Definition ModRef.h:128
bool onlyAccessesInaccessibleOrArgMem() const
Whether this function only (at most) accesses argument and inaccessible memory.
Definition ModRef.h:305
static MemoryEffectsBase unknown()
Definition ModRef.h:123
static LLVM_ABI std::optional< MemoryLocation > getOrNone(const Instruction *Inst)
static SizeOffsetValue unknown()
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
Value * getReturnValue() const
Convenience accessor. Returns null if there is no return value.
LLVM_ABI SCEVUse getSCEVAtScope(const SCEV *S, const Loop *L)
Return a SCEV expression for the specified value at the specified scope in the program.
LLVM_ABI const SCEV * getSCEV(Value *V)
Return a SCEV expression for the full generality of the specified expression.
LLVM_ABI unsigned getSmallConstantMaxTripCount(const Loop *L, SmallVectorImpl< const SCEVPredicate * > *Predicates=nullptr)
Returns the upper bound of the loop trip count as a normal unsigned value.
ConstantRange getUnsignedRange(const SCEV *S)
Determine the unsigned range for a particular SCEV.
A vector that has set insertion semantics.
Definition SetVector.h:57
size_type size() const
Determine the number of elements in the SetVector.
Definition SetVector.h:103
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition SetVector.h:157
bool erase(PtrType Ptr)
Remove pointer from the set.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
Definition SmallSet.h:184
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Used to lazily calculate structure layout information for a target machine, based on the DataLayout s...
Definition DataLayout.h:743
TypeSize getElementOffset(unsigned Idx) const
Definition DataLayout.h:774
TypeSize getSizeInBits() const
Definition DataLayout.h:754
TypeSize getElementOffsetInBits(unsigned Idx) const
Definition DataLayout.h:779
Class to represent struct types.
unsigned getNumElements() const
Random access to the elements.
Type * getElementType(unsigned N) const
LLVM_ABI bool areTypesABICompatible(const Function *Caller, const Function *Callee, ArrayRef< Type * > Types) const
LLVM_ABI unsigned getAssumedAddrSpace(const Value *V) const
LLVM_ABI bool hasVolatileVariant(Instruction *I, unsigned AddrSpace) const
Return true if the given instruction (assumed to be a memory access instruction) has a volatile varia...
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
LLVM_ABI unsigned getIntegerBitWidth() const
bool isPointerTy() const
True if this is an instance of PointerType.
Definition Type.h:277
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
bool isPtrOrPtrVectorTy() const
Return true if this is a pointer type or a vector of pointer types.
Definition Type.h:280
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:252
bool isVoidTy() const
Return true if this is 'void'.
Definition Type.h:141
static UncondBrInst * Create(BasicBlock *Target, InsertPosition InsertBefore=nullptr)
BasicBlock * getSuccessor(unsigned i=0) const
static LLVM_ABI UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
A Use represents the edge between a Value definition and its users.
Definition Use.h:35
User * getUser() const
Returns the User that contains this Use.
Definition Use.h:61
Value * get() const
Definition Use.h:55
const Use & getOperandUse(unsigned i) const
Definition User.h:220
LLVM_ABI bool isDroppable() const
A droppable user is a user for which uses can be dropped without affecting correctness and should be ...
Definition User.cpp:113
LLVM_ABI bool replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
Definition User.cpp:25
Value * getOperand(unsigned i) const
Definition User.h:207
unsigned getNumOperands() const
Definition User.h:229
ValueT lookup(const KeyT &Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
Definition ValueMap.h:167
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:257
static constexpr uint64_t MaximumAlignment
Definition Value.h:801
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition Value.cpp:549
LLVMContext & getContext() const
All values hold a context through their type.
Definition Value.h:260
LLVM_ABI const Value * stripAndAccumulateConstantOffsets(const DataLayout &DL, APInt &Offset, bool AllowNonInbounds, bool AllowInvariantGroup=false, function_ref< bool(Value &Value, APInt &Offset)> ExternalAnalysis=nullptr, bool LookThroughIntToPtr=false) const
Accumulate the constant offset this value has compared to a base pointer.
bool use_empty() const
Definition Value.h:348
static constexpr unsigned MaxAlignmentExponent
The maximum alignment for instructions.
Definition Value.h:800
iterator_range< use_iterator > uses()
Definition Value.h:382
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:315
std::pair< iterator, bool > insert(const ValueT &V)
Definition DenseSet.h:209
constexpr ScalarTy getFixedValue() const
Definition TypeSize.h:201
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
Definition TypeSize.h:169
const ParentTy * getParent() const
Definition ilist_node.h:34
self_iterator getIterator()
Definition ilist_node.h:123
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
Definition ilist_node.h:348
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
A raw_ostream that writes to an std::string.
Changed
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Abstract Attribute helper functions.
Definition Attributor.h:165
LLVM_ABI bool isAssumedReadNone(Attributor &A, const IRPosition &IRP, const AbstractAttribute &QueryingAA, bool &IsKnown)
Return true if IRP is readnone.
LLVM_ABI bool isAssumedReadOnly(Attributor &A, const IRPosition &IRP, const AbstractAttribute &QueryingAA, bool &IsKnown)
Return true if IRP is readonly.
raw_ostream & operator<<(raw_ostream &OS, const RangeTy &R)
Definition Attributor.h:327
LLVM_ABI std::optional< Value * > combineOptionalValuesInAAValueLatice(const std::optional< Value * > &A, const std::optional< Value * > &B, Type *Ty)
Return the combination of A and B such that the result is a possible value of both.
LLVM_ABI bool isValidAtPosition(const ValueAndContext &VAC, InformationCache &InfoCache)
Return true if the value of VAC is a valid at the position of VAC, that is a constant,...
LLVM_ABI bool isAssumedThreadLocalObject(Attributor &A, Value &Obj, const AbstractAttribute &QueryingAA)
Return true if Obj is assumed to be a thread local object.
LLVM_ABI bool isGPUConstantAddressSpace(const Module &M, unsigned AS)
Check if the given address space AS corresponds to a GPU constant address space for the target triple...
LLVM_ABI bool isDynamicallyUnique(Attributor &A, const AbstractAttribute &QueryingAA, const Value &V, bool ForAnalysisOnly=true)
Return true if V is dynamically unique, that is, there are no two "instances" of V at runtime with di...
LLVM_ABI bool getPotentialCopiesOfStoredValue(Attributor &A, StoreInst &SI, SmallSetVector< Value *, 4 > &PotentialCopies, const AbstractAttribute &QueryingAA, bool &UsedAssumedInformation, bool OnlyExact=false)
Collect all potential values of the one stored by SI into PotentialCopies.
LLVM_ABI bool isGPUSharedAddressSpace(const Module &M, unsigned AS)
Check if the given address space AS corresponds to a GPU shared address space for the target triple i...
LLVM_ABI bool isGPULocalAddressSpace(const Module &M, unsigned AS)
Check if the given address space AS corresponds to a GPU local/private address space for the target t...
SmallPtrSet< Instruction *, 4 > InstExclusionSetTy
Definition Attributor.h:166
LLVM_ABI bool isGPU(const Module &M)
Return true iff M target a GPU (and we can use GPU AS reasoning).
ValueScope
Flags to distinguish intra-procedural queries from potentially inter-procedural queries.
Definition Attributor.h:186
@ Intraprocedural
Definition Attributor.h:187
@ Interprocedural
Definition Attributor.h:188
LLVM_ABI bool isValidInScope(const Value &V, const Function *Scope)
Return true if V is a valid value in Scope, that is a constant or an instruction/argument of Scope.
LLVM_ABI bool isPotentiallyReachable(Attributor &A, const Instruction &FromI, const Instruction &ToI, const AbstractAttribute &QueryingAA, const AA::InstExclusionSetTy *ExclusionSet=nullptr, std::function< bool(const Function &F)> GoBackwardsCB=nullptr)
Return true if ToI is potentially reachable from FromI without running into any instruction in Exclus...
LLVM_ABI bool isNoSyncInst(Attributor &A, const Instruction &I, const AbstractAttribute &QueryingAA)
Return true if I is a nosync instruction.
bool hasAssumedIRAttr(Attributor &A, const AbstractAttribute *QueryingAA, const IRPosition &IRP, DepClassTy DepClass, bool &IsKnown, bool IgnoreSubsumingPositions=false, const AAType **AAPtr=nullptr)
Helper to avoid creating an AA for IR Attributes that might already be set.
LLVM_ABI bool getPotentiallyLoadedValues(Attributor &A, LoadInst &LI, SmallSetVector< Value *, 4 > &PotentialValues, SmallSetVector< Instruction *, 4 > &PotentialValueOrigins, const AbstractAttribute &QueryingAA, bool &UsedAssumedInformation, bool OnlyExact=false)
Collect all potential values LI could read into PotentialValues.
LLVM_ABI Value * getWithType(Value &V, Type &Ty)
Try to convert V to type Ty without introducing new instructions.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char Attrs[]
Key for Kernel::Metadata::mAttrs.
@ BasicBlock
Various leaf nodes.
Definition ISDOpcodes.h:83
@ Unsupported
This operation is completely unsupported on the target.
Offsets
Offsets in bytes from the start of the input buffer.
@ SingleThread
Synchronized with respect to signal handlers executing in the same thread.
Definition LLVMContext.h:63
@ Valid
The data is already valid.
initializer< Ty > init(const Ty &Val)
LocationClass< Ty > location(Ty &L)
unsigned combineHashValue(unsigned a, unsigned b)
Simplistic combination of 32-bit hash values into 32-bit hash values.
ElementType
The element type of an SRV or UAV resource.
Definition DXILABI.h:68
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > dyn_extract_or_null(Y &&MD)
Extract a Value from Metadata, if any, allowing null.
Definition Metadata.h:720
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > extract(Y &&MD)
Extract a Value from Metadata.
Definition Metadata.h:679
@ User
could "use" a pointer
DiagnosticInfoOptimizationBase::Argument NV
NodeAddr< UseNode * > Use
Definition RDFGraph.h:385
iterator end() const
Definition BasicBlock.h:89
friend class Instruction
Iterator for Instructions in a `BasicBlock.
Definition BasicBlock.h:73
LLVM_ABI iterator begin() const
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:577
@ Length
Definition DWP.cpp:577
bool operator<(int64_t V1, const APSInt &V2)
Definition APSInt.h:360
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt gcd(const DynamicAPInt &A, const DynamicAPInt &B)
LLVM_ABI KnownFPClass computeKnownFPClass(const Value *V, const APInt &DemandedElts, FPClassTest InterestedClasses, const SimplifyQuery &SQ, unsigned Depth=0)
Determine which floating-point classes are valid for V, and return them in KnownFPClass bit sets.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1755
LLVM_ABI bool isLegalToPromote(const CallBase &CB, Function *Callee, const char **FailureReason=nullptr)
Return true if the given indirect call site can be made to call Callee.
LLVM_ABI Constant * getInitialValueOfAllocation(const Value *V, const TargetLibraryInfo *TLI, Type *Ty)
If this is a call to an allocation function that initializes memory to a fixed value,...
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
Definition STLExtras.h:1685
RelativeUniformCounterPtr Values
Definition InstrProf.h:91
@ Known
Known to have no common set bits.
@ Undef
Value of the register doesn't matter.
auto pred_end(const MachineBasicBlock *BB)
unsigned getPointerAddressSpace(const Type *T)
Definition SPIRVUtils.h:393
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
auto successors(const MachineBasicBlock *BB)
LLVM_ABI bool isRemovableAlloc(const CallBase *V, const TargetLibraryInfo *TLI)
Return true if this is a call to an allocation function that does not have side effects that we are r...
APFloat abs(APFloat X)
Returns the absolute value of the argument.
Definition APFloat.h:1721
@ Load
The value being inserted comes from a load (InsertElement only).
@ Store
The extracted value is stored (ExtractElement only).
LLVM_ABI raw_fd_ostream & outs()
This returns a reference to a raw_fd_ostream for standard output.
LLVM_ABI Value * getAllocAlignment(const CallBase *V, const TargetLibraryInfo *TLI)
Gets the alignment argument for an aligned_alloc-like function, using either built-in knowledge based...
auto dyn_cast_if_present(const Y &Val)
dyn_cast_if_present<X> - Functionally identical to dyn_cast, except that a null (or none in the case ...
Definition Casting.h:732
LLVM_ABI Value * simplifyInstructionWithOperands(Instruction *I, ArrayRef< Value * > NewOps, const SimplifyQuery &Q)
Like simplifyInstruction but the operands of I are replaced with NewOps.
Value * GetPointerBaseWithConstantOffset(Value *Ptr, int64_t &Offset, const DataLayout &DL, bool AllowNonInbounds=true)
Analyze the specified pointer to see if it can be expressed as a base pointer plus a constant offset.
scc_iterator< T > scc_begin(const T &G)
Construct the begin iterator for a deduced graph type T.
LLVM_ABI bool isNoAliasCall(const Value *V)
Return true if this pointer is returned by a noalias function.
MemoryEffectsBase< IRMemLocation > MemoryEffects
Summary of how a function affects memory in the program.
Definition ModRef.h:356
raw_ostream & WriteGraph(raw_ostream &O, const GraphType &G, bool ShortNames=false, const Twine &Title="")
LLVM_ABI bool isSafeToSpeculativelyExecute(const Instruction *I, const Instruction *CtxI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr, const TargetLibraryInfo *TLI=nullptr, bool UseVariableInfo=true, bool IgnoreUBImplyingAttrs=true)
Return true if the instruction does not have any effects besides calculating the result and does not ...
bool isa_and_nonnull(const Y &Val)
Definition Casting.h:676
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
LLVM_ABI ConstantRange getConstantRangeFromMetadata(const MDNode &RangeMD)
Parse out a conservative ConstantRange from !range metadata.
auto map_range(ContainerTy &&C, FuncTy F)
Return a range that applies F to the elements of C.
Definition STLExtras.h:366
const Value * getPointerOperand(const Value *V)
A helper function that returns the pointer operand of a load, store or GEP instruction.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
LLVM_ABI Value * simplifyInstruction(Instruction *I, const SimplifyQuery &Q)
See if we can compute a simplified version of this instruction.
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:753
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:1762
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:326
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition MathExtras.h:280
PotentialValuesState< std::pair< AA::ValueAndContext, AA::ValueScope > > PotentialLLVMValuesState
void sort(IteratorTy Start, IteratorTy End)
Definition STLExtras.h:1652
LLVM_ABI bool NullPointerIsDefined(const Function *F, unsigned AS=0)
Check whether null pointer dereferencing is considered undefined behavior for a given function or an ...
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
bool isPointerTy(const Type *T)
Definition SPIRVUtils.h:381
IRBuilder(LLVMContext &, FolderTy, InserterTy) -> IRBuilder< FolderTy, InserterTy >
LLVM_ABI bool wouldInstructionBeTriviallyDead(const Instruction *I, const TargetLibraryInfo *TLI=nullptr)
Return true if the result produced by the instruction would have no side effects if it was not used.
Definition Local.cpp:413
bool set_union(S1Ty &S1, const S2Ty &S2)
set_union(A, B) - Compute A := A u B, return whether A changed.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
LLVM_ABI CallBase & promoteCall(CallBase &CB, Function *Callee, CastInst **RetBitCast=nullptr)
Promote the given indirect call site to unconditionally call Callee.
LLVM_ABI const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=MaxLookupSearchDepth, bool MustPreserveProvenance=false)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
LLVM_ABI bool hasAssumption(const Function &F, const KnownAssumptionString &AssumptionStr)
Return true if F has the assumption AssumptionStr attached.
LLVM_ABI RetainedKnowledge getKnowledgeFromUse(const Use *U, ArrayRef< Attribute::AttrKind > AttrKinds)
Return a valid Knowledge associated to the Use U if its Attribute kind is in AttrKinds.
@ Success
The lock was released successfully.
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
LLVM_ABI bool isKnownNonZero(const Value *V, const SimplifyQuery &Q, unsigned Depth=0)
Return true if the given value is known to be non-zero when defined.
AtomicOrdering
Atomic ordering for LLVM's memory model.
@ Other
Any other memory.
Definition ModRef.h:68
PotentialValuesState< APInt > PotentialConstantIntValuesState
TargetTransformInfo TTI
std::string join(IteratorT Begin, IteratorT End, StringRef Separator)
Joins the strings in the range [Begin, End), adding Separator between the elements.
InterleavedRange< Range > interleaved_array(const Range &R, StringRef Separator=", ")
Output range R as an array of interleaved elements.
ChangeStatus clampStateAndIndicateChange< DerefState >(DerefState &S, const DerefState &R)
void RemapInstruction(Instruction *I, ValueToValueMapTy &VM, RemapFlags Flags=RF_None, ValueMapTypeRemapper *TypeMapper=nullptr, ValueMaterializer *Materializer=nullptr, const MetadataPredicate *IdentityMD=nullptr)
Convert the instruction operands from referencing the current values into those specified by VM.
LLVM_ABI bool isIntrinsicReturningPointerAliasingArgumentWithoutCapturing(const CallBase *Call, bool MustPreserveOffset, bool MustPreserveProvenance=false)
launder.invariant.group and similar intrinsics return a pointer that aliases their argument,...
DWARFExpression::Operation Op
LLVM_ABI bool isGuaranteedNotToBeUndefOrPoison(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Return true if this function can prove that V does not have undef bits and is never poison.
ArrayRef(const T &OneElt) -> ArrayRef< T >
LLVM_ABI Value * getFreedOperand(const CallBase *CB, const TargetLibraryInfo *TLI)
If this if a call to a free function, return the freed operand.
ChangeStatus clampStateAndIndicateChange(StateType &S, const StateType &R)
Helper function to clamp a state S of type StateType with the information in R and indicate/return if...
constexpr unsigned BitWidth
ValueMap< const Value *, WeakTrackingVH > ValueToValueMapTy
auto pred_begin(const MachineBasicBlock *BB)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
iterator_range< pointer_iterator< WrappedIteratorT > > make_pointer_range(RangeT &&Range)
Definition iterator.h:368
ChangeStatus
{
Definition Attributor.h:477
LLVM_ABI std::optional< APInt > getAllocSize(const CallBase *CB, const TargetLibraryInfo *TLI, function_ref< const Value *(const Value *)> Mapper=[](const Value *V) { return V;})
Return the size of the requested allocation.
LLVM_ABI DenseSet< StringRef > getAssumptions(const Function &F)
Return the set of all assumptions for the function F.
Align assumeAligned(uint64_t Value)
Treats the value 0 as a 1, so Align is always at least 1.
Definition Alignment.h:105
LLVM_ABI Instruction * SplitBlockAndInsertIfThen(Value *Cond, BasicBlock::iterator SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, BasicBlock *ThenBlock=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...
@ OPTIONAL
The target may be valid if the source is not.
Definition Attributor.h:489
@ NONE
Do not track a dependence between source and target.
Definition Attributor.h:490
@ REQUIRED
The target cannot be valid if the source is not.
Definition Attributor.h:488
LLVM_ABI UseCaptureInfo DetermineUseCaptureKind(const Use &U, const Value *Base)
Determine what kind of capture behaviour U may exhibit.
LLVM_ABI Value * simplifyCmpInst(CmpPredicate Predicate, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for a CmpInst, fold the result or return null.
LLVM_ABI bool mayContainIrreducibleControl(const Function &F, const LoopInfo *LI)
BumpPtrAllocatorImpl<> BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
Definition Allocator.h:391
T bit_floor(T Value)
Returns the largest integral power of two no greater than Value if Value is nonzero.
Definition bit.h:347
bool capturesNothing(CaptureComponents CC)
Definition ModRef.h:375
LLVM_ABI bool isIdentifiedObject(const Value *V)
Return true if this pointer refers to a distinct and identifiable object.
bool capturesAnyProvenance(CaptureComponents CC)
Definition ModRef.h:400
constexpr StringRef AssumptionAttrKey
The key we use for assumption attributes.
Definition Assumptions.h:29
constexpr bool isCallableCC(CallingConv::ID CC)
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:880
A type to track pointer/struct usage and accesses for AAPointerInfo.
bool forallInterferingAccesses(AA::RangeTy Range, F CB) const
See AAPointerInfo::forallInterferingAccesses.
AAPointerInfo::const_bin_iterator end() const
ChangeStatus addAccess(Attributor &A, const AAPointerInfo::RangeList &Ranges, Instruction &I, std::optional< Value * > Content, AAPointerInfo::AccessKind Kind, Type *Ty, Instruction *RemoteI=nullptr)
Add a new Access to the state at offset Offset and with size Size.
DenseMap< const Instruction *, SmallVector< unsigned > > RemoteIMap
AAPointerInfo::const_bin_iterator begin() const
AAPointerInfo::OffsetInfo ReturnedOffsets
Flag to determine if the underlying pointer is reaching a return statement in the associated function...
State(State &&SIS)=default
const AAPointerInfo::Access & getAccess(unsigned Index) const
SmallVector< AAPointerInfo::Access > AccessList
bool isAtFixpoint() const override
See AbstractState::isAtFixpoint().
bool forallInterferingAccesses(Instruction &I, F CB, AA::RangeTy &Range) const
See AAPointerInfo::forallInterferingAccesses.
static State getWorstState(const State &SIS)
Return the worst possible representable state.
AAPointerInfo::OffsetBinsTy OffsetBins
ChangeStatus indicateOptimisticFixpoint() override
See AbstractState::indicateOptimisticFixpoint().
ChangeStatus indicatePessimisticFixpoint() override
See AbstractState::indicatePessimisticFixpoint().
static State getBestState(const State &SIS)
Return the best possible representable state.
bool isValidState() const override
See AbstractState::isValidState().
----------------—AAIntraFnReachability Attribute-----------------------—
ReachabilityQueryInfo(const ReachabilityQueryInfo &RQI)
unsigned Hash
Precomputed hash for this RQI.
const Instruction * From
Start here,.
Reachable Result
and remember if it worked:
ReachabilityQueryInfo(const Instruction *From, const ToTy *To)
ReachabilityQueryInfo(Attributor &A, const Instruction &From, const ToTy &To, const AA::InstExclusionSetTy *ES, bool MakeUnique)
Constructor replacement to ensure unique and stable sets are used for the cache.
const ToTy * To
reach this place,
const AA::InstExclusionSetTy * ExclusionSet
without going through any of these instructions,
An abstract interface for address space information.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for all align attributes.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
Align getKnownAlign() const
Return known alignment.
static LLVM_ABI const char ID
An abstract attribute for getting assumption information.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract state for querying live call edges.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract Attribute for specializing "dynamic" components of denormal_fpenv to a known denormal mod...
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for all dereferenceable attribute.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for llvm::GlobalValue information interference.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for indirect call information interference.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface to track if a value leaves it's defining function instance.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract Attribute for computing reachability between functions.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
bool canReach(Attributor &A, const Function &Fn) const
If the function represented by this possition can reach Fn.
virtual bool instructionCanReach(Attributor &A, const Instruction &Inst, const Function &Fn, const AA::InstExclusionSetTy *ExclusionSet=nullptr) const =0
Can Inst reach Fn.
An abstract interface to determine reachability of point A to B.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for identifying pointers from which loads can be marked invariant.
static LLVM_ABI const char ID
Unique ID (due to the unique address).
An abstract interface for liveness abstract attribute.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for memory access kind related attributes (readnone/readonly/writeonly).
bool isAssumedReadOnly() const
Return true if we assume that the underlying value is not accessed (=written) in its respective scope...
bool isKnownReadNone() const
Return true if we know that the underlying value is not read or accessed in its respective scope.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
bool isAssumedReadNone() const
Return true if we assume that the underlying value is not read or accessed in its respective scope.
An abstract interface for all memory location attributes (readnone/argmemonly/inaccessiblememonly/ina...
static LLVM_ABI std::string getMemoryLocationsAsStr(MemoryLocationsKind MLK)
Return the locations encoded by MLK as a readable string.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
StateType::base_t MemoryLocationsKind
An abstract interface for all nonnull attributes.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for potential address space information.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for all noalias attributes.
static LLVM_ABI bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
See IRAttribute::isImpliedByIR.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for all nocapture attributes.
@ NO_CAPTURE_MAYBE_RETURNED
If we do not capture the value in memory or through integers we can only communicate it back as a der...
@ NO_CAPTURE
If we do not capture the value in memory, through integers, or as a derived pointer we know it is not...
static LLVM_ABI const char ID
Unique ID (due to the unique address)
bool isAssumedNoCaptureMaybeReturned() const
Return true if we assume that the underlying value is not captured in its respective scope but we all...
static LLVM_ABI bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
See IRAttribute::isImpliedByIR.
static LLVM_ABI void determineFunctionCaptureCapabilities(const IRPosition &IRP, const Function &F, BitIntegerState &State)
Update State according to the capture capabilities of F for position IRP.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An AbstractAttribute for nofree.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract attribute for norecurse.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An AbstractAttribute for noreturn.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI bool isAlignedBarrier(const CallBase &CB, bool ExecutedAligned)
Helper function to determine if CB is an aligned (GPU) barrier.
static LLVM_ABI bool isNonRelaxedAtomic(const Instruction *I)
Helper function used to determine whether an instruction is non-relaxed atomic.
An abstract interface for all noundef attributes.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
See IRAttribute::isImpliedByIR.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract Attribute for determining the necessity of the convergent attribute.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for all nonnull attributes.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
See AbstractAttribute::isImpliedByIR(...).
An access description.
A helper containing a list of offsets computed for a Use.
A container for a list of ranges.
static void set_difference(const RangeList &L, const RangeList &R, RangeList &D)
Copy ranges from L that are not in R, into D.
An abstract interface for struct information.
virtual bool reachesReturn() const =0
OffsetBinsTy::const_iterator const_bin_iterator
virtual const_bin_iterator begin() const =0
DenseMap< AA::RangeTy, SmallSet< unsigned, 4 > > OffsetBinsTy
static LLVM_ABI const char ID
Unique ID (due to the unique address)
virtual int64_t numOffsetBins() const =0
An abstract interface for potential values analysis.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
friend struct Attributor
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI Value * getSingleValue(Attributor &A, const AbstractAttribute &AA, const IRPosition &IRP, SmallVectorImpl< AA::ValueAndContext > &Values)
Extract the single value in Values if any.
An abstract interface for privatizability.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract attribute for undefined behavior.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract attribute for getting all assumption underlying objects.
virtual bool forallUnderlyingObjects(function_ref< bool(Value &)> Pred, AA::ValueScope Scope=AA::Interprocedural) const =0
Check Pred on all underlying objects in Scope collected so far.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for range value analysis.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for value simplify abstract attribute.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract attribute for willreturn.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
Helper to represent an access offset and size, with logic to deal with uncertainty and check for over...
Definition Attributor.h:245
static constexpr int64_t Unknown
Definition Attributor.h:324
static RangeTy getUnknown()
Definition Attributor.h:251
Value * getValue() const
Definition Attributor.h:198
const Instruction * getCtxI() const
Definition Attributor.h:199
Base struct for all "concrete attribute" deductions.
void print(raw_ostream &OS) const
Helper functions, for debug purposes only.
virtual StateType & getState()=0
Return the internal abstract state for inspection.
AbstractState StateType
An interface to query the internal state of an abstract attribute.
virtual bool isAtFixpoint() const =0
Return if this abstract state is fixed, thus does not need to be updated if information changes as it...
virtual bool isValidState() const =0
Return if this abstract state is in a valid state.
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
Definition Alignment.h:82
static constexpr Align fromLog2(unsigned Log2Value)
Returns an alignment of 1 << Log2Value bytes.
Definition Alignment.h:73
std::function< void( const ArgumentReplacementInfo &, Function &, Function::arg_iterator)> CalleeRepairCBTy
Callee repair callback type.
const Argument & getReplacedArg() const
std::function< void(const ArgumentReplacementInfo &, AbstractCallSite, SmallVectorImpl< Value * > &)> ACSRepairCBTy
Abstract call site (ACS) repair callback type.
The fixpoint analysis framework that orchestrates the attribute deduction.
std::function< std::optional< Value * >( const IRPosition &, const AbstractAttribute *, bool &)> SimplifictionCallbackTy
Register CB as a simplification callback.
Specialization of the integer state for a bit-wise encoding.
BitIntegerState & addKnownBits(base_t Bits)
Add the bits in BitsEncoding to the "known bits".
Simple wrapper for a single bit (boolean) state.
static constexpr DenormalFPEnv getDefault()
static unsigned getHashValue(const Access &A)
static bool isEqual(const Access &LHS, const Access &RHS)
static bool isEqual(const AA::RangeTy &A, const AA::RangeTy B)
static unsigned getHashValue(const AA::RangeTy &Range)
DenseMapInfo< std::pair< const Instruction *, const ToTy * > > PairDMI
static bool isEqual(const ReachabilityQueryInfo< ToTy > *LHS, const ReachabilityQueryInfo< ToTy > *RHS)
DenseMapInfo< const AA::InstExclusionSetTy * > InstSetDMI
static unsigned getHashValue(const ReachabilityQueryInfo< ToTy > *RQI)
An information struct used to provide DenseMap with the various necessary components for a given valu...
State for dereferenceable attribute.
IncIntegerState DerefBytesState
State representing for dereferenceable bytes.
ChangeStatus manifest(Attributor &A) override
See AbstractAttribute::manifest(...).
Helper to describe and deal with positions in the LLVM-IR.
Definition Attributor.h:573
Function * getAssociatedFunction() const
Return the associated function, if any.
Definition Attributor.h:704
static const IRPosition callsite_returned(const CallBase &CB)
Create a position describing the returned value of CB.
Definition Attributor.h:641
static const IRPosition returned(const Function &F, const CallBaseContext *CBContext=nullptr)
Create a position describing the returned value of F.
Definition Attributor.h:623
LLVM_ABI Argument * getAssociatedArgument() const
Return the associated argument, if any.
static const IRPosition value(const Value &V, const CallBaseContext *CBContext=nullptr)
Create a position describing the value of V.
Definition Attributor.h:597
CallBase CallBaseContext
Definition Attributor.h:576
int getCalleeArgNo() const
Return the callee argument number of the associated value if it is an argument or call site argument,...
Definition Attributor.h:791
static const IRPosition inst(const Instruction &I, const CallBaseContext *CBContext=nullptr)
Create a position describing the instruction I.
Definition Attributor.h:609
static const IRPosition callsite_argument(const CallBase &CB, unsigned ArgNo)
Create a position describing the argument of CB at position ArgNo.
Definition Attributor.h:646
@ IRP_ARGUMENT
An attribute for a function argument.
Definition Attributor.h:587
@ IRP_RETURNED
An attribute for the function return value.
Definition Attributor.h:583
@ IRP_CALL_SITE
An attribute for a call site (function scope).
Definition Attributor.h:586
@ IRP_CALL_SITE_RETURNED
An attribute for a call site return value.
Definition Attributor.h:584
@ IRP_FUNCTION
An attribute for a function (scope).
Definition Attributor.h:585
@ IRP_CALL_SITE_ARGUMENT
An attribute for a call site argument.
Definition Attributor.h:588
@ IRP_INVALID
An invalid position.
Definition Attributor.h:580
Instruction * getCtxI() const
Return the context instruction, if any.
Definition Attributor.h:757
static const IRPosition argument(const Argument &Arg, const CallBaseContext *CBContext=nullptr)
Create a position describing the argument Arg.
Definition Attributor.h:630
Type * getAssociatedType() const
Return the type this abstract attribute is associated with.
Definition Attributor.h:780
static const IRPosition function(const Function &F, const CallBaseContext *CBContext=nullptr)
Create a position describing the function scope of F.
Definition Attributor.h:616
const CallBaseContext * getCallBaseContext() const
Get the call base context from the position.
Definition Attributor.h:897
Value & getAssociatedValue() const
Return the value this abstract attribute is associated with.
Definition Attributor.h:771
Value & getAnchorValue() const
Return the value this abstract attribute is anchored with.
Definition Attributor.h:690
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:800
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:669
Kind getPositionKind() const
Return the associated position kind.
Definition Attributor.h:847
bool isArgumentPosition() const
Return true if the position is an argument or call site argument.
Definition Attributor.h:879
static const IRPosition callsite_function(const CallBase &CB)
Create a position describing the function scope of CB.
Definition Attributor.h:636
Function * getAnchorScope() const
Return the Function surrounding the anchor value.
Definition Attributor.h:745
Data structure to hold cached (LLVM-IR) information.
TargetLibraryInfo * getTargetLibraryInfoForFunction(const Function &F)
Return TargetLibraryInfo for function F.
bool isOnlyUsedByAssume(const Instruction &I) const
AP::Result * getAnalysisResultForFunction(const Function &F, bool CachedOnly=false)
Return the analysis result from a pass AP for function F.
ConstantRange getKnown() const
Return the known state encoding.
ConstantRange getAssumed() const
Return the assumed state encoding.
base_t getAssumed() const
Return the assumed state encoding.
Helper that allows to insert a new assumption string in the known assumption set by creating a (stati...
Definition Assumptions.h:37
FPClassTest getKnownFPClasses() const
Floating-point classes the value could be one of.
A "must be executed context" for a given program point PP is the set of instructions,...
iterator & end()
Return an universal end iterator.
bool findInContextOf(const Instruction *I, const Instruction *PP)
Helper to look for I in the context of PP.
iterator & begin(const Instruction *PP)
Return an iterator to explore the context around PP.
bool checkForAllContext(const Instruction *PP, function_ref< bool(const Instruction *)> Pred)
}
Helper to tie a abstract state implementation to an abstract attribute.
StateType & getState() override
See AbstractAttribute::getState(...).
CaptureComponents ResultCC
Components captured by the return value of the user of this Use.
LLVM_ABI bool unionAssumed(std::optional< Value * > Other)
Merge Other into the currently assumed simplified value.
std::optional< Value * > SimplifiedAssociatedValue
An assumed simplified value.
Type * Ty
The type of the original value.