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(Offsets.begin(), Offsets.end());
1470
1471 for (int i = 0, e = VT->getElementCount().getFixedValue(); i != e; ++i) {
1472 Value *ElementContent = ConstantExpr::getExtractElement(
1473 ConstContent, ConstantInt::get(Int32Ty, i));
1474
1475 // Add the element access.
1476 Changed = Changed | addAccess(A, {ElementOffsets, ElementSize}, I,
1477 ElementContent, Kind, ElementType);
1478
1479 // Advance the offsets for the next element.
1480 for (auto &ElementOffset : ElementOffsets)
1481 ElementOffset += ElementSize;
1482 }
1483 }
1484 return true;
1485 };
1486
1487 /// See AbstractAttribute::updateImpl(...).
1488 ChangeStatus updateImpl(Attributor &A) override;
1489
1490 /// If the indices to \p GEP can be traced to constants, incorporate all
1491 /// of these into \p UsrOI.
1492 ///
1493 /// \return true iff \p UsrOI is updated.
1494 bool collectConstantsForGEP(Attributor &A, const DataLayout &DL,
1495 OffsetInfo &UsrOI, const OffsetInfo &PtrOI,
1496 const GEPOperator *GEP);
1497
1498 /// See AbstractAttribute::trackStatistics()
1499 void trackStatistics() const override {
1500 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
1501 }
1502};
1503
1504bool AAPointerInfoFloating::collectConstantsForGEP(Attributor &A,
1505 const DataLayout &DL,
1506 OffsetInfo &UsrOI,
1507 const OffsetInfo &PtrOI,
1508 const GEPOperator *GEP) {
1509 unsigned BitWidth = DL.getIndexTypeSizeInBits(GEP->getType());
1510 SmallMapVector<Value *, APInt, 4> VariableOffsets;
1511 APInt ConstantOffset(BitWidth, 0);
1512
1513 assert(!UsrOI.isUnknown() && !PtrOI.isUnknown() &&
1514 "Don't look for constant values if the offset has already been "
1515 "determined to be unknown.");
1516
1517 if (!GEP->collectOffset(DL, BitWidth, VariableOffsets, ConstantOffset)) {
1518 UsrOI.setUnknown();
1519 return true;
1520 }
1521
1522 LLVM_DEBUG(dbgs() << "[AAPointerInfo] GEP offset is "
1523 << (VariableOffsets.empty() ? "" : "not") << " constant "
1524 << *GEP << "\n");
1525
1526 auto Union = PtrOI;
1527 Union.addToAll(ConstantOffset.getSExtValue());
1528
1529 // Each VI in VariableOffsets has a set of potential constant values. Every
1530 // combination of elements, picked one each from these sets, is separately
1531 // added to the original set of offsets, thus resulting in more offsets.
1532 for (const auto &VI : VariableOffsets) {
1533 auto *PotentialConstantsAA = A.getAAFor<AAPotentialConstantValues>(
1534 *this, IRPosition::value(*VI.first), DepClassTy::OPTIONAL);
1535 if (!PotentialConstantsAA || !PotentialConstantsAA->isValidState()) {
1536 UsrOI.setUnknown();
1537 return true;
1538 }
1539
1540 // UndefValue is treated as a zero, which leaves Union as is.
1541 if (PotentialConstantsAA->undefIsContained())
1542 continue;
1543
1544 // We need at least one constant in every set to compute an actual offset.
1545 // Otherwise, we end up pessimizing AAPointerInfo by respecting offsets that
1546 // don't actually exist. In other words, the absence of constant values
1547 // implies that the operation can be assumed dead for now.
1548 auto &AssumedSet = PotentialConstantsAA->getAssumedSet();
1549 if (AssumedSet.empty())
1550 return false;
1551
1552 OffsetInfo Product;
1553 for (const auto &ConstOffset : AssumedSet) {
1554 auto CopyPerOffset = Union;
1555 CopyPerOffset.addToAll(ConstOffset.getSExtValue() *
1556 VI.second.getZExtValue());
1557 Product.merge(CopyPerOffset);
1558 }
1559 Union = Product;
1560 }
1561
1562 UsrOI = std::move(Union);
1563 return true;
1564}
1565
1566ChangeStatus AAPointerInfoFloating::updateImpl(Attributor &A) {
1567 using namespace AA::PointerInfo;
1569 const DataLayout &DL = A.getDataLayout();
1570 Value &AssociatedValue = getAssociatedValue();
1571
1572 DenseMap<Value *, OffsetInfo> OffsetInfoMap;
1573 OffsetInfoMap[&AssociatedValue].insert(0);
1574
1575 auto HandlePassthroughUser = [&](Value *Usr, Value *CurPtr, bool &Follow) {
1576 // One does not simply walk into a map and assign a reference to a possibly
1577 // new location. That can cause an invalidation before the assignment
1578 // happens, like so:
1579 //
1580 // OffsetInfoMap[Usr] = OffsetInfoMap[CurPtr]; /* bad idea! */
1581 //
1582 // The RHS is a reference that may be invalidated by an insertion caused by
1583 // the LHS. So we ensure that the side-effect of the LHS happens first.
1584
1585 assert(OffsetInfoMap.contains(CurPtr) &&
1586 "CurPtr does not exist in the map!");
1587
1588 auto &UsrOI = OffsetInfoMap[Usr];
1589 auto &PtrOI = OffsetInfoMap[CurPtr];
1590 assert(!PtrOI.isUnassigned() &&
1591 "Cannot pass through if the input Ptr was not visited!");
1592 UsrOI.merge(PtrOI);
1593 Follow = true;
1594 return true;
1595 };
1596
1597 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
1598 Value *CurPtr = U.get();
1599 User *Usr = U.getUser();
1600 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Analyze " << *CurPtr << " in " << *Usr
1601 << "\n");
1602 assert(OffsetInfoMap.count(CurPtr) &&
1603 "The current pointer offset should have been seeded!");
1604 assert(!OffsetInfoMap[CurPtr].isUnassigned() &&
1605 "Current pointer should be assigned");
1606
1607 // Only address space casts are followed; other casts of a pointer (e.g.,
1608 // ptrtoint, ptrtoaddr, or a bitcast to a byte type) do not produce a
1609 // pointer that can be tracked.
1611 return HandlePassthroughUser(Usr, CurPtr, Follow);
1612
1613 if (auto *GEP = dyn_cast<GEPOperator>(Usr)) {
1614 // Note the order here, the Usr access might change the map, CurPtr is
1615 // already in it though.
1616 auto &UsrOI = OffsetInfoMap[Usr];
1617 auto &PtrOI = OffsetInfoMap[CurPtr];
1618
1619 if (UsrOI.isUnknown())
1620 return true;
1621
1622 if (PtrOI.isUnknown()) {
1623 Follow = true;
1624 UsrOI.setUnknown();
1625 return true;
1626 }
1627
1628 Follow = collectConstantsForGEP(A, DL, UsrOI, PtrOI, GEP);
1629 return true;
1630 }
1631 if (isa<SelectInst>(Usr))
1632 return HandlePassthroughUser(Usr, CurPtr, Follow);
1633 // Returns are allowed if they are in the associated functions. Users can
1634 // then check the call site return. Returns from other functions can't be
1635 // tracked and are cause for invalidation.
1636 if (auto *RI = dyn_cast<ReturnInst>(Usr)) {
1637 if (RI->getFunction() == getAssociatedFunction()) {
1638 auto &PtrOI = OffsetInfoMap[CurPtr];
1639 Changed |= setReachesReturn(PtrOI);
1640 return true;
1641 }
1642 return false;
1643 }
1644
1645 // For PHIs we need to take care of the recurrence explicitly as the value
1646 // might change while we iterate through a loop. For now, we give up if
1647 // the PHI is not invariant.
1648 if (auto *PHI = dyn_cast<PHINode>(Usr)) {
1649 // Note the order here, the Usr access might change the map, CurPtr is
1650 // already in it though.
1651 auto [PhiIt, IsFirstPHIUser] = OffsetInfoMap.try_emplace(PHI);
1652 auto &UsrOI = PhiIt->second;
1653 auto &PtrOI = OffsetInfoMap[CurPtr];
1654
1655 // Check if the PHI operand has already an unknown offset as we can't
1656 // improve on that anymore.
1657 if (PtrOI.isUnknown()) {
1658 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI operand offset unknown "
1659 << *CurPtr << " in " << *PHI << "\n");
1660 Follow = !UsrOI.isUnknown();
1661 UsrOI.setUnknown();
1662 return true;
1663 }
1664
1665 // Check if the PHI is invariant (so far).
1666 if (UsrOI == PtrOI) {
1667 assert(!PtrOI.isUnassigned() &&
1668 "Cannot assign if the current Ptr was not visited!");
1669 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI is invariant (so far)");
1670 return true;
1671 }
1672
1673 // Check if the PHI operand can be traced back to AssociatedValue.
1674 APInt Offset(
1675 DL.getIndexSizeInBits(CurPtr->getType()->getPointerAddressSpace()),
1676 0);
1677 Value *CurPtrBase = CurPtr->stripAndAccumulateConstantOffsets(
1678 DL, Offset, /* AllowNonInbounds */ true);
1679 auto It = OffsetInfoMap.find(CurPtrBase);
1680 if (It == OffsetInfoMap.end()) {
1681 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI operand is too complex "
1682 << *CurPtr << " in " << *PHI
1683 << " (base: " << *CurPtrBase << ")\n");
1684 UsrOI.setUnknown();
1685 Follow = true;
1686 return true;
1687 }
1688
1689 // Check if the PHI operand is not dependent on the PHI itself. Every
1690 // recurrence is a cyclic net of PHIs in the data flow, and has an
1691 // equivalent Cycle in the control flow. One of those PHIs must be in the
1692 // header of that control flow Cycle. This is independent of the choice of
1693 // Cycles reported by CycleInfo. It is sufficient to check the PHIs in
1694 // every Cycle header; if such a node is marked unknown, this will
1695 // eventually propagate through the whole net of PHIs in the recurrence.
1696 const auto *CI =
1697 A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>(
1698 *PHI->getFunction());
1699 if (mayBeInCycle(CI, cast<Instruction>(Usr), /* HeaderOnly */ true)) {
1700 auto BaseOI = It->getSecond();
1701 BaseOI.addToAll(Offset.getZExtValue());
1702 if (IsFirstPHIUser || BaseOI == UsrOI) {
1703 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI is invariant " << *CurPtr
1704 << " in " << *Usr << "\n");
1705 return HandlePassthroughUser(Usr, CurPtr, Follow);
1706 }
1707
1708 LLVM_DEBUG(
1709 dbgs() << "[AAPointerInfo] PHI operand pointer offset mismatch "
1710 << *CurPtr << " in " << *PHI << "\n");
1711 UsrOI.setUnknown();
1712 Follow = true;
1713 return true;
1714 }
1715
1716 UsrOI.merge(PtrOI);
1717 Follow = true;
1718 return true;
1719 }
1720
1721 if (auto *LoadI = dyn_cast<LoadInst>(Usr)) {
1722 // If the access is to a pointer that may or may not be the associated
1723 // value, e.g. due to a PHI, we cannot assume it will be read.
1724 AccessKind AK = AccessKind::AK_R;
1725 if (getUnderlyingObject(CurPtr) == &AssociatedValue)
1726 AK = AccessKind(AK | AccessKind::AK_MUST);
1727 else
1728 AK = AccessKind(AK | AccessKind::AK_MAY);
1729 if (!handleAccess(A, *LoadI, /* Content */ nullptr, AK,
1730 OffsetInfoMap[CurPtr].Offsets, Changed,
1731 *LoadI->getType()))
1732 return false;
1733
1734 auto IsAssumption = [](Instruction &I) {
1735 if (auto *II = dyn_cast<IntrinsicInst>(&I))
1736 return II->isAssumeLikeIntrinsic();
1737 return false;
1738 };
1739
1740 auto IsImpactedInRange = [&](Instruction *FromI, Instruction *ToI) {
1741 // Check if the assumption and the load are executed together without
1742 // memory modification.
1743 do {
1744 if (FromI->mayWriteToMemory() && !IsAssumption(*FromI))
1745 return true;
1746 FromI = FromI->getNextNode();
1747 } while (FromI && FromI != ToI);
1748 return false;
1749 };
1750
1751 BasicBlock *BB = LoadI->getParent();
1752 auto IsValidAssume = [&](IntrinsicInst &IntrI) {
1753 if (IntrI.getIntrinsicID() != Intrinsic::assume)
1754 return false;
1755 BasicBlock *IntrBB = IntrI.getParent();
1756 if (IntrI.getParent() == BB) {
1757 if (IsImpactedInRange(LoadI->getNextNode(), &IntrI))
1758 return false;
1759 } else {
1760 auto PredIt = pred_begin(IntrBB);
1761 if (PredIt == pred_end(IntrBB))
1762 return false;
1763 if ((*PredIt) != BB)
1764 return false;
1765 if (++PredIt != pred_end(IntrBB))
1766 return false;
1767 for (auto *SuccBB : successors(BB)) {
1768 if (SuccBB == IntrBB)
1769 continue;
1770 if (isa<UnreachableInst>(SuccBB->getTerminator()))
1771 continue;
1772 return false;
1773 }
1774 if (IsImpactedInRange(LoadI->getNextNode(), BB->getTerminator()))
1775 return false;
1776 if (IsImpactedInRange(&IntrBB->front(), &IntrI))
1777 return false;
1778 }
1779 return true;
1780 };
1781
1782 std::pair<Value *, IntrinsicInst *> Assumption;
1783 for (const Use &LoadU : LoadI->uses()) {
1784 if (auto *CmpI = dyn_cast<CmpInst>(LoadU.getUser())) {
1785 if (!CmpI->isEquality() || !CmpI->isTrueWhenEqual())
1786 continue;
1787 for (const Use &CmpU : CmpI->uses()) {
1788 if (auto *IntrI = dyn_cast<IntrinsicInst>(CmpU.getUser())) {
1789 if (!IsValidAssume(*IntrI))
1790 continue;
1791 int Idx = CmpI->getOperandUse(0) == LoadU;
1792 Assumption = {CmpI->getOperand(Idx), IntrI};
1793 break;
1794 }
1795 }
1796 }
1797 if (Assumption.first)
1798 break;
1799 }
1800
1801 // Check if we found an assumption associated with this load.
1802 if (!Assumption.first || !Assumption.second)
1803 return true;
1804
1805 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Assumption found "
1806 << *Assumption.second << ": " << *LoadI
1807 << " == " << *Assumption.first << "\n");
1808 bool UsedAssumedInformation = false;
1809 std::optional<Value *> Content = nullptr;
1810 if (Assumption.first)
1811 Content =
1812 A.getAssumedSimplified(*Assumption.first, *this,
1813 UsedAssumedInformation, AA::Interprocedural);
1814 return handleAccess(
1815 A, *Assumption.second, Content, AccessKind::AK_ASSUMPTION,
1816 OffsetInfoMap[CurPtr].Offsets, Changed, *LoadI->getType());
1817 }
1818
1819 auto HandleStoreLike = [&](Instruction &I, Value *ValueOp, Type &ValueTy,
1820 ArrayRef<Value *> OtherOps, AccessKind AK) {
1821 for (auto *OtherOp : OtherOps) {
1822 if (OtherOp == CurPtr) {
1823 LLVM_DEBUG(
1824 dbgs()
1825 << "[AAPointerInfo] Escaping use in store like instruction " << I
1826 << "\n");
1827 return false;
1828 }
1829 }
1830
1831 // If the access is to a pointer that may or may not be the associated
1832 // value, e.g. due to a PHI, we cannot assume it will be written.
1833 if (getUnderlyingObject(CurPtr) == &AssociatedValue)
1834 AK = AccessKind(AK | AccessKind::AK_MUST);
1835 else
1836 AK = AccessKind(AK | AccessKind::AK_MAY);
1837 bool UsedAssumedInformation = false;
1838 std::optional<Value *> Content = nullptr;
1839 if (ValueOp)
1840 Content = A.getAssumedSimplified(
1841 *ValueOp, *this, UsedAssumedInformation, AA::Interprocedural);
1842 return handleAccess(A, I, Content, AK, OffsetInfoMap[CurPtr].Offsets,
1843 Changed, ValueTy);
1844 };
1845
1846 if (auto *StoreI = dyn_cast<StoreInst>(Usr))
1847 return HandleStoreLike(*StoreI, StoreI->getValueOperand(),
1848 *StoreI->getValueOperand()->getType(),
1849 {StoreI->getValueOperand()}, AccessKind::AK_W);
1850 if (auto *RMWI = dyn_cast<AtomicRMWInst>(Usr))
1851 return HandleStoreLike(*RMWI, nullptr, *RMWI->getValOperand()->getType(),
1852 {RMWI->getValOperand()}, AccessKind::AK_RW);
1853 if (auto *CXI = dyn_cast<AtomicCmpXchgInst>(Usr))
1854 return HandleStoreLike(
1855 *CXI, nullptr, *CXI->getNewValOperand()->getType(),
1856 {CXI->getCompareOperand(), CXI->getNewValOperand()},
1857 AccessKind::AK_RW);
1858
1859 if (auto *CB = dyn_cast<CallBase>(Usr)) {
1860 if (CB->isLifetimeStartOrEnd())
1861 return true;
1862 const auto *TLI =
1863 A.getInfoCache().getTargetLibraryInfoForFunction(*CB->getFunction());
1864 if (getFreedOperand(CB, TLI) == U)
1865 return true;
1866 if (CB->isArgOperand(&U)) {
1867 unsigned ArgNo = CB->getArgOperandNo(&U);
1868 const auto *CSArgPI = A.getAAFor<AAPointerInfo>(
1869 *this, IRPosition::callsite_argument(*CB, ArgNo),
1871 if (!CSArgPI)
1872 return false;
1873 bool IsArgMustAcc = (getUnderlyingObject(CurPtr) == &AssociatedValue);
1874 Changed = translateAndAddState(A, *CSArgPI, OffsetInfoMap[CurPtr], *CB,
1875 IsArgMustAcc) |
1876 Changed;
1877 if (!CSArgPI->reachesReturn())
1878 return isValidState();
1879
1881 if (!Callee || Callee->arg_size() <= ArgNo)
1882 return false;
1883 bool UsedAssumedInformation = false;
1884 auto ReturnedValue = A.getAssumedSimplified(
1885 IRPosition::returned(*Callee), *this, UsedAssumedInformation,
1887 auto *ReturnedArg =
1888 dyn_cast_or_null<Argument>(ReturnedValue.value_or(nullptr));
1889 auto *Arg = Callee->getArg(ArgNo);
1890 if (ReturnedArg && Arg != ReturnedArg)
1891 return true;
1892 bool IsRetMustAcc = IsArgMustAcc && (ReturnedArg == Arg);
1893 const auto *CSRetPI = A.getAAFor<AAPointerInfo>(
1895 if (!CSRetPI)
1896 return false;
1897 OffsetInfo OI = OffsetInfoMap[CurPtr];
1898 CSArgPI->addReturnedOffsetsTo(OI);
1899 Changed =
1900 translateAndAddState(A, *CSRetPI, OI, *CB, IsRetMustAcc) | Changed;
1901 return isValidState();
1902 }
1903 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Call user not handled " << *CB
1904 << "\n");
1905 return false;
1906 }
1907
1908 LLVM_DEBUG(dbgs() << "[AAPointerInfo] User not handled " << *Usr << "\n");
1909 return false;
1910 };
1911 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) {
1912 assert(OffsetInfoMap.count(OldU) && "Old use should be known already!");
1913 assert(!OffsetInfoMap[OldU].isUnassigned() && "Old use should be assinged");
1914 if (OffsetInfoMap.count(NewU)) {
1915 LLVM_DEBUG({
1916 if (!(OffsetInfoMap[NewU] == OffsetInfoMap[OldU])) {
1917 dbgs() << "[AAPointerInfo] Equivalent use callback failed: "
1918 << OffsetInfoMap[NewU] << " vs " << OffsetInfoMap[OldU]
1919 << "\n";
1920 }
1921 });
1922 return OffsetInfoMap[NewU] == OffsetInfoMap[OldU];
1923 }
1924 bool Unused;
1925 return HandlePassthroughUser(NewU.get(), OldU.get(), Unused);
1926 };
1927 if (!A.checkForAllUses(UsePred, *this, AssociatedValue,
1928 /* CheckBBLivenessOnly */ true, DepClassTy::OPTIONAL,
1929 /* IgnoreDroppableUses */ true, EquivalentUseCB)) {
1930 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Check for all uses failed, abort!\n");
1931 return indicatePessimisticFixpoint();
1932 }
1933
1934 LLVM_DEBUG({
1935 dbgs() << "Accesses by bin after update:\n";
1936 dumpState(dbgs());
1937 });
1938
1939 return Changed;
1940}
1941
1942struct AAPointerInfoReturned final : AAPointerInfoImpl {
1943 AAPointerInfoReturned(const IRPosition &IRP, Attributor &A)
1944 : AAPointerInfoImpl(IRP, A) {}
1945
1946 /// See AbstractAttribute::updateImpl(...).
1947 ChangeStatus updateImpl(Attributor &A) override {
1948 return indicatePessimisticFixpoint();
1949 }
1950
1951 /// See AbstractAttribute::trackStatistics()
1952 void trackStatistics() const override {
1953 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
1954 }
1955};
1956
1957struct AAPointerInfoArgument final : AAPointerInfoFloating {
1958 AAPointerInfoArgument(const IRPosition &IRP, Attributor &A)
1959 : AAPointerInfoFloating(IRP, A) {}
1960
1961 /// See AbstractAttribute::trackStatistics()
1962 void trackStatistics() const override {
1963 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
1964 }
1965};
1966
1967struct AAPointerInfoCallSiteArgument final : AAPointerInfoFloating {
1968 AAPointerInfoCallSiteArgument(const IRPosition &IRP, Attributor &A)
1969 : AAPointerInfoFloating(IRP, A) {}
1970
1971 /// See AbstractAttribute::updateImpl(...).
1972 ChangeStatus updateImpl(Attributor &A) override {
1973 using namespace AA::PointerInfo;
1974 // We handle memory intrinsics explicitly, at least the first (=
1975 // destination) and second (=source) arguments as we know how they are
1976 // accessed.
1977 if (auto *MI = dyn_cast_or_null<MemIntrinsic>(getCtxI())) {
1978 int64_t LengthVal = AA::RangeTy::Unknown;
1979 if (auto Length = MI->getLengthInBytes())
1980 LengthVal = Length->getSExtValue();
1981 unsigned ArgNo = getIRPosition().getCallSiteArgNo();
1982 ChangeStatus Changed = ChangeStatus::UNCHANGED;
1983 if (ArgNo > 1) {
1984 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Unhandled memory intrinsic "
1985 << *MI << "\n");
1986 return indicatePessimisticFixpoint();
1987 } else {
1988 auto Kind =
1989 ArgNo == 0 ? AccessKind::AK_MUST_WRITE : AccessKind::AK_MUST_READ;
1990 Changed =
1991 Changed | addAccess(A, {0, LengthVal}, *MI, nullptr, Kind, nullptr);
1992 }
1993 LLVM_DEBUG({
1994 dbgs() << "Accesses by bin after update:\n";
1995 dumpState(dbgs());
1996 });
1997
1998 return Changed;
1999 }
2000
2001 // TODO: Once we have call site specific value information we can provide
2002 // call site specific liveness information and then it makes
2003 // sense to specialize attributes for call sites arguments instead of
2004 // redirecting requests to the callee argument.
2005 Argument *Arg = getAssociatedArgument();
2006 if (Arg) {
2007 const IRPosition &ArgPos = IRPosition::argument(*Arg);
2008 auto *ArgAA =
2009 A.getAAFor<AAPointerInfo>(*this, ArgPos, DepClassTy::REQUIRED);
2010 if (ArgAA && ArgAA->getState().isValidState())
2011 return translateAndAddStateFromCallee(A, *ArgAA,
2012 *cast<CallBase>(getCtxI()));
2013 if (!Arg->getParent()->isDeclaration())
2014 return indicatePessimisticFixpoint();
2015 }
2016
2017 bool IsKnownNoCapture;
2019 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNoCapture))
2020 return indicatePessimisticFixpoint();
2021
2022 bool IsKnown = false;
2023 if (AA::isAssumedReadNone(A, getIRPosition(), *this, IsKnown))
2024 return ChangeStatus::UNCHANGED;
2025 bool ReadOnly = AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown);
2026 auto Kind =
2027 ReadOnly ? AccessKind::AK_MAY_READ : AccessKind::AK_MAY_READ_WRITE;
2028 return addAccess(A, AA::RangeTy::getUnknown(), *getCtxI(), nullptr, Kind,
2029 nullptr);
2030 }
2031
2032 /// See AbstractAttribute::trackStatistics()
2033 void trackStatistics() const override {
2034 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
2035 }
2036};
2037
2038struct AAPointerInfoCallSiteReturned final : AAPointerInfoFloating {
2039 AAPointerInfoCallSiteReturned(const IRPosition &IRP, Attributor &A)
2040 : AAPointerInfoFloating(IRP, A) {}
2041
2042 /// See AbstractAttribute::trackStatistics()
2043 void trackStatistics() const override {
2044 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
2045 }
2046};
2047} // namespace
2048
2049/// -----------------------NoUnwind Function Attribute--------------------------
2050
2051namespace {
2052struct AANoUnwindImpl : AANoUnwind {
2053 AANoUnwindImpl(const IRPosition &IRP, Attributor &A) : AANoUnwind(IRP, A) {}
2054
2055 /// See AbstractAttribute::initialize(...).
2056 void initialize(Attributor &A) override {
2057 bool IsKnown;
2059 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
2060 (void)IsKnown;
2061 }
2062
2063 const std::string getAsStr(Attributor *A) const override {
2064 return getAssumed() ? "nounwind" : "may-unwind";
2065 }
2066
2067 /// See AbstractAttribute::updateImpl(...).
2068 ChangeStatus updateImpl(Attributor &A) override {
2069 auto Opcodes = {
2070 (unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,
2071 (unsigned)Instruction::Call, (unsigned)Instruction::CleanupRet,
2072 (unsigned)Instruction::CatchSwitch, (unsigned)Instruction::Resume};
2073
2074 auto CheckForNoUnwind = [&](Instruction &I) {
2075 if (!I.mayThrow(/* IncludePhaseOneUnwind */ true))
2076 return true;
2077
2078 if (const auto *CB = dyn_cast<CallBase>(&I)) {
2079 bool IsKnownNoUnwind;
2081 A, this, IRPosition::callsite_function(*CB), DepClassTy::REQUIRED,
2082 IsKnownNoUnwind);
2083 }
2084 return false;
2085 };
2086
2087 bool UsedAssumedInformation = false;
2088 if (!A.checkForAllInstructions(CheckForNoUnwind, *this, Opcodes,
2089 UsedAssumedInformation))
2090 return indicatePessimisticFixpoint();
2091
2092 return ChangeStatus::UNCHANGED;
2093 }
2094};
2095
2096struct AANoUnwindFunction final : public AANoUnwindImpl {
2097 AANoUnwindFunction(const IRPosition &IRP, Attributor &A)
2098 : AANoUnwindImpl(IRP, A) {}
2099
2100 /// See AbstractAttribute::trackStatistics()
2101 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nounwind) }
2102};
2103
2104/// NoUnwind attribute deduction for a call sites.
2105struct AANoUnwindCallSite final
2106 : AACalleeToCallSite<AANoUnwind, AANoUnwindImpl> {
2107 AANoUnwindCallSite(const IRPosition &IRP, Attributor &A)
2108 : AACalleeToCallSite<AANoUnwind, AANoUnwindImpl>(IRP, A) {}
2109
2110 /// See AbstractAttribute::trackStatistics()
2111 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nounwind); }
2112};
2113} // namespace
2114
2115/// ------------------------ NoSync Function Attribute -------------------------
2116
2117bool AANoSync::isAlignedBarrier(const CallBase &CB, bool ExecutedAligned) {
2118 switch (CB.getIntrinsicID()) {
2119 case Intrinsic::nvvm_barrier_cta_sync_aligned_all:
2120 case Intrinsic::nvvm_barrier_cta_sync_aligned_count:
2121 case Intrinsic::nvvm_barrier_cta_red_and_aligned_all:
2122 case Intrinsic::nvvm_barrier_cta_red_and_aligned_count:
2123 case Intrinsic::nvvm_barrier_cta_red_or_aligned_all:
2124 case Intrinsic::nvvm_barrier_cta_red_or_aligned_count:
2125 case Intrinsic::nvvm_barrier_cta_red_popc_aligned_all:
2126 case Intrinsic::nvvm_barrier_cta_red_popc_aligned_count:
2127 return true;
2128 case Intrinsic::amdgcn_s_barrier:
2129 if (ExecutedAligned)
2130 return true;
2131 break;
2132 default:
2133 break;
2134 }
2135 return hasAssumption(CB, KnownAssumptionString("ompx_aligned_barrier"));
2136}
2137
2139 if (!I->isAtomic())
2140 return false;
2141
2142 if (auto *FI = dyn_cast<FenceInst>(I))
2143 // All legal orderings for fence are stronger than monotonic.
2144 return FI->getSyncScopeID() != SyncScope::SingleThread;
2145 if (auto *AI = dyn_cast<AtomicCmpXchgInst>(I)) {
2146 // Unordered is not a legal ordering for cmpxchg.
2147 return (AI->getSuccessOrdering() != AtomicOrdering::Monotonic ||
2148 AI->getFailureOrdering() != AtomicOrdering::Monotonic);
2149 }
2150
2151 AtomicOrdering Ordering;
2152 switch (I->getOpcode()) {
2153 case Instruction::AtomicRMW:
2154 Ordering = cast<AtomicRMWInst>(I)->getOrdering();
2155 break;
2156 case Instruction::Store:
2157 Ordering = cast<StoreInst>(I)->getOrdering();
2158 break;
2159 case Instruction::Load:
2160 Ordering = cast<LoadInst>(I)->getOrdering();
2161 break;
2162 default:
2164 "New atomic operations need to be known in the attributor.");
2165 }
2166
2167 return (Ordering != AtomicOrdering::Unordered &&
2168 Ordering != AtomicOrdering::Monotonic);
2169}
2170
2171namespace {
2172struct AANoSyncImpl : AANoSync {
2173 AANoSyncImpl(const IRPosition &IRP, Attributor &A) : AANoSync(IRP, A) {}
2174
2175 /// See AbstractAttribute::initialize(...).
2176 void initialize(Attributor &A) override {
2177 bool IsKnown;
2178 assert(!AA::hasAssumedIRAttr<Attribute::NoSync>(A, nullptr, getIRPosition(),
2179 DepClassTy::NONE, IsKnown));
2180 (void)IsKnown;
2181 }
2182
2183 const std::string getAsStr(Attributor *A) const override {
2184 return getAssumed() ? "nosync" : "may-sync";
2185 }
2186
2187 /// See AbstractAttribute::updateImpl(...).
2188 ChangeStatus updateImpl(Attributor &A) override;
2189};
2190
2191ChangeStatus AANoSyncImpl::updateImpl(Attributor &A) {
2192
2193 auto CheckRWInstForNoSync = [&](Instruction &I) {
2194 return AA::isNoSyncInst(A, I, *this);
2195 };
2196
2197 auto CheckForNoSync = [&](Instruction &I) {
2198 // At this point we handled all read/write effects and they are all
2199 // nosync, so they can be skipped.
2200 if (I.mayReadOrWriteMemory())
2201 return true;
2202
2203 bool IsKnown;
2204 CallBase &CB = cast<CallBase>(I);
2207 IsKnown))
2208 return true;
2209
2210 // non-convergent and readnone imply nosync.
2211 return !CB.isConvergent();
2212 };
2213
2214 bool UsedAssumedInformation = false;
2215 if (!A.checkForAllReadWriteInstructions(CheckRWInstForNoSync, *this,
2216 UsedAssumedInformation) ||
2217 !A.checkForAllCallLikeInstructions(CheckForNoSync, *this,
2218 UsedAssumedInformation))
2219 return indicatePessimisticFixpoint();
2220
2222}
2223
2224struct AANoSyncFunction final : public AANoSyncImpl {
2225 AANoSyncFunction(const IRPosition &IRP, Attributor &A)
2226 : AANoSyncImpl(IRP, A) {}
2227
2228 /// See AbstractAttribute::trackStatistics()
2229 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nosync) }
2230};
2231
2232/// NoSync attribute deduction for a call sites.
2233struct AANoSyncCallSite final : AACalleeToCallSite<AANoSync, AANoSyncImpl> {
2234 AANoSyncCallSite(const IRPosition &IRP, Attributor &A)
2235 : AACalleeToCallSite<AANoSync, AANoSyncImpl>(IRP, A) {}
2236
2237 /// See AbstractAttribute::trackStatistics()
2238 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nosync); }
2239};
2240} // namespace
2241
2242/// ------------------------ No-Free Attributes ----------------------------
2243
2244namespace {
2245struct AANoFreeImpl : public AANoFree {
2246 AANoFreeImpl(const IRPosition &IRP, Attributor &A) : AANoFree(IRP, A) {}
2247
2248 /// See AbstractAttribute::initialize(...).
2249 void initialize(Attributor &A) override {
2250 bool IsKnown;
2251 assert(!AA::hasAssumedIRAttr<Attribute::NoFree>(A, nullptr, getIRPosition(),
2252 DepClassTy::NONE, IsKnown));
2253 (void)IsKnown;
2254 }
2255
2256 /// See AbstractAttribute::updateImpl(...).
2257 ChangeStatus updateImpl(Attributor &A) override {
2258 auto CheckForNoFree = [&](Instruction &I) {
2259 if (auto *CB = dyn_cast<CallBase>(&I)) {
2260 bool IsKnown;
2262 A, this, IRPosition::callsite_function(*CB), DepClassTy::REQUIRED,
2263 IsKnown);
2264 }
2265 // Make sure that synchronization cannot establish happens-before with a
2266 // free on another thread.
2267 return AA::isNoSyncInst(A, I, *this);
2268 };
2269
2270 bool UsedAssumedInformation = false;
2271 if (!A.checkForAllReadWriteInstructions(CheckForNoFree, *this,
2272 UsedAssumedInformation) ||
2273 !A.checkForAllCallLikeInstructions(CheckForNoFree, *this,
2274 UsedAssumedInformation))
2275 return indicatePessimisticFixpoint();
2276
2277 return ChangeStatus::UNCHANGED;
2278 }
2279
2280 /// See AbstractAttribute::getAsStr().
2281 const std::string getAsStr(Attributor *A) const override {
2282 return getAssumed() ? "nofree" : "may-free";
2283 }
2284};
2285
2286struct AANoFreeFunction final : public AANoFreeImpl {
2287 AANoFreeFunction(const IRPosition &IRP, Attributor &A)
2288 : AANoFreeImpl(IRP, A) {}
2289
2290 /// See AbstractAttribute::trackStatistics()
2291 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nofree) }
2292};
2293
2294/// NoFree attribute deduction for a call sites.
2295struct AANoFreeCallSite final : AACalleeToCallSite<AANoFree, AANoFreeImpl> {
2296 AANoFreeCallSite(const IRPosition &IRP, Attributor &A)
2297 : AACalleeToCallSite<AANoFree, AANoFreeImpl>(IRP, A) {}
2298
2299 /// See AbstractAttribute::trackStatistics()
2300 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nofree); }
2301};
2302
2303/// NoFree attribute for floating values.
2304struct AANoFreeFloating : AANoFreeImpl {
2305 AANoFreeFloating(const IRPosition &IRP, Attributor &A)
2306 : AANoFreeImpl(IRP, A) {}
2307
2308 /// See AbstractAttribute::trackStatistics()
2309 void trackStatistics() const override{STATS_DECLTRACK_FLOATING_ATTR(nofree)}
2310
2311 /// See Abstract Attribute::updateImpl(...).
2312 ChangeStatus updateImpl(Attributor &A) override {
2313 const IRPosition &IRP = getIRPosition();
2314
2315 bool IsKnown;
2318 DepClassTy::OPTIONAL, IsKnown))
2319 return ChangeStatus::UNCHANGED;
2320
2321 Value &AssociatedValue = getIRPosition().getAssociatedValue();
2322 auto Pred = [&](const Use &U, bool &Follow) -> bool {
2323 Instruction *UserI = cast<Instruction>(U.getUser());
2324 if (auto *CB = dyn_cast<CallBase>(UserI)) {
2325 if (CB->isBundleOperand(&U))
2326 return false;
2327 if (!CB->isArgOperand(&U))
2328 return true;
2329 unsigned ArgNo = CB->getArgOperandNo(&U);
2330
2331 // Even if the argument is nofree, we still need to check for nocapture,
2332 // as the call may capture the argument without freeing it, and the
2333 // captured argument is freed later.
2334 bool IsKnown;
2336 A, this, IRPosition::callsite_argument(*CB, ArgNo),
2337 DepClassTy::REQUIRED, IsKnown))
2338 return false;
2339
2340 const AANoCapture *NoCaptureAA = nullptr;
2342 A, this, IRPosition::callsite_argument(*CB, ArgNo),
2343 DepClassTy::REQUIRED, IsKnown,
2344 /*IgnoreSubsumingPositions=*/false, &NoCaptureAA)) {
2345 if (NoCaptureAA && NoCaptureAA->isAssumedNoCaptureMaybeReturned()) {
2346 Follow = true;
2347 return true;
2348 }
2349 return false;
2350 }
2351
2352 return true;
2353 }
2354
2355 UseCaptureInfo CI = DetermineUseCaptureKind(U, /*Base=*/nullptr);
2356 if (!capturesAnyProvenance(CI))
2357 return true;
2359 Follow = true;
2360 return true;
2361 }
2362
2363 if (isa<ReturnInst>(UserI) && getIRPosition().isArgumentPosition())
2364 return true;
2365
2366 // Capturing user.
2367 return false;
2368 };
2369 if (!A.checkForAllUses(Pred, *this, AssociatedValue))
2370 return indicatePessimisticFixpoint();
2371
2372 return ChangeStatus::UNCHANGED;
2373 }
2374};
2375
2376/// NoFree attribute for a call site argument.
2377struct AANoFreeArgument final : AANoFreeFloating {
2378 AANoFreeArgument(const IRPosition &IRP, Attributor &A)
2379 : AANoFreeFloating(IRP, A) {}
2380
2381 /// See AbstractAttribute::trackStatistics()
2382 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nofree) }
2383};
2384
2385/// NoFree attribute for call site arguments.
2386struct AANoFreeCallSiteArgument final : AANoFreeFloating {
2387 AANoFreeCallSiteArgument(const IRPosition &IRP, Attributor &A)
2388 : AANoFreeFloating(IRP, A) {}
2389
2390 /// See AbstractAttribute::updateImpl(...).
2391 ChangeStatus updateImpl(Attributor &A) override {
2392 // TODO: Once we have call site specific value information we can provide
2393 // call site specific liveness information and then it makes
2394 // sense to specialize attributes for call sites arguments instead of
2395 // redirecting requests to the callee argument.
2396 Argument *Arg = getAssociatedArgument();
2397 if (!Arg)
2398 return indicatePessimisticFixpoint();
2399 const IRPosition &ArgPos = IRPosition::argument(*Arg);
2400 bool IsKnown;
2402 DepClassTy::REQUIRED, IsKnown))
2403 return ChangeStatus::UNCHANGED;
2404 return indicatePessimisticFixpoint();
2405 }
2406
2407 /// See AbstractAttribute::trackStatistics()
2408 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(nofree) };
2409};
2410
2411/// NoFree attribute for function return value.
2412struct AANoFreeReturned final : AANoFreeFloating {
2413 AANoFreeReturned(const IRPosition &IRP, Attributor &A)
2414 : AANoFreeFloating(IRP, A) {
2415 llvm_unreachable("NoFree is not applicable to function returns!");
2416 }
2417
2418 /// See AbstractAttribute::initialize(...).
2419 void initialize(Attributor &A) override {
2420 llvm_unreachable("NoFree is not applicable to function returns!");
2421 }
2422
2423 /// See AbstractAttribute::updateImpl(...).
2424 ChangeStatus updateImpl(Attributor &A) override {
2425 llvm_unreachable("NoFree is not applicable to function returns!");
2426 }
2427
2428 /// See AbstractAttribute::trackStatistics()
2429 void trackStatistics() const override {}
2430};
2431
2432/// NoFree attribute deduction for a call site return value.
2433struct AANoFreeCallSiteReturned final : AANoFreeFloating {
2434 AANoFreeCallSiteReturned(const IRPosition &IRP, Attributor &A)
2435 : AANoFreeFloating(IRP, A) {}
2436
2437 ChangeStatus manifest(Attributor &A) override {
2438 return ChangeStatus::UNCHANGED;
2439 }
2440 /// See AbstractAttribute::trackStatistics()
2441 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(nofree) }
2442};
2443} // namespace
2444
2445/// ------------------------ NonNull Argument Attribute ------------------------
2446
2448 Attribute::AttrKind ImpliedAttributeKind,
2449 bool IgnoreSubsumingPositions) {
2451 AttrKinds.push_back(Attribute::NonNull);
2454 AttrKinds.push_back(Attribute::Dereferenceable);
2455 if (A.hasAttr(IRP, AttrKinds, IgnoreSubsumingPositions, Attribute::NonNull))
2456 return true;
2457
2458 DominatorTree *DT = nullptr;
2459 AssumptionCache *AC = nullptr;
2460 InformationCache &InfoCache = A.getInfoCache();
2461 if (const Function *Fn = IRP.getAnchorScope()) {
2462 if (!Fn->isDeclaration()) {
2465 }
2466 }
2467
2469 if (IRP.getPositionKind() != IRP_RETURNED) {
2470 Worklist.push_back({IRP.getAssociatedValue(), IRP.getCtxI()});
2471 } else {
2472 bool UsedAssumedInformation = false;
2473 if (!A.checkForAllInstructions(
2474 [&](Instruction &I) {
2475 Worklist.push_back({*cast<ReturnInst>(I).getReturnValue(), &I});
2476 return true;
2477 },
2478 IRP.getAssociatedFunction(), nullptr, {Instruction::Ret},
2479 UsedAssumedInformation, false, /*CheckPotentiallyDead=*/true))
2480 return false;
2481 }
2482
2483 if (llvm::any_of(Worklist, [&](AA::ValueAndContext VAC) {
2484 return !isKnownNonZero(
2485 VAC.getValue(),
2486 SimplifyQuery(A.getDataLayout(), DT, AC, VAC.getCtxI()));
2487 }))
2488 return false;
2489
2490 A.manifestAttrs(IRP, {Attribute::get(IRP.getAnchorValue().getContext(),
2491 Attribute::NonNull)});
2492 return true;
2493}
2494
2495namespace {
2496static int64_t getKnownNonNullAndDerefBytesForUse(
2497 Attributor &A, const AbstractAttribute &QueryingAA, Value &AssociatedValue,
2498 const Use *U, const Instruction *I, bool &IsNonNull, bool &TrackUse) {
2499 TrackUse = false;
2500
2501 const Value *UseV = U->get();
2502 if (!UseV->getType()->isPointerTy())
2503 return 0;
2504
2505 // We need to follow common pointer manipulation uses to the accesses they
2506 // feed into. We can try to be smart to avoid looking through things we do not
2507 // like for now, e.g., non-inbounds GEPs.
2508 if (isa<CastInst>(I)) {
2509 TrackUse = true;
2510 return 0;
2511 }
2512
2514 TrackUse = true;
2515 return 0;
2516 }
2517
2518 Type *PtrTy = UseV->getType();
2519 const Function *F = I->getFunction();
2522 const DataLayout &DL = A.getInfoCache().getDL();
2523 if (const auto *CB = dyn_cast<CallBase>(I)) {
2524 if (CB->isBundleOperand(U)) {
2525 if (RetainedKnowledge RK = getKnowledgeFromUse(
2526 U, {Attribute::NonNull, Attribute::Dereferenceable})) {
2527 IsNonNull |=
2528 (RK.AttrKind == Attribute::NonNull || !NullPointerIsDefined);
2529 return RK.ArgValue;
2530 }
2531 return 0;
2532 }
2533
2534 if (CB->isCallee(U)) {
2535 IsNonNull |= !NullPointerIsDefined;
2536 return 0;
2537 }
2538
2539 unsigned ArgNo = CB->getArgOperandNo(U);
2540 IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo);
2541 // As long as we only use known information there is no need to track
2542 // dependences here.
2543 bool IsKnownNonNull;
2545 DepClassTy::NONE, IsKnownNonNull);
2546 IsNonNull |= IsKnownNonNull;
2547 auto *DerefAA =
2548 A.getAAFor<AADereferenceable>(QueryingAA, IRP, DepClassTy::NONE);
2549 return DerefAA ? DerefAA->getKnownDereferenceableBytes() : 0;
2550 }
2551
2552 std::optional<MemoryLocation> Loc = MemoryLocation::getOrNone(I);
2553 if (!Loc || Loc->Ptr != UseV || !Loc->Size.isPrecise() ||
2554 Loc->Size.isScalable() || I->isVolatile())
2555 return 0;
2556
2557 int64_t Offset;
2558 const Value *Base =
2559 getMinimalBaseOfPointer(A, QueryingAA, Loc->Ptr, Offset, DL);
2560 if (Base && Base == &AssociatedValue) {
2561 int64_t DerefBytes = Loc->Size.getValue() + Offset;
2562 IsNonNull |= !NullPointerIsDefined;
2563 return std::max(int64_t(0), DerefBytes);
2564 }
2565
2566 /// Corner case when an offset is 0.
2568 /*AllowNonInbounds*/ true);
2569 if (Base && Base == &AssociatedValue && Offset == 0) {
2570 int64_t DerefBytes = Loc->Size.getValue();
2571 IsNonNull |= !NullPointerIsDefined;
2572 return std::max(int64_t(0), DerefBytes);
2573 }
2574
2575 return 0;
2576}
2577
2578struct AANonNullImpl : AANonNull {
2579 AANonNullImpl(const IRPosition &IRP, Attributor &A) : AANonNull(IRP, A) {}
2580
2581 /// See AbstractAttribute::initialize(...).
2582 void initialize(Attributor &A) override {
2583 Value &V = *getAssociatedValue().stripPointerCasts();
2584 if (isa<ConstantPointerNull>(V)) {
2585 indicatePessimisticFixpoint();
2586 return;
2587 }
2588
2589 if (Instruction *CtxI = getCtxI())
2590 followUsesInMBEC(*this, A, getState(), *CtxI);
2591 }
2592
2593 /// See followUsesInMBEC
2594 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
2595 AANonNull::StateType &State) {
2596 bool IsNonNull = false;
2597 bool TrackUse = false;
2598 getKnownNonNullAndDerefBytesForUse(A, *this, getAssociatedValue(), U, I,
2599 IsNonNull, TrackUse);
2600 State.setKnown(IsNonNull);
2601 return TrackUse;
2602 }
2603
2604 /// See AbstractAttribute::getAsStr().
2605 const std::string getAsStr(Attributor *A) const override {
2606 return getAssumed() ? "nonnull" : "may-null";
2607 }
2608};
2609
2610/// NonNull attribute for a floating value.
2611struct AANonNullFloating : public AANonNullImpl {
2612 AANonNullFloating(const IRPosition &IRP, Attributor &A)
2613 : AANonNullImpl(IRP, A) {}
2614
2615 /// See AbstractAttribute::updateImpl(...).
2616 ChangeStatus updateImpl(Attributor &A) override {
2617 auto CheckIRP = [&](const IRPosition &IRP) {
2618 bool IsKnownNonNull;
2620 A, *this, IRP, DepClassTy::OPTIONAL, IsKnownNonNull);
2621 };
2622
2623 bool Stripped;
2624 bool UsedAssumedInformation = false;
2625 Value *AssociatedValue = &getAssociatedValue();
2627 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
2628 AA::AnyScope, UsedAssumedInformation))
2629 Stripped = false;
2630 else
2631 Stripped =
2632 Values.size() != 1 || Values.front().getValue() != AssociatedValue;
2633
2634 if (!Stripped) {
2635 bool IsKnown;
2636 if (auto *PHI = dyn_cast<PHINode>(AssociatedValue))
2637 if (llvm::all_of(PHI->incoming_values(), [&](Value *Op) {
2638 return AA::hasAssumedIRAttr<Attribute::NonNull>(
2639 A, this, IRPosition::value(*Op), DepClassTy::OPTIONAL,
2640 IsKnown);
2641 }))
2642 return ChangeStatus::UNCHANGED;
2643 if (auto *Select = dyn_cast<SelectInst>(AssociatedValue))
2645 A, this, IRPosition::value(*Select->getFalseValue()),
2646 DepClassTy::OPTIONAL, IsKnown) &&
2648 A, this, IRPosition::value(*Select->getTrueValue()),
2649 DepClassTy::OPTIONAL, IsKnown))
2650 return ChangeStatus::UNCHANGED;
2651
2652 // If we haven't stripped anything we might still be able to use a
2653 // different AA, but only if the IRP changes. Effectively when we
2654 // interpret this not as a call site value but as a floating/argument
2655 // value.
2656 const IRPosition AVIRP = IRPosition::value(*AssociatedValue);
2657 if (AVIRP == getIRPosition() || !CheckIRP(AVIRP))
2658 return indicatePessimisticFixpoint();
2659 return ChangeStatus::UNCHANGED;
2660 }
2661
2662 for (const auto &VAC : Values)
2663 if (!CheckIRP(IRPosition::value(*VAC.getValue())))
2664 return indicatePessimisticFixpoint();
2665
2666 return ChangeStatus::UNCHANGED;
2667 }
2668
2669 /// See AbstractAttribute::trackStatistics()
2670 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
2671};
2672
2673/// NonNull attribute for function return value.
2674struct AANonNullReturned final
2675 : AAReturnedFromReturnedValues<AANonNull, AANonNull, AANonNull::StateType,
2676 false, AANonNull::IRAttributeKind, false> {
2677 AANonNullReturned(const IRPosition &IRP, Attributor &A)
2678 : AAReturnedFromReturnedValues<AANonNull, AANonNull, AANonNull::StateType,
2679 false, Attribute::NonNull, false>(IRP, A) {
2680 }
2681
2682 /// See AbstractAttribute::getAsStr().
2683 const std::string getAsStr(Attributor *A) const override {
2684 return getAssumed() ? "nonnull" : "may-null";
2685 }
2686
2687 /// See AbstractAttribute::trackStatistics()
2688 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
2689};
2690
2691/// NonNull attribute for function argument.
2692struct AANonNullArgument final
2693 : AAArgumentFromCallSiteArguments<AANonNull, AANonNullImpl> {
2694 AANonNullArgument(const IRPosition &IRP, Attributor &A)
2695 : AAArgumentFromCallSiteArguments<AANonNull, AANonNullImpl>(IRP, A) {}
2696
2697 /// See AbstractAttribute::trackStatistics()
2698 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nonnull) }
2699};
2700
2701struct AANonNullCallSiteArgument final : AANonNullFloating {
2702 AANonNullCallSiteArgument(const IRPosition &IRP, Attributor &A)
2703 : AANonNullFloating(IRP, A) {}
2704
2705 /// See AbstractAttribute::trackStatistics()
2706 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(nonnull) }
2707};
2708
2709/// NonNull attribute for a call site return position.
2710struct AANonNullCallSiteReturned final
2711 : AACalleeToCallSite<AANonNull, AANonNullImpl> {
2712 AANonNullCallSiteReturned(const IRPosition &IRP, Attributor &A)
2713 : AACalleeToCallSite<AANonNull, AANonNullImpl>(IRP, A) {}
2714
2715 /// See AbstractAttribute::trackStatistics()
2716 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(nonnull) }
2717};
2718} // namespace
2719
2720/// ------------------------ Must-Progress Attributes --------------------------
2721namespace {
2722struct AAMustProgressImpl : public AAMustProgress {
2723 AAMustProgressImpl(const IRPosition &IRP, Attributor &A)
2724 : AAMustProgress(IRP, A) {}
2725
2726 /// See AbstractAttribute::initialize(...).
2727 void initialize(Attributor &A) override {
2728 bool IsKnown;
2730 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
2731 (void)IsKnown;
2732 }
2733
2734 /// See AbstractAttribute::getAsStr()
2735 const std::string getAsStr(Attributor *A) const override {
2736 return getAssumed() ? "mustprogress" : "may-not-progress";
2737 }
2738};
2739
2740struct AAMustProgressFunction final : AAMustProgressImpl {
2741 AAMustProgressFunction(const IRPosition &IRP, Attributor &A)
2742 : AAMustProgressImpl(IRP, A) {}
2743
2744 /// See AbstractAttribute::updateImpl(...).
2745 ChangeStatus updateImpl(Attributor &A) override {
2746 bool IsKnown;
2748 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnown)) {
2749 if (IsKnown)
2750 return indicateOptimisticFixpoint();
2751 return ChangeStatus::UNCHANGED;
2752 }
2753
2754 auto CheckForMustProgress = [&](AbstractCallSite ACS) {
2755 IRPosition IPos = IRPosition::callsite_function(*ACS.getInstruction());
2756 bool IsKnownMustProgress;
2758 A, this, IPos, DepClassTy::REQUIRED, IsKnownMustProgress,
2759 /* IgnoreSubsumingPositions */ true);
2760 };
2761
2762 bool AllCallSitesKnown = true;
2763 if (!A.checkForAllCallSites(CheckForMustProgress, *this,
2764 /* RequireAllCallSites */ true,
2765 AllCallSitesKnown))
2766 return indicatePessimisticFixpoint();
2767
2768 return ChangeStatus::UNCHANGED;
2769 }
2770
2771 /// See AbstractAttribute::trackStatistics()
2772 void trackStatistics() const override {
2773 STATS_DECLTRACK_FN_ATTR(mustprogress)
2774 }
2775};
2776
2777/// MustProgress attribute deduction for a call sites.
2778struct AAMustProgressCallSite final : AAMustProgressImpl {
2779 AAMustProgressCallSite(const IRPosition &IRP, Attributor &A)
2780 : AAMustProgressImpl(IRP, A) {}
2781
2782 /// See AbstractAttribute::updateImpl(...).
2783 ChangeStatus updateImpl(Attributor &A) override {
2784 // TODO: Once we have call site specific value information we can provide
2785 // call site specific liveness information and then it makes
2786 // sense to specialize attributes for call sites arguments instead of
2787 // redirecting requests to the callee argument.
2788 const IRPosition &FnPos = IRPosition::function(*getAnchorScope());
2789 bool IsKnownMustProgress;
2791 A, this, FnPos, DepClassTy::REQUIRED, IsKnownMustProgress))
2792 return indicatePessimisticFixpoint();
2793 return ChangeStatus::UNCHANGED;
2794 }
2795
2796 /// See AbstractAttribute::trackStatistics()
2797 void trackStatistics() const override {
2798 STATS_DECLTRACK_CS_ATTR(mustprogress);
2799 }
2800};
2801} // namespace
2802
2803/// ------------------------ No-Recurse Attributes ----------------------------
2804
2805namespace {
2806struct AANoRecurseImpl : public AANoRecurse {
2807 AANoRecurseImpl(const IRPosition &IRP, Attributor &A) : AANoRecurse(IRP, A) {}
2808
2809 /// See AbstractAttribute::initialize(...).
2810 void initialize(Attributor &A) override {
2811 bool IsKnown;
2813 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
2814 (void)IsKnown;
2815 }
2816
2817 /// See AbstractAttribute::getAsStr()
2818 const std::string getAsStr(Attributor *A) const override {
2819 return getAssumed() ? "norecurse" : "may-recurse";
2820 }
2821};
2822
2823struct AANoRecurseFunction final : AANoRecurseImpl {
2824 AANoRecurseFunction(const IRPosition &IRP, Attributor &A)
2825 : AANoRecurseImpl(IRP, A) {}
2826
2827 /// See AbstractAttribute::updateImpl(...).
2828 ChangeStatus updateImpl(Attributor &A) override {
2829
2830 // If all live call sites are known to be no-recurse, we are as well.
2831 auto CallSitePred = [&](AbstractCallSite ACS) {
2832 bool IsKnownNoRecurse;
2834 A, this,
2835 IRPosition::function(*ACS.getInstruction()->getFunction()),
2836 DepClassTy::NONE, IsKnownNoRecurse))
2837 return false;
2838 return IsKnownNoRecurse;
2839 };
2840 bool UsedAssumedInformation = false;
2841 if (A.checkForAllCallSites(CallSitePred, *this, true,
2842 UsedAssumedInformation)) {
2843 // If we know all call sites and all are known no-recurse, we are done.
2844 // If all known call sites, which might not be all that exist, are known
2845 // to be no-recurse, we are not done but we can continue to assume
2846 // no-recurse. If one of the call sites we have not visited will become
2847 // live, another update is triggered.
2848 if (!UsedAssumedInformation)
2849 indicateOptimisticFixpoint();
2850 return ChangeStatus::UNCHANGED;
2851 }
2852
2853 const AAInterFnReachability *EdgeReachability =
2854 A.getAAFor<AAInterFnReachability>(*this, getIRPosition(),
2855 DepClassTy::REQUIRED);
2856 if (EdgeReachability && EdgeReachability->canReach(A, *getAnchorScope()))
2857 return indicatePessimisticFixpoint();
2858 return ChangeStatus::UNCHANGED;
2859 }
2860
2861 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(norecurse) }
2862};
2863
2864/// NoRecurse attribute deduction for a call sites.
2865struct AANoRecurseCallSite final
2866 : AACalleeToCallSite<AANoRecurse, AANoRecurseImpl> {
2867 AANoRecurseCallSite(const IRPosition &IRP, Attributor &A)
2868 : AACalleeToCallSite<AANoRecurse, AANoRecurseImpl>(IRP, A) {}
2869
2870 /// See AbstractAttribute::trackStatistics()
2871 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(norecurse); }
2872};
2873} // namespace
2874
2875/// ------------------------ No-Convergent Attribute --------------------------
2876
2877namespace {
2878struct AANonConvergentImpl : public AANonConvergent {
2879 AANonConvergentImpl(const IRPosition &IRP, Attributor &A)
2880 : AANonConvergent(IRP, A) {}
2881
2882 /// See AbstractAttribute::getAsStr()
2883 const std::string getAsStr(Attributor *A) const override {
2884 return getAssumed() ? "non-convergent" : "may-be-convergent";
2885 }
2886};
2887
2888struct AANonConvergentFunction final : AANonConvergentImpl {
2889 AANonConvergentFunction(const IRPosition &IRP, Attributor &A)
2890 : AANonConvergentImpl(IRP, A) {}
2891
2892 /// See AbstractAttribute::updateImpl(...).
2893 ChangeStatus updateImpl(Attributor &A) override {
2894 // If all function calls are known to not be convergent, we are not
2895 // convergent.
2896 auto CalleeIsNotConvergent = [&](Instruction &Inst) {
2897 CallBase &CB = cast<CallBase>(Inst);
2899 if (!Callee || Callee->isIntrinsic()) {
2900 return false;
2901 }
2902 if (Callee->isDeclaration()) {
2903 return !Callee->hasFnAttribute(Attribute::Convergent);
2904 }
2905 const auto *ConvergentAA = A.getAAFor<AANonConvergent>(
2906 *this, IRPosition::function(*Callee), DepClassTy::REQUIRED);
2907 return ConvergentAA && ConvergentAA->isAssumedNotConvergent();
2908 };
2909
2910 bool UsedAssumedInformation = false;
2911 if (!A.checkForAllCallLikeInstructions(CalleeIsNotConvergent, *this,
2912 UsedAssumedInformation)) {
2913 return indicatePessimisticFixpoint();
2914 }
2915 return ChangeStatus::UNCHANGED;
2916 }
2917
2918 ChangeStatus manifest(Attributor &A) override {
2919 if (isKnownNotConvergent() &&
2920 A.hasAttr(getIRPosition(), Attribute::Convergent)) {
2921 A.removeAttrs(getIRPosition(), {Attribute::Convergent});
2922 return ChangeStatus::CHANGED;
2923 }
2924 return ChangeStatus::UNCHANGED;
2925 }
2926
2927 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(convergent) }
2928};
2929} // namespace
2930
2931/// -------------------- Undefined-Behavior Attributes ------------------------
2932
2933namespace {
2934struct AAUndefinedBehaviorImpl : public AAUndefinedBehavior {
2935 AAUndefinedBehaviorImpl(const IRPosition &IRP, Attributor &A)
2936 : AAUndefinedBehavior(IRP, A) {}
2937
2938 struct UBInfo {
2939 enum Kind {
2940 NullPtrAccess,
2941 UndefPtrAccess,
2942 UndefBranchCondition,
2943 UndefReturnValue,
2944 NullReturnViolatesNonNull,
2945 UndefCallArgument,
2946 NullArgViolatesNonNull,
2947 };
2948
2949 Kind K;
2950 std::optional<unsigned> ArgNo;
2951
2952 UBInfo(Kind K) : K(K), ArgNo(std::nullopt) {}
2953
2954 UBInfo(Kind K, std::optional<unsigned> ArgNo) : K(K), ArgNo(ArgNo) {}
2955 };
2956
2957 /// See AbstractAttribute::updateImpl(...).
2958 // through a pointer (i.e. also branches etc.)
2959 ChangeStatus updateImpl(Attributor &A) override {
2960 const size_t UBPrevSize = KnownUBInsts.size();
2961 const size_t NoUBPrevSize = AssumedNoUBInsts.size();
2962
2963 auto InspectMemAccessInstForUB = [&](Instruction &I) {
2964 // Volatile accesses on null are not necessarily UB.
2965 if (I.isVolatile())
2966 return true;
2967
2968 // Skip instructions that are already saved.
2969 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
2970 return true;
2971
2972 // If we reach here, we know we have an instruction
2973 // that accesses memory through a pointer operand,
2974 // for which getPointerOperand() should give it to us.
2975 Value *PtrOp =
2976 const_cast<Value *>(getPointerOperand(&I, /* AllowVolatile */ true));
2977 assert(PtrOp &&
2978 "Expected pointer operand of memory accessing instruction");
2979
2980 // Either we stopped and the appropriate action was taken,
2981 // or we got back a simplified value to continue.
2982 std::optional<Value *> SimplifiedPtrOp =
2983 stopOnUndefOrAssumed(A, PtrOp, &I, UBInfo::UndefPtrAccess);
2984 if (!SimplifiedPtrOp || !*SimplifiedPtrOp)
2985 return true;
2986 const Value *PtrOpVal = *SimplifiedPtrOp;
2987
2988 // A memory access through a pointer is considered UB
2989 // only if the pointer has constant null value.
2990 // TODO: Expand it to not only check constant values.
2991 if (!isa<ConstantPointerNull>(PtrOpVal)) {
2992 AssumedNoUBInsts.insert(&I);
2993 return true;
2994 }
2995 const Type *PtrTy = PtrOpVal->getType();
2996
2997 // Because we only consider instructions inside functions,
2998 // assume that a parent function exists.
2999 const Function *F = I.getFunction();
3000
3001 // A memory access using constant null pointer is only considered UB
3002 // if null pointer is _not_ defined for the target platform.
3004 AssumedNoUBInsts.insert(&I);
3005 else
3006 KnownUBInsts.try_emplace(&I, UBInfo::NullPtrAccess);
3007 return true;
3008 };
3009
3010 auto InspectBrInstForUB = [&](Instruction &I) {
3011 // A conditional branch instruction is considered UB if it has `undef`
3012 // condition.
3013
3014 // Skip instructions that are already saved.
3015 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
3016 return true;
3017
3018 // We know we have a branch instruction.
3019 auto *BrInst = cast<CondBrInst>(&I);
3020
3021 // Either we stopped and the appropriate action was taken,
3022 // or we got back a simplified value to continue.
3023 std::optional<Value *> SimplifiedCond = stopOnUndefOrAssumed(
3024 A, BrInst->getCondition(), BrInst, UBInfo::UndefBranchCondition);
3025 if (!SimplifiedCond || !*SimplifiedCond)
3026 return true;
3027 AssumedNoUBInsts.insert(&I);
3028 return true;
3029 };
3030
3031 auto InspectCallSiteForUB = [&](Instruction &I) {
3032 // Check whether a callsite always cause UB or not
3033
3034 // Skip instructions that are already saved.
3035 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
3036 return true;
3037
3038 // Check nonnull and noundef argument attribute violation for each
3039 // callsite.
3040 CallBase &CB = cast<CallBase>(I);
3042 if (!Callee)
3043 return true;
3044 for (unsigned idx = 0; idx < CB.arg_size(); idx++) {
3045 // If current argument is known to be simplified to null pointer and the
3046 // corresponding argument position is known to have nonnull attribute,
3047 // the argument is poison. Furthermore, if the argument is poison and
3048 // the position is known to have noundef attriubte, this callsite is
3049 // considered UB.
3050 if (idx >= Callee->arg_size())
3051 break;
3052 Value *ArgVal = CB.getArgOperand(idx);
3053 if (!ArgVal)
3054 continue;
3055 // Here, we handle three cases.
3056 // (1) Not having a value means it is dead. (we can replace the value
3057 // with undef)
3058 // (2) Simplified to undef. The argument violate noundef attriubte.
3059 // (3) Simplified to null pointer where known to be nonnull.
3060 // The argument is a poison value and violate noundef attribute.
3061 IRPosition CalleeArgumentIRP = IRPosition::callsite_argument(CB, idx);
3062 bool IsKnownNoUndef;
3064 A, this, CalleeArgumentIRP, DepClassTy::NONE, IsKnownNoUndef);
3065 if (!IsKnownNoUndef)
3066 continue;
3067 bool UsedAssumedInformation = false;
3068 std::optional<Value *> SimplifiedVal =
3069 A.getAssumedSimplified(IRPosition::value(*ArgVal), *this,
3070 UsedAssumedInformation, AA::Interprocedural);
3071 if (UsedAssumedInformation)
3072 continue;
3073 if (SimplifiedVal && !*SimplifiedVal)
3074 return true;
3075 if (!SimplifiedVal || isa<UndefValue>(**SimplifiedVal)) {
3076 KnownUBInsts.try_emplace(&I, UBInfo(UBInfo::UndefCallArgument, idx));
3077 continue;
3078 }
3079 if (!ArgVal->getType()->isPointerTy() ||
3080 !isa<ConstantPointerNull>(**SimplifiedVal))
3081 continue;
3082 bool IsKnownNonNull;
3084 A, this, CalleeArgumentIRP, DepClassTy::NONE, IsKnownNonNull);
3085 if (IsKnownNonNull)
3086 KnownUBInsts.try_emplace(&I,
3087 UBInfo(UBInfo::NullArgViolatesNonNull, idx));
3088 }
3089 return true;
3090 };
3091
3092 auto InspectReturnInstForUB = [&](Instruction &I) {
3093 auto &RI = cast<ReturnInst>(I);
3094 // Either we stopped and the appropriate action was taken,
3095 // or we got back a simplified return value to continue.
3096 std::optional<Value *> SimplifiedRetValue = stopOnUndefOrAssumed(
3097 A, RI.getReturnValue(), &I, UBInfo::UndefReturnValue);
3098 if (!SimplifiedRetValue || !*SimplifiedRetValue)
3099 return true;
3100
3101 // Check if a return instruction always cause UB or not
3102 // Note: It is guaranteed that the returned position of the anchor
3103 // scope has noundef attribute when this is called.
3104 // We also ensure the return position is not "assumed dead"
3105 // because the returned value was then potentially simplified to
3106 // `undef` in AAReturnedValues without removing the `noundef`
3107 // attribute yet.
3108
3109 // When the returned position has noundef attriubte, UB occurs in the
3110 // following cases.
3111 // (1) Returned value is known to be undef.
3112 // (2) The value is known to be a null pointer and the returned
3113 // position has nonnull attribute (because the returned value is
3114 // poison).
3115 if (isa<ConstantPointerNull>(*SimplifiedRetValue)) {
3116 bool IsKnownNonNull;
3118 A, this, IRPosition::returned(*getAnchorScope()), DepClassTy::NONE,
3119 IsKnownNonNull);
3120 if (IsKnownNonNull)
3121 KnownUBInsts.try_emplace(&I, UBInfo::NullReturnViolatesNonNull);
3122 }
3123
3124 return true;
3125 };
3126
3127 bool UsedAssumedInformation = false;
3128 A.checkForAllInstructions(InspectMemAccessInstForUB, *this,
3129 {Instruction::Load, Instruction::Store,
3130 Instruction::AtomicCmpXchg,
3131 Instruction::AtomicRMW},
3132 UsedAssumedInformation,
3133 /* CheckBBLivenessOnly */ true);
3134 A.checkForAllInstructions(InspectBrInstForUB, *this, {Instruction::CondBr},
3135 UsedAssumedInformation,
3136 /* CheckBBLivenessOnly */ true);
3137 A.checkForAllCallLikeInstructions(InspectCallSiteForUB, *this,
3138 UsedAssumedInformation);
3139
3140 // If the returned position of the anchor scope has noundef attriubte, check
3141 // all returned instructions.
3142 if (!getAnchorScope()->getReturnType()->isVoidTy()) {
3143 const IRPosition &ReturnIRP = IRPosition::returned(*getAnchorScope());
3144 if (!A.isAssumedDead(ReturnIRP, this, nullptr, UsedAssumedInformation)) {
3145 bool IsKnownNoUndef;
3147 A, this, ReturnIRP, DepClassTy::NONE, IsKnownNoUndef);
3148 if (IsKnownNoUndef)
3149 A.checkForAllInstructions(InspectReturnInstForUB, *this,
3150 {Instruction::Ret}, UsedAssumedInformation,
3151 /* CheckBBLivenessOnly */ true);
3152 }
3153 }
3154
3155 if (NoUBPrevSize != AssumedNoUBInsts.size() ||
3156 UBPrevSize != KnownUBInsts.size())
3157 return ChangeStatus::CHANGED;
3158 return ChangeStatus::UNCHANGED;
3159 }
3160
3161 bool isKnownToCauseUB(Instruction *I) const override {
3162 return KnownUBInsts.count(I);
3163 }
3164
3165 bool isAssumedToCauseUB(Instruction *I) const override {
3166 // In simple words, if an instruction is not in the assumed to _not_
3167 // cause UB, then it is assumed UB (that includes those
3168 // in the KnownUBInsts set). The rest is boilerplate
3169 // is to ensure that it is one of the instructions we test
3170 // for UB.
3171
3172 switch (I->getOpcode()) {
3173 case Instruction::Load:
3174 case Instruction::Store:
3175 case Instruction::AtomicCmpXchg:
3176 case Instruction::AtomicRMW:
3177 case Instruction::CondBr:
3178 return !AssumedNoUBInsts.count(I);
3179 default:
3180 return false;
3181 }
3182 return false;
3183 }
3184
3185 /// Emit an optimization remark explaining why \p I is known to cause UB,
3186 /// per \p Info, right before it is replaced with 'unreachable'.
3187 static void emitUBRemark(Attributor &A, Instruction *I, const UBInfo &Info) {
3188 auto Remark = [&](OptimizationRemark OR) {
3189 switch (Info.K) {
3190 case UBInfo::NullPtrAccess:
3191 case UBInfo::UndefPtrAccess: {
3192 return OR << "Memory access through a pointer known to be "
3193 << ore::NV("Pointer",
3194 getPointerOperand(I, /*AllowVolatile*/ true))
3195 << " is undefined behavior; replacing with 'unreachable'.";
3196 }
3197 case UBInfo::UndefBranchCondition:
3198 return OR << "Branch condition known to be "
3199 << ore::NV("Condition", cast<CondBrInst>(I)->getCondition())
3200 << " is undefined behavior; replacing with 'unreachable'.";
3201 case UBInfo::UndefReturnValue:
3202 case UBInfo::NullReturnViolatesNonNull:
3203 return OR << "Value returned known to be "
3204 << ore::NV("ReturnValue",
3205 cast<ReturnInst>(I)->getReturnValue())
3206 << " is undefined behavior; replacing with 'unreachable'.";
3207 case UBInfo::UndefCallArgument:
3208 case UBInfo::NullArgViolatesNonNull: {
3209 bool IsUndef = Info.K == UBInfo::UndefCallArgument;
3210 CallBase &CB = *cast<CallBase>(I);
3211 OR << "Argument " << ore::NV("ArgNo", *Info.ArgNo)
3212 << " passed to parameter of ";
3213 if (auto *Callee = dyn_cast_if_present<Function>(CB.getCalledOperand()))
3214 OR << ore::NV("Callee", Callee);
3215 else
3216 OR << "the callee";
3217 return OR << " known to be "
3218 << ore::NV("Argument", IsUndef ? "undef" : "null")
3219 << " is undefined behavior; replacing with 'unreachable'.";
3220 }
3221 }
3222 llvm_unreachable("Unknown UBInfo::Kind");
3223 };
3224 A.emitRemark<OptimizationRemark>(I, "UndefinedBehavior", Remark);
3225 }
3226
3227 ChangeStatus manifest(Attributor &A) override {
3228 if (KnownUBInsts.empty())
3229 return ChangeStatus::UNCHANGED;
3230 for (const auto &[I, Info] : KnownUBInsts) {
3231 emitUBRemark(A, I, Info);
3232 A.changeToUnreachableAfterManifest(I);
3233 }
3234 return ChangeStatus::CHANGED;
3235 }
3236
3237 /// See AbstractAttribute::getAsStr()
3238 const std::string getAsStr(Attributor *A) const override {
3239 return getAssumed() ? "undefined-behavior" : "no-ub";
3240 }
3241
3242 /// Note: The correctness of this analysis depends on the fact that the
3243 /// following 2 sets will stop changing after some point.
3244 /// "Change" here means that their size changes.
3245 /// The size of each set is monotonically increasing
3246 /// (we only add items to them) and it is upper bounded by the number of
3247 /// instructions in the processed function (we can never save more
3248 /// elements in either set than this number). Hence, at some point,
3249 /// they will stop increasing.
3250 /// Consequently, at some point, both sets will have stopped
3251 /// changing, effectively making the analysis reach a fixpoint.
3252
3253 /// Note: These 2 sets are disjoint and an instruction can be considered
3254 /// one of 3 things:
3255 /// 1) Known to cause UB (AAUndefinedBehavior could prove it) and put it in
3256 /// the KnownUBInsts set.
3257 /// 2) Assumed to cause UB (in every updateImpl, AAUndefinedBehavior
3258 /// has a reason to assume it).
3259 /// 3) Assumed to not cause UB. very other instruction - AAUndefinedBehavior
3260 /// could not find a reason to assume or prove that it can cause UB,
3261 /// hence it assumes it doesn't. We have a set for these instructions
3262 /// so that we don't reprocess them in every update.
3263 /// Note however that instructions in this set may cause UB.
3264
3265protected:
3266 /// A map from all live instructions _known_ to cause UB to the reason why,
3267 /// used to build actionable optimization remarks in manifest().
3268 MapVector<Instruction *, UBInfo> KnownUBInsts;
3269
3270private:
3271 /// A set of all the (live) instructions that are assumed to _not_ cause UB.
3272 SmallPtrSet<Instruction *, 8> AssumedNoUBInsts;
3273
3274 // Should be called on updates in which if we're processing an instruction
3275 // \p I that depends on a value \p V, one of the following has to happen:
3276 // - If the value is assumed, then stop.
3277 // - If the value is known but undef, then consider it UB for \p K.
3278 // - Otherwise, do specific processing with the simplified value.
3279 // We return std::nullopt in the first 2 cases to signify that an appropriate
3280 // action was taken and the caller should stop.
3281 // Otherwise, we return the simplified value that the caller should
3282 // use for specific processing.
3283 std::optional<Value *> stopOnUndefOrAssumed(Attributor &A, Value *V,
3284 Instruction *I, UBInfo::Kind K) {
3285 bool UsedAssumedInformation = false;
3286 std::optional<Value *> SimplifiedV =
3287 A.getAssumedSimplified(IRPosition::value(*V), *this,
3288 UsedAssumedInformation, AA::Interprocedural);
3289 if (!UsedAssumedInformation) {
3290 // Don't depend on assumed values.
3291 if (!SimplifiedV) {
3292 // If it is known (which we tested above) but it doesn't have a value,
3293 // then we can assume `undef` and hence the instruction is UB.
3294 KnownUBInsts.try_emplace(I, K);
3295 return std::nullopt;
3296 }
3297 if (!*SimplifiedV)
3298 return nullptr;
3299 V = *SimplifiedV;
3300 }
3301 if (isa<UndefValue>(V)) {
3302 KnownUBInsts.try_emplace(I, K);
3303 return std::nullopt;
3304 }
3305 return V;
3306 }
3307};
3308
3309struct AAUndefinedBehaviorFunction final : AAUndefinedBehaviorImpl {
3310 AAUndefinedBehaviorFunction(const IRPosition &IRP, Attributor &A)
3311 : AAUndefinedBehaviorImpl(IRP, A) {}
3312
3313 /// See AbstractAttribute::trackStatistics()
3314 void trackStatistics() const override {
3315 STATS_DECL(UndefinedBehaviorInstruction, Instruction,
3316 "Number of instructions known to have UB");
3317 BUILD_STAT_NAME(UndefinedBehaviorInstruction, Instruction) +=
3318 KnownUBInsts.size();
3319 }
3320};
3321} // namespace
3322
3323/// ------------------------ Will-Return Attributes ----------------------------
3324
3325namespace {
3326// Helper function that checks whether a function has any cycle which we don't
3327// know if it is bounded or not.
3328// Loops with maximum trip count are considered bounded, any other cycle not.
3329static bool mayContainUnboundedCycle(Function &F, Attributor &A) {
3330 ScalarEvolution *SE =
3331 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(F);
3332 LoopInfo *LI = A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(F);
3333 // If either SCEV or LoopInfo is not available for the function then we assume
3334 // any cycle to be unbounded cycle.
3335 // We use scc_iterator which uses Tarjan algorithm to find all the maximal
3336 // SCCs.To detect if there's a cycle, we only need to find the maximal ones.
3337 if (!SE || !LI) {
3338 for (scc_iterator<Function *> SCCI = scc_begin(&F); !SCCI.isAtEnd(); ++SCCI)
3339 if (SCCI.hasCycle())
3340 return true;
3341 return false;
3342 }
3343
3344 // If there's irreducible control, the function may contain non-loop cycles.
3346 return true;
3347
3348 // Any loop that does not have a max trip count is considered unbounded cycle.
3349 for (auto *L : LI->getLoopsInPreorder()) {
3350 if (!SE->getSmallConstantMaxTripCount(L))
3351 return true;
3352 }
3353 return false;
3354}
3355
3356struct AAWillReturnImpl : public AAWillReturn {
3357 AAWillReturnImpl(const IRPosition &IRP, Attributor &A)
3358 : AAWillReturn(IRP, A) {}
3359
3360 /// See AbstractAttribute::initialize(...).
3361 void initialize(Attributor &A) override {
3362 bool IsKnown;
3364 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
3365 (void)IsKnown;
3366 }
3367
3368 /// Check for `mustprogress` and `readonly` as they imply `willreturn`.
3369 bool isImpliedByMustprogressAndReadonly(Attributor &A, bool KnownOnly) {
3370 if (!A.hasAttr(getIRPosition(), {Attribute::MustProgress}))
3371 return false;
3372
3373 bool IsKnown;
3374 if (AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown))
3375 return IsKnown || !KnownOnly;
3376 return false;
3377 }
3378
3379 /// See AbstractAttribute::updateImpl(...).
3380 ChangeStatus updateImpl(Attributor &A) override {
3381 if (isImpliedByMustprogressAndReadonly(A, /* KnownOnly */ false))
3382 return ChangeStatus::UNCHANGED;
3383
3384 auto CheckForWillReturn = [&](Instruction &I) {
3386 bool IsKnown;
3388 A, this, IPos, DepClassTy::REQUIRED, IsKnown)) {
3389 if (IsKnown)
3390 return true;
3391 } else {
3392 return false;
3393 }
3394 bool IsKnownNoRecurse;
3396 A, this, IPos, DepClassTy::REQUIRED, IsKnownNoRecurse);
3397 };
3398
3399 bool UsedAssumedInformation = false;
3400 if (!A.checkForAllCallLikeInstructions(CheckForWillReturn, *this,
3401 UsedAssumedInformation))
3402 return indicatePessimisticFixpoint();
3403
3404 auto CheckForVolatile = [&](Instruction &I) {
3405 // Volatile operations are not willreturn.
3406 return !I.isVolatile();
3407 };
3408 if (!A.checkForAllInstructions(CheckForVolatile, *this,
3409 {Instruction::Load, Instruction::Store,
3410 Instruction::AtomicCmpXchg,
3411 Instruction::AtomicRMW},
3412 UsedAssumedInformation))
3413 return indicatePessimisticFixpoint();
3414
3415 return ChangeStatus::UNCHANGED;
3416 }
3417
3418 /// See AbstractAttribute::getAsStr()
3419 const std::string getAsStr(Attributor *A) const override {
3420 return getAssumed() ? "willreturn" : "may-noreturn";
3421 }
3422};
3423
3424struct AAWillReturnFunction final : AAWillReturnImpl {
3425 AAWillReturnFunction(const IRPosition &IRP, Attributor &A)
3426 : AAWillReturnImpl(IRP, A) {}
3427
3428 /// See AbstractAttribute::initialize(...).
3429 void initialize(Attributor &A) override {
3430 AAWillReturnImpl::initialize(A);
3431
3432 Function *F = getAnchorScope();
3433 assert(F && "Did expect an anchor function");
3434 if (F->isDeclaration() || mayContainUnboundedCycle(*F, A))
3435 indicatePessimisticFixpoint();
3436 }
3437
3438 /// See AbstractAttribute::trackStatistics()
3439 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(willreturn) }
3440};
3441
3442/// WillReturn attribute deduction for a call sites.
3443struct AAWillReturnCallSite final
3444 : AACalleeToCallSite<AAWillReturn, AAWillReturnImpl> {
3445 AAWillReturnCallSite(const IRPosition &IRP, Attributor &A)
3446 : AACalleeToCallSite<AAWillReturn, AAWillReturnImpl>(IRP, A) {}
3447
3448 /// See AbstractAttribute::updateImpl(...).
3449 ChangeStatus updateImpl(Attributor &A) override {
3450 if (isImpliedByMustprogressAndReadonly(A, /* KnownOnly */ false))
3451 return ChangeStatus::UNCHANGED;
3452
3453 return AACalleeToCallSite::updateImpl(A);
3454 }
3455
3456 /// See AbstractAttribute::trackStatistics()
3457 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(willreturn); }
3458};
3459} // namespace
3460
3461/// -------------------AAIntraFnReachability Attribute--------------------------
3462
3463/// All information associated with a reachability query. This boilerplate code
3464/// is used by both AAIntraFnReachability and AAInterFnReachability, with
3465/// different \p ToTy values.
3466template <typename ToTy> struct ReachabilityQueryInfo {
3467 enum class Reachable {
3470 };
3471
3472 /// Start here,
3473 const Instruction *From = nullptr;
3474 /// reach this place,
3475 const ToTy *To = nullptr;
3476 /// without going through any of these instructions,
3478 /// and remember if it worked:
3480
3481 /// Precomputed hash for this RQI.
3482 unsigned Hash = 0;
3483
3484 unsigned computeHashValue() const {
3485 assert(Hash == 0 && "Computed hash twice!");
3488 return const_cast<ReachabilityQueryInfo<ToTy> *>(this)->Hash =
3489 detail::combineHashValue(PairDMI ::getHashValue({From, To}),
3490 InstSetDMI::getHashValue(ExclusionSet));
3491 }
3492
3494 : From(From), To(To) {}
3495
3496 /// Constructor replacement to ensure unique and stable sets are used for the
3497 /// cache.
3499 const AA::InstExclusionSetTy *ES, bool MakeUnique)
3500 : From(&From), To(&To), ExclusionSet(ES) {
3501
3502 if (!ES || ES->empty()) {
3503 ExclusionSet = nullptr;
3504 } else if (MakeUnique) {
3505 ExclusionSet = A.getInfoCache().getOrCreateUniqueBlockExecutionSet(ES);
3506 }
3507 }
3508
3511};
3512
3513namespace llvm {
3514template <typename ToTy> struct DenseMapInfo<ReachabilityQueryInfo<ToTy> *> {
3517
3518 static unsigned getHashValue(const ReachabilityQueryInfo<ToTy> *RQI) {
3519 return RQI->Hash ? RQI->Hash : RQI->computeHashValue();
3520 }
3521 static bool isEqual(const ReachabilityQueryInfo<ToTy> *LHS,
3522 const ReachabilityQueryInfo<ToTy> *RHS) {
3523 if (!PairDMI::isEqual({LHS->From, LHS->To}, {RHS->From, RHS->To}))
3524 return false;
3525 return InstSetDMI::isEqual(LHS->ExclusionSet, RHS->ExclusionSet);
3526 }
3527};
3528
3529} // namespace llvm
3530
3531namespace {
3532
3533template <typename BaseTy, typename ToTy>
3534struct CachedReachabilityAA : public BaseTy {
3535 using RQITy = ReachabilityQueryInfo<ToTy>;
3536
3537 CachedReachabilityAA(const IRPosition &IRP, Attributor &A) : BaseTy(IRP, A) {}
3538
3539 /// See AbstractAttribute::isQueryAA.
3540 bool isQueryAA() const override { return true; }
3541
3542 /// See AbstractAttribute::updateImpl(...).
3543 ChangeStatus updateImpl(Attributor &A) override {
3544 ChangeStatus Changed = ChangeStatus::UNCHANGED;
3545 for (unsigned u = 0, e = QueryVector.size(); u < e; ++u) {
3546 RQITy *RQI = QueryVector[u];
3547 if (RQI->Result == RQITy::Reachable::No &&
3548 isReachableImpl(A, *RQI, /*IsTemporaryRQI=*/false))
3549 Changed = ChangeStatus::CHANGED;
3550 }
3551 return Changed;
3552 }
3553
3554 virtual bool isReachableImpl(Attributor &A, RQITy &RQI,
3555 bool IsTemporaryRQI) = 0;
3556
3557 bool rememberResult(Attributor &A, typename RQITy::Reachable Result,
3558 RQITy &RQI, bool UsedExclusionSet, bool IsTemporaryRQI) {
3559 RQI.Result = Result;
3560
3561 // Remove the temporary RQI from the cache.
3562 if (IsTemporaryRQI)
3563 QueryCache.erase(&RQI);
3564
3565 // Insert a plain RQI (w/o exclusion set) if that makes sense. Two options:
3566 // 1) If it is reachable, it doesn't matter if we have an exclusion set for
3567 // this query. 2) We did not use the exclusion set, potentially because
3568 // there is none.
3569 if (Result == RQITy::Reachable::Yes || !UsedExclusionSet) {
3570 RQITy PlainRQI(RQI.From, RQI.To);
3571 if (!QueryCache.count(&PlainRQI)) {
3572 RQITy *RQIPtr = new (A.Allocator) RQITy(RQI.From, RQI.To);
3573 RQIPtr->Result = Result;
3574 QueryVector.push_back(RQIPtr);
3575 QueryCache.insert(RQIPtr);
3576 }
3577 }
3578
3579 // Check if we need to insert a new permanent RQI with the exclusion set.
3580 if (IsTemporaryRQI && Result != RQITy::Reachable::Yes && UsedExclusionSet) {
3581 assert((!RQI.ExclusionSet || !RQI.ExclusionSet->empty()) &&
3582 "Did not expect empty set!");
3583 RQITy *RQIPtr = new (A.Allocator)
3584 RQITy(A, *RQI.From, *RQI.To, RQI.ExclusionSet, true);
3585 assert(RQIPtr->Result == RQITy::Reachable::No && "Already reachable?");
3586 RQIPtr->Result = Result;
3587 assert(!QueryCache.count(RQIPtr));
3588 QueryVector.push_back(RQIPtr);
3589 QueryCache.insert(RQIPtr);
3590 }
3591
3592 if (Result == RQITy::Reachable::No && IsTemporaryRQI)
3593 A.registerForUpdate(*this);
3594 return Result == RQITy::Reachable::Yes;
3595 }
3596
3597 const std::string getAsStr(Attributor *A) const override {
3598 // TODO: Return the number of reachable queries.
3599 return "#queries(" + std::to_string(QueryVector.size()) + ")";
3600 }
3601
3602 bool checkQueryCache(Attributor &A, RQITy &StackRQI,
3603 typename RQITy::Reachable &Result) {
3604 if (!this->getState().isValidState()) {
3605 Result = RQITy::Reachable::Yes;
3606 return true;
3607 }
3608
3609 // If we have an exclusion set we might be able to find our answer by
3610 // ignoring it first.
3611 if (StackRQI.ExclusionSet) {
3612 RQITy PlainRQI(StackRQI.From, StackRQI.To);
3613 auto It = QueryCache.find(&PlainRQI);
3614 if (It != QueryCache.end() && (*It)->Result == RQITy::Reachable::No) {
3615 Result = RQITy::Reachable::No;
3616 return true;
3617 }
3618 }
3619
3620 auto It = QueryCache.find(&StackRQI);
3621 if (It != QueryCache.end()) {
3622 Result = (*It)->Result;
3623 return true;
3624 }
3625
3626 // Insert a temporary for recursive queries. We will replace it with a
3627 // permanent entry later.
3628 QueryCache.insert(&StackRQI);
3629 return false;
3630 }
3631
3632private:
3633 SmallVector<RQITy *> QueryVector;
3634 DenseSet<RQITy *> QueryCache;
3635};
3636
3637struct AAIntraFnReachabilityFunction final
3638 : public CachedReachabilityAA<AAIntraFnReachability, Instruction> {
3639 using Base = CachedReachabilityAA<AAIntraFnReachability, Instruction>;
3640 AAIntraFnReachabilityFunction(const IRPosition &IRP, Attributor &A)
3641 : Base(IRP, A) {
3642 DT = A.getInfoCache().getAnalysisResultForFunction<DominatorTreeAnalysis>(
3643 *IRP.getAssociatedFunction());
3644 }
3645
3646 bool isAssumedReachable(
3647 Attributor &A, const Instruction &From, const Instruction &To,
3648 const AA::InstExclusionSetTy *ExclusionSet) const override {
3649 auto *NonConstThis = const_cast<AAIntraFnReachabilityFunction *>(this);
3650 if (&From == &To)
3651 return true;
3652
3653 RQITy StackRQI(A, From, To, ExclusionSet, false);
3654 RQITy::Reachable Result;
3655 if (!NonConstThis->checkQueryCache(A, StackRQI, Result))
3656 return NonConstThis->isReachableImpl(A, StackRQI,
3657 /*IsTemporaryRQI=*/true);
3658 return Result == RQITy::Reachable::Yes;
3659 }
3660
3661 ChangeStatus updateImpl(Attributor &A) override {
3662 // We only depend on liveness. DeadEdges is all we care about, check if any
3663 // of them changed.
3664 auto *LivenessAA =
3665 A.getAAFor<AAIsDead>(*this, getIRPosition(), DepClassTy::OPTIONAL);
3666 if (LivenessAA &&
3667 llvm::all_of(DeadEdges,
3668 [&](const auto &DeadEdge) {
3669 return LivenessAA->isEdgeDead(DeadEdge.first,
3670 DeadEdge.second);
3671 }) &&
3672 llvm::all_of(DeadBlocks, [&](const BasicBlock *BB) {
3673 return LivenessAA->isAssumedDead(BB);
3674 })) {
3675 return ChangeStatus::UNCHANGED;
3676 }
3677 DeadEdges.clear();
3678 DeadBlocks.clear();
3679 return Base::updateImpl(A);
3680 }
3681
3682 bool isReachableImpl(Attributor &A, RQITy &RQI,
3683 bool IsTemporaryRQI) override {
3684 const Instruction *Origin = RQI.From;
3685 bool UsedExclusionSet = false;
3686
3687 auto WillReachInBlock = [&](const Instruction &From, const Instruction &To,
3688 const AA::InstExclusionSetTy *ExclusionSet) {
3689 const Instruction *IP = &From;
3690 while (IP && IP != &To) {
3691 if (ExclusionSet && IP != Origin && ExclusionSet->count(IP)) {
3692 UsedExclusionSet = true;
3693 break;
3694 }
3695 IP = IP->getNextNode();
3696 }
3697 return IP == &To;
3698 };
3699
3700 const BasicBlock *FromBB = RQI.From->getParent();
3701 const BasicBlock *ToBB = RQI.To->getParent();
3702 assert(FromBB->getParent() == ToBB->getParent() &&
3703 "Not an intra-procedural query!");
3704
3705 // Check intra-block reachability, however, other reaching paths are still
3706 // possible.
3707 if (FromBB == ToBB &&
3708 WillReachInBlock(*RQI.From, *RQI.To, RQI.ExclusionSet))
3709 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
3710 IsTemporaryRQI);
3711
3712 // Check if reaching the ToBB block is sufficient or if even that would not
3713 // ensure reaching the target. In the latter case we are done.
3714 if (!WillReachInBlock(ToBB->front(), *RQI.To, RQI.ExclusionSet))
3715 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
3716 IsTemporaryRQI);
3717
3718 const Function *Fn = FromBB->getParent();
3719 SmallPtrSet<const BasicBlock *, 16> ExclusionBlocks;
3720 if (RQI.ExclusionSet)
3721 for (auto *I : *RQI.ExclusionSet)
3722 if (I->getFunction() == Fn)
3723 ExclusionBlocks.insert(I->getParent());
3724
3725 // Check if we make it out of the FromBB block at all.
3726 if (ExclusionBlocks.count(FromBB) &&
3727 !WillReachInBlock(*RQI.From, *FromBB->getTerminator(),
3728 RQI.ExclusionSet))
3729 return rememberResult(A, RQITy::Reachable::No, RQI, true, IsTemporaryRQI);
3730
3731 auto *LivenessAA =
3732 A.getAAFor<AAIsDead>(*this, getIRPosition(), DepClassTy::OPTIONAL);
3733 if (LivenessAA && LivenessAA->isAssumedDead(ToBB)) {
3734 DeadBlocks.insert(ToBB);
3735 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
3736 IsTemporaryRQI);
3737 }
3738
3739 SmallPtrSet<const BasicBlock *, 16> Visited;
3741 Worklist.push_back(FromBB);
3742
3743 DenseSet<std::pair<const BasicBlock *, const BasicBlock *>> LocalDeadEdges;
3744 while (!Worklist.empty()) {
3745 const BasicBlock *BB = Worklist.pop_back_val();
3746 if (!Visited.insert(BB).second)
3747 continue;
3748 for (const BasicBlock *SuccBB : successors(BB)) {
3749 if (LivenessAA && LivenessAA->isEdgeDead(BB, SuccBB)) {
3750 LocalDeadEdges.insert({BB, SuccBB});
3751 continue;
3752 }
3753 // We checked before if we just need to reach the ToBB block.
3754 if (SuccBB == ToBB)
3755 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
3756 IsTemporaryRQI);
3757 if (DT && ExclusionBlocks.empty() && DT->dominates(BB, ToBB))
3758 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
3759 IsTemporaryRQI);
3760
3761 if (ExclusionBlocks.count(SuccBB)) {
3762 UsedExclusionSet = true;
3763 continue;
3764 }
3765 Worklist.push_back(SuccBB);
3766 }
3767 }
3768
3769 DeadEdges.insert_range(LocalDeadEdges);
3770 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
3771 IsTemporaryRQI);
3772 }
3773
3774 /// See AbstractAttribute::trackStatistics()
3775 void trackStatistics() const override {}
3776
3777private:
3778 // Set of assumed dead blocks we used in the last query. If any changes we
3779 // update the state.
3780 DenseSet<const BasicBlock *> DeadBlocks;
3781
3782 // Set of assumed dead edges we used in the last query. If any changes we
3783 // update the state.
3784 DenseSet<std::pair<const BasicBlock *, const BasicBlock *>> DeadEdges;
3785
3786 /// The dominator tree of the function to short-circuit reasoning.
3787 const DominatorTree *DT = nullptr;
3788};
3789} // namespace
3790
3791/// ------------------------ NoAlias Argument Attribute ------------------------
3792
3794 Attribute::AttrKind ImpliedAttributeKind,
3795 bool IgnoreSubsumingPositions) {
3796 assert(ImpliedAttributeKind == Attribute::NoAlias &&
3797 "Unexpected attribute kind");
3798 Value *Val = &IRP.getAssociatedValue();
3800 if (isa<AllocaInst>(Val))
3801 return true;
3802 } else {
3803 IgnoreSubsumingPositions = true;
3804 }
3805
3806 if (isa<UndefValue>(Val))
3807 return true;
3808
3809 if (isa<ConstantPointerNull>(Val) &&
3812 return true;
3813
3814 if (A.hasAttr(IRP, {Attribute::ByVal, Attribute::NoAlias},
3815 IgnoreSubsumingPositions, Attribute::NoAlias))
3816 return true;
3817
3818 return false;
3819}
3820
3821namespace {
3822struct AANoAliasImpl : AANoAlias {
3823 AANoAliasImpl(const IRPosition &IRP, Attributor &A) : AANoAlias(IRP, A) {
3824 assert(getAssociatedType()->isPointerTy() &&
3825 "Noalias is a pointer attribute");
3826 }
3827
3828 const std::string getAsStr(Attributor *A) const override {
3829 return getAssumed() ? "noalias" : "may-alias";
3830 }
3831};
3832
3833/// NoAlias attribute for a floating value.
3834struct AANoAliasFloating final : AANoAliasImpl {
3835 AANoAliasFloating(const IRPosition &IRP, Attributor &A)
3836 : AANoAliasImpl(IRP, A) {}
3837
3838 /// See AbstractAttribute::updateImpl(...).
3839 ChangeStatus updateImpl(Attributor &A) override {
3840 // TODO: Implement this.
3841 return indicatePessimisticFixpoint();
3842 }
3843
3844 /// See AbstractAttribute::trackStatistics()
3845 void trackStatistics() const override {
3847 }
3848};
3849
3850/// NoAlias attribute for an argument.
3851struct AANoAliasArgument final
3852 : AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl> {
3853 using Base = AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl>;
3854 AANoAliasArgument(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {}
3855
3856 /// See AbstractAttribute::update(...).
3857 ChangeStatus updateImpl(Attributor &A) override {
3858 // We have to make sure no-alias on the argument does not break
3859 // synchronization when this is a callback argument, see also [1] below.
3860 // If synchronization cannot be affected, we delegate to the base updateImpl
3861 // function, otherwise we give up for now.
3862
3863 // If the function is no-sync, no-alias cannot break synchronization.
3864 bool IsKnownNoSycn;
3866 A, this, IRPosition::function_scope(getIRPosition()),
3867 DepClassTy::OPTIONAL, IsKnownNoSycn))
3868 return Base::updateImpl(A);
3869
3870 // If the argument is read-only, no-alias cannot break synchronization.
3871 bool IsKnown;
3872 if (AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown))
3873 return Base::updateImpl(A);
3874
3875 // If the argument is never passed through callbacks, no-alias cannot break
3876 // synchronization.
3877 bool UsedAssumedInformation = false;
3878 if (A.checkForAllCallSites(
3879 [](AbstractCallSite ACS) { return !ACS.isCallbackCall(); }, *this,
3880 true, UsedAssumedInformation))
3881 return Base::updateImpl(A);
3882
3883 // TODO: add no-alias but make sure it doesn't break synchronization by
3884 // introducing fake uses. See:
3885 // [1] Compiler Optimizations for OpenMP, J. Doerfert and H. Finkel,
3886 // International Workshop on OpenMP 2018,
3887 // http://compilers.cs.uni-saarland.de/people/doerfert/par_opt18.pdf
3888
3889 return indicatePessimisticFixpoint();
3890 }
3891
3892 /// See AbstractAttribute::trackStatistics()
3893 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noalias) }
3894};
3895
3896struct AANoAliasCallSiteArgument final : AANoAliasImpl {
3897 AANoAliasCallSiteArgument(const IRPosition &IRP, Attributor &A)
3898 : AANoAliasImpl(IRP, A) {}
3899
3900 /// Determine if the underlying value may alias with the call site argument
3901 /// \p OtherArgNo of \p ICS (= the underlying call site).
3902 bool mayAliasWithArgument(Attributor &A, AAResults *&AAR,
3903 const AAMemoryBehavior &MemBehaviorAA,
3904 const CallBase &CB, unsigned OtherArgNo) {
3905 // We do not need to worry about aliasing with the underlying IRP.
3906 if (this->getCallSiteArgNo() == (int)OtherArgNo)
3907 return false;
3908
3909 // If it is not a pointer or pointer vector we do not alias.
3910 const Value *ArgOp = CB.getArgOperand(OtherArgNo);
3911 if (!ArgOp->getType()->isPtrOrPtrVectorTy())
3912 return false;
3913
3914 auto *CBArgMemBehaviorAA = A.getAAFor<AAMemoryBehavior>(
3915 *this, IRPosition::callsite_argument(CB, OtherArgNo), DepClassTy::NONE);
3916
3917 // If the argument is readnone, there is no read-write aliasing.
3918 if (CBArgMemBehaviorAA && CBArgMemBehaviorAA->isAssumedReadNone()) {
3919 A.recordDependence(*CBArgMemBehaviorAA, *this, DepClassTy::OPTIONAL);
3920 return false;
3921 }
3922
3923 // If the argument is readonly and the underlying value is readonly, there
3924 // is no read-write aliasing.
3925 bool IsReadOnly = MemBehaviorAA.isAssumedReadOnly();
3926 if (CBArgMemBehaviorAA && CBArgMemBehaviorAA->isAssumedReadOnly() &&
3927 IsReadOnly) {
3928 A.recordDependence(MemBehaviorAA, *this, DepClassTy::OPTIONAL);
3929 A.recordDependence(*CBArgMemBehaviorAA, *this, DepClassTy::OPTIONAL);
3930 return false;
3931 }
3932
3933 // We have to utilize actual alias analysis queries so we need the object.
3934 if (!AAR)
3935 AAR = A.getInfoCache().getAnalysisResultForFunction<AAManager>(
3936 *getAnchorScope());
3937
3938 // Try to rule it out at the call site.
3939 bool IsAliasing = !AAR || !AAR->isNoAlias(&getAssociatedValue(), ArgOp);
3940 LLVM_DEBUG(dbgs() << "[NoAliasCSArg] Check alias between "
3941 "callsite arguments: "
3942 << getAssociatedValue() << " " << *ArgOp << " => "
3943 << (IsAliasing ? "" : "no-") << "alias \n");
3944
3945 return IsAliasing;
3946 }
3947
3948 bool isKnownNoAliasDueToNoAliasPreservation(
3949 Attributor &A, AAResults *&AAR, const AAMemoryBehavior &MemBehaviorAA) {
3950 // We can deduce "noalias" if the following conditions hold.
3951 // (i) Associated value is assumed to be noalias in the definition.
3952 // (ii) Associated value is assumed to be no-capture in all the uses
3953 // possibly executed before this callsite.
3954 // (iii) There is no other pointer argument which could alias with the
3955 // value.
3956
3957 const IRPosition &VIRP = IRPosition::value(getAssociatedValue());
3958 const Function *ScopeFn = VIRP.getAnchorScope();
3959 // Check whether the value is captured in the scope using AANoCapture.
3960 // Look at CFG and check only uses possibly executed before this
3961 // callsite.
3962 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
3963 Instruction *UserI = cast<Instruction>(U.getUser());
3964
3965 // If UserI is the curr instruction and there is a single potential use of
3966 // the value in UserI we allow the use.
3967 // TODO: We should inspect the operands and allow those that cannot alias
3968 // with the value.
3969 if (UserI == getCtxI() && UserI->getNumOperands() == 1)
3970 return true;
3971
3972 if (ScopeFn) {
3973 if (auto *CB = dyn_cast<CallBase>(UserI)) {
3974 if (CB->isArgOperand(&U)) {
3975
3976 unsigned ArgNo = CB->getArgOperandNo(&U);
3977
3978 bool IsKnownNoCapture;
3980 A, this, IRPosition::callsite_argument(*CB, ArgNo),
3981 DepClassTy::OPTIONAL, IsKnownNoCapture))
3982 return true;
3983 }
3984 }
3985
3987 A, *UserI, *getCtxI(), *this, /* ExclusionSet */ nullptr,
3988 [ScopeFn](const Function &Fn) { return &Fn != ScopeFn; }))
3989 return true;
3990 }
3991
3992 // TODO: We should track the capturing uses in AANoCapture but the problem
3993 // is CGSCC runs. For those we would need to "allow" AANoCapture for
3994 // a value in the module slice.
3995 // TODO(captures): Make this more precise.
3996 UseCaptureInfo CI = DetermineUseCaptureKind(U, /*Base=*/nullptr);
3997 if (capturesNothing(CI))
3998 return true;
3999 if (CI.isPassthrough()) {
4000 Follow = true;
4001 return true;
4002 }
4003 LLVM_DEBUG(dbgs() << "[AANoAliasCSArg] Unknown user: " << *UserI << "\n");
4004 return false;
4005 };
4006
4007 bool IsKnownNoCapture;
4008 const AANoCapture *NoCaptureAA = nullptr;
4009 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
4010 A, this, VIRP, DepClassTy::NONE, IsKnownNoCapture, false, &NoCaptureAA);
4011 if (!IsAssumedNoCapture &&
4012 (!NoCaptureAA || !NoCaptureAA->isAssumedNoCaptureMaybeReturned())) {
4013 if (!A.checkForAllUses(UsePred, *this, getAssociatedValue())) {
4014 LLVM_DEBUG(
4015 dbgs() << "[AANoAliasCSArg] " << getAssociatedValue()
4016 << " cannot be noalias as it is potentially captured\n");
4017 return false;
4018 }
4019 }
4020 if (NoCaptureAA)
4021 A.recordDependence(*NoCaptureAA, *this, DepClassTy::OPTIONAL);
4022
4023 // Check there is no other pointer argument which could alias with the
4024 // value passed at this call site.
4025 // TODO: AbstractCallSite
4026 const auto &CB = cast<CallBase>(getAnchorValue());
4027 for (unsigned OtherArgNo = 0; OtherArgNo < CB.arg_size(); OtherArgNo++)
4028 if (mayAliasWithArgument(A, AAR, MemBehaviorAA, CB, OtherArgNo))
4029 return false;
4030
4031 return true;
4032 }
4033
4034 /// See AbstractAttribute::updateImpl(...).
4035 ChangeStatus updateImpl(Attributor &A) override {
4036 // If the argument is readnone we are done as there are no accesses via the
4037 // argument.
4038 auto *MemBehaviorAA =
4039 A.getAAFor<AAMemoryBehavior>(*this, getIRPosition(), DepClassTy::NONE);
4040 if (MemBehaviorAA && MemBehaviorAA->isAssumedReadNone()) {
4041 A.recordDependence(*MemBehaviorAA, *this, DepClassTy::OPTIONAL);
4042 return ChangeStatus::UNCHANGED;
4043 }
4044
4045 bool IsKnownNoAlias;
4046 const IRPosition &VIRP = IRPosition::value(getAssociatedValue());
4048 A, this, VIRP, DepClassTy::REQUIRED, IsKnownNoAlias)) {
4049 LLVM_DEBUG(dbgs() << "[AANoAlias] " << getAssociatedValue()
4050 << " is not no-alias at the definition\n");
4051 return indicatePessimisticFixpoint();
4052 }
4053
4054 AAResults *AAR = nullptr;
4055 if (MemBehaviorAA &&
4056 isKnownNoAliasDueToNoAliasPreservation(A, AAR, *MemBehaviorAA)) {
4057 LLVM_DEBUG(
4058 dbgs() << "[AANoAlias] No-Alias deduced via no-alias preservation\n");
4059 return ChangeStatus::UNCHANGED;
4060 }
4061
4062 return indicatePessimisticFixpoint();
4063 }
4064
4065 /// See AbstractAttribute::trackStatistics()
4066 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(noalias) }
4067};
4068
4069/// NoAlias attribute for function return value.
4070struct AANoAliasReturned final : AANoAliasImpl {
4071 AANoAliasReturned(const IRPosition &IRP, Attributor &A)
4072 : AANoAliasImpl(IRP, A) {}
4073
4074 /// See AbstractAttribute::updateImpl(...).
4075 ChangeStatus updateImpl(Attributor &A) override {
4076
4077 auto CheckReturnValue = [&](Value &RV) -> bool {
4078 if (Constant *C = dyn_cast<Constant>(&RV))
4079 if (C->isNullValue() || isa<UndefValue>(C))
4080 return true;
4081
4082 /// For now, we can only deduce noalias if we have call sites.
4083 /// FIXME: add more support.
4084 if (!isa<CallBase>(&RV))
4085 return false;
4086
4087 const IRPosition &RVPos = IRPosition::value(RV);
4088 bool IsKnownNoAlias;
4090 A, this, RVPos, DepClassTy::REQUIRED, IsKnownNoAlias))
4091 return false;
4092
4093 bool IsKnownNoCapture;
4094 const AANoCapture *NoCaptureAA = nullptr;
4095 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
4096 A, this, RVPos, DepClassTy::REQUIRED, IsKnownNoCapture, false,
4097 &NoCaptureAA);
4098 return IsAssumedNoCapture ||
4099 (NoCaptureAA && NoCaptureAA->isAssumedNoCaptureMaybeReturned());
4100 };
4101
4102 if (!A.checkForAllReturnedValues(CheckReturnValue, *this))
4103 return indicatePessimisticFixpoint();
4104
4105 return ChangeStatus::UNCHANGED;
4106 }
4107
4108 /// See AbstractAttribute::trackStatistics()
4109 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noalias) }
4110};
4111
4112/// NoAlias attribute deduction for a call site return value.
4113struct AANoAliasCallSiteReturned final
4114 : AACalleeToCallSite<AANoAlias, AANoAliasImpl> {
4115 AANoAliasCallSiteReturned(const IRPosition &IRP, Attributor &A)
4116 : AACalleeToCallSite<AANoAlias, AANoAliasImpl>(IRP, A) {}
4117
4118 /// See AbstractAttribute::trackStatistics()
4119 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(noalias); }
4120};
4121} // namespace
4122
4123/// -------------------AAIsDead Function Attribute-----------------------
4124
4125namespace {
4126struct AAIsDeadValueImpl : public AAIsDead {
4127 AAIsDeadValueImpl(const IRPosition &IRP, Attributor &A) : AAIsDead(IRP, A) {}
4128
4129 /// See AAIsDead::isAssumedDead().
4130 bool isAssumedDead() const override { return isAssumed(IS_DEAD); }
4131
4132 /// See AAIsDead::isKnownDead().
4133 bool isKnownDead() const override { return isKnown(IS_DEAD); }
4134
4135 /// See AAIsDead::isAssumedDead(BasicBlock *).
4136 bool isAssumedDead(const BasicBlock *BB) const override { return false; }
4137
4138 /// See AAIsDead::isKnownDead(BasicBlock *).
4139 bool isKnownDead(const BasicBlock *BB) const override { return false; }
4140
4141 /// See AAIsDead::isAssumedDead(Instruction *I).
4142 bool isAssumedDead(const Instruction *I) const override {
4143 return I == getCtxI() && isAssumedDead();
4144 }
4145
4146 /// See AAIsDead::isKnownDead(Instruction *I).
4147 bool isKnownDead(const Instruction *I) const override {
4148 return isAssumedDead(I) && isKnownDead();
4149 }
4150
4151 /// See AbstractAttribute::getAsStr().
4152 const std::string getAsStr(Attributor *A) const override {
4153 return isAssumedDead() ? "assumed-dead" : "assumed-live";
4154 }
4155
4156 /// Check if all uses are assumed dead.
4157 bool areAllUsesAssumedDead(Attributor &A, Value &V) {
4158 // Callers might not check the type, void has no uses.
4159 if (V.getType()->isVoidTy() || V.use_empty())
4160 return true;
4161
4162 // If we replace a value with a constant there are no uses left afterwards.
4163 if (!isa<Constant>(V)) {
4164 if (auto *I = dyn_cast<Instruction>(&V))
4165 if (!A.isRunOn(*I->getFunction()))
4166 return false;
4167 bool UsedAssumedInformation = false;
4168 std::optional<Constant *> C =
4169 A.getAssumedConstant(V, *this, UsedAssumedInformation);
4170 if (!C || *C)
4171 return true;
4172 }
4173
4174 auto UsePred = [&](const Use &U, bool &Follow) { return false; };
4175 // Explicitly set the dependence class to required because we want a long
4176 // chain of N dependent instructions to be considered live as soon as one is
4177 // without going through N update cycles. This is not required for
4178 // correctness.
4179 return A.checkForAllUses(UsePred, *this, V, /* CheckBBLivenessOnly */ false,
4180 DepClassTy::REQUIRED,
4181 /* IgnoreDroppableUses */ false);
4182 }
4183
4184 /// Determine if \p I is assumed to be side-effect free.
4185 bool isAssumedSideEffectFree(Attributor &A, Instruction *I) {
4187 return true;
4188
4189 if (!I->isTerminator() && !I->mayHaveSideEffects())
4190 return true;
4191
4192 auto *CB = dyn_cast<CallBase>(I);
4193 if (!CB || isa<IntrinsicInst>(CB))
4194 return false;
4195
4196 const IRPosition &CallIRP = IRPosition::callsite_function(*CB);
4197
4198 bool IsKnownNoUnwind;
4200 A, this, CallIRP, DepClassTy::OPTIONAL, IsKnownNoUnwind))
4201 return false;
4202
4203 bool IsKnown;
4204 return AA::isAssumedReadOnly(A, CallIRP, *this, IsKnown);
4205 }
4206};
4207
4208struct AAIsDeadFloating : public AAIsDeadValueImpl {
4209 AAIsDeadFloating(const IRPosition &IRP, Attributor &A)
4210 : AAIsDeadValueImpl(IRP, A) {}
4211
4212 /// See AbstractAttribute::initialize(...).
4213 void initialize(Attributor &A) override {
4214 AAIsDeadValueImpl::initialize(A);
4215
4216 if (isa<UndefValue>(getAssociatedValue())) {
4217 indicatePessimisticFixpoint();
4218 return;
4219 }
4220
4221 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
4222 if (!isAssumedSideEffectFree(A, I)) {
4224 indicatePessimisticFixpoint();
4225 else
4226 removeAssumedBits(HAS_NO_EFFECT);
4227 }
4228 }
4229
4230 bool isDeadFence(Attributor &A, FenceInst &FI) {
4231 const auto *ExecDomainAA = A.lookupAAFor<AAExecutionDomain>(
4232 IRPosition::function(*FI.getFunction()), *this, DepClassTy::NONE);
4233 if (!ExecDomainAA || !ExecDomainAA->isNoOpFence(FI))
4234 return false;
4235 A.recordDependence(*ExecDomainAA, *this, DepClassTy::OPTIONAL);
4236 return true;
4237 }
4238
4239 bool isDeadStore(Attributor &A, StoreInst &SI,
4240 SmallSetVector<Instruction *, 8> *AssumeOnlyInst = nullptr) {
4241 // Lang ref now states volatile store is not UB/dead, let's skip them.
4242 if (SI.isVolatile())
4243 return false;
4244
4245 // If we are collecting assumes to be deleted we are in the manifest stage.
4246 // It's problematic to collect the potential copies again now so we use the
4247 // cached ones.
4248 bool UsedAssumedInformation = false;
4249 if (!AssumeOnlyInst) {
4250 PotentialCopies.clear();
4251 if (!AA::getPotentialCopiesOfStoredValue(A, SI, PotentialCopies, *this,
4252 UsedAssumedInformation)) {
4253 LLVM_DEBUG(
4254 dbgs()
4255 << "[AAIsDead] Could not determine potential copies of store!\n");
4256 return false;
4257 }
4258 }
4259 LLVM_DEBUG(dbgs() << "[AAIsDead] Store has " << PotentialCopies.size()
4260 << " potential copies.\n");
4261
4262 InformationCache &InfoCache = A.getInfoCache();
4263 return llvm::all_of(PotentialCopies, [&](Value *V) {
4264 if (A.isAssumedDead(IRPosition::value(*V), this, nullptr,
4265 UsedAssumedInformation))
4266 return true;
4267 if (auto *LI = dyn_cast<LoadInst>(V)) {
4268 if (llvm::all_of(LI->uses(), [&](const Use &U) {
4269 auto &UserI = cast<Instruction>(*U.getUser());
4270 if (InfoCache.isOnlyUsedByAssume(UserI)) {
4271 if (AssumeOnlyInst)
4272 AssumeOnlyInst->insert(&UserI);
4273 return true;
4274 }
4275 return A.isAssumedDead(U, this, nullptr, UsedAssumedInformation);
4276 })) {
4277 return true;
4278 }
4279 }
4280 LLVM_DEBUG(dbgs() << "[AAIsDead] Potential copy " << *V
4281 << " is assumed live!\n");
4282 return false;
4283 });
4284 }
4285
4286 /// See AbstractAttribute::getAsStr().
4287 const std::string getAsStr(Attributor *A) const override {
4288 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
4290 if (isValidState())
4291 return "assumed-dead-store";
4293 if (isValidState())
4294 return "assumed-dead-fence";
4295 return AAIsDeadValueImpl::getAsStr(A);
4296 }
4297
4298 /// See AbstractAttribute::updateImpl(...).
4299 ChangeStatus updateImpl(Attributor &A) override {
4300 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
4301 if (auto *SI = dyn_cast_or_null<StoreInst>(I)) {
4302 if (!isDeadStore(A, *SI))
4303 return indicatePessimisticFixpoint();
4304 } else if (auto *FI = dyn_cast_or_null<FenceInst>(I)) {
4305 if (!isDeadFence(A, *FI))
4306 return indicatePessimisticFixpoint();
4307 } else {
4308 if (!isAssumedSideEffectFree(A, I))
4309 return indicatePessimisticFixpoint();
4310 if (!areAllUsesAssumedDead(A, getAssociatedValue()))
4311 return indicatePessimisticFixpoint();
4312 }
4314 }
4315
4316 bool isRemovableStore() const override {
4317 return isAssumed(IS_REMOVABLE) && isa<StoreInst>(&getAssociatedValue());
4318 }
4319
4320 /// See AbstractAttribute::manifest(...).
4321 ChangeStatus manifest(Attributor &A) override {
4322 Value &V = getAssociatedValue();
4323 if (auto *I = dyn_cast<Instruction>(&V)) {
4324 // If we get here we basically know the users are all dead. We check if
4325 // isAssumedSideEffectFree returns true here again because it might not be
4326 // the case and only the users are dead but the instruction (=call) is
4327 // still needed.
4328 if (auto *SI = dyn_cast<StoreInst>(I)) {
4329 SmallSetVector<Instruction *, 8> AssumeOnlyInst;
4330 bool IsDead = isDeadStore(A, *SI, &AssumeOnlyInst);
4331 (void)IsDead;
4332 assert(IsDead && "Store was assumed to be dead!");
4333 A.deleteAfterManifest(*I);
4334 for (size_t i = 0; i < AssumeOnlyInst.size(); ++i) {
4335 Instruction *AOI = AssumeOnlyInst[i];
4336 for (auto *Usr : AOI->users())
4337 AssumeOnlyInst.insert(cast<Instruction>(Usr));
4338 A.deleteAfterManifest(*AOI);
4339 }
4340 return ChangeStatus::CHANGED;
4341 }
4342 if (auto *FI = dyn_cast<FenceInst>(I)) {
4343 assert(isDeadFence(A, *FI));
4344 A.deleteAfterManifest(*FI);
4345 return ChangeStatus::CHANGED;
4346 }
4347 if (isAssumedSideEffectFree(A, I) && !I->isTerminator()) {
4348 A.deleteAfterManifest(*I);
4349 return ChangeStatus::CHANGED;
4350 }
4351 }
4353 }
4354
4355 /// See AbstractAttribute::trackStatistics()
4356 void trackStatistics() const override {
4358 }
4359
4360private:
4361 // The potential copies of a dead store, used for deletion during manifest.
4362 SmallSetVector<Value *, 4> PotentialCopies;
4363};
4364
4365struct AAIsDeadArgument : public AAIsDeadFloating {
4366 AAIsDeadArgument(const IRPosition &IRP, Attributor &A)
4367 : AAIsDeadFloating(IRP, A) {}
4368
4369 /// See AbstractAttribute::manifest(...).
4370 ChangeStatus manifest(Attributor &A) override {
4371 Argument &Arg = *getAssociatedArgument();
4372 if (A.isValidFunctionSignatureRewrite(Arg, /* ReplacementTypes */ {}))
4373 if (A.registerFunctionSignatureRewrite(
4374 Arg, /* ReplacementTypes */ {},
4377 return ChangeStatus::CHANGED;
4378 }
4379 return ChangeStatus::UNCHANGED;
4380 }
4381
4382 /// See AbstractAttribute::trackStatistics()
4383 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(IsDead) }
4384};
4385
4386struct AAIsDeadCallSiteArgument : public AAIsDeadValueImpl {
4387 AAIsDeadCallSiteArgument(const IRPosition &IRP, Attributor &A)
4388 : AAIsDeadValueImpl(IRP, A) {}
4389
4390 /// See AbstractAttribute::initialize(...).
4391 void initialize(Attributor &A) override {
4392 AAIsDeadValueImpl::initialize(A);
4393 if (isa<UndefValue>(getAssociatedValue()))
4394 indicatePessimisticFixpoint();
4395 }
4396
4397 /// See AbstractAttribute::updateImpl(...).
4398 ChangeStatus updateImpl(Attributor &A) override {
4399 // TODO: Once we have call site specific value information we can provide
4400 // call site specific liveness information and then it makes
4401 // sense to specialize attributes for call sites arguments instead of
4402 // redirecting requests to the callee argument.
4403 Argument *Arg = getAssociatedArgument();
4404 if (!Arg)
4405 return indicatePessimisticFixpoint();
4406 const IRPosition &ArgPos = IRPosition::argument(*Arg);
4407 auto *ArgAA = A.getAAFor<AAIsDead>(*this, ArgPos, DepClassTy::REQUIRED);
4408 if (!ArgAA)
4409 return indicatePessimisticFixpoint();
4410 return clampStateAndIndicateChange(getState(), ArgAA->getState());
4411 }
4412
4413 /// See AbstractAttribute::manifest(...).
4414 ChangeStatus manifest(Attributor &A) override {
4415 CallBase &CB = cast<CallBase>(getAnchorValue());
4416 Use &U = CB.getArgOperandUse(getCallSiteArgNo());
4417 assert(!isa<UndefValue>(U.get()) &&
4418 "Expected undef values to be filtered out!");
4419 UndefValue &UV = *UndefValue::get(U->getType());
4420 if (A.changeUseAfterManifest(U, UV))
4421 return ChangeStatus::CHANGED;
4422 return ChangeStatus::UNCHANGED;
4423 }
4424
4425 /// See AbstractAttribute::trackStatistics()
4426 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(IsDead) }
4427};
4428
4429struct AAIsDeadCallSiteReturned : public AAIsDeadFloating {
4430 AAIsDeadCallSiteReturned(const IRPosition &IRP, Attributor &A)
4431 : AAIsDeadFloating(IRP, A) {}
4432
4433 /// See AAIsDead::isAssumedDead().
4434 bool isAssumedDead() const override {
4435 return AAIsDeadFloating::isAssumedDead() && IsAssumedSideEffectFree;
4436 }
4437
4438 /// See AbstractAttribute::initialize(...).
4439 void initialize(Attributor &A) override {
4440 AAIsDeadFloating::initialize(A);
4441 if (isa<UndefValue>(getAssociatedValue())) {
4442 indicatePessimisticFixpoint();
4443 return;
4444 }
4445
4446 // We track this separately as a secondary state.
4447 IsAssumedSideEffectFree = isAssumedSideEffectFree(A, getCtxI());
4448 }
4449
4450 /// See AbstractAttribute::updateImpl(...).
4451 ChangeStatus updateImpl(Attributor &A) override {
4452 ChangeStatus Changed = ChangeStatus::UNCHANGED;
4453 if (IsAssumedSideEffectFree && !isAssumedSideEffectFree(A, getCtxI())) {
4454 IsAssumedSideEffectFree = false;
4455 Changed = ChangeStatus::CHANGED;
4456 }
4457 if (!areAllUsesAssumedDead(A, getAssociatedValue()))
4458 return indicatePessimisticFixpoint();
4459 return Changed;
4460 }
4461
4462 /// See AbstractAttribute::trackStatistics()
4463 void trackStatistics() const override {
4464 if (IsAssumedSideEffectFree)
4466 else
4467 STATS_DECLTRACK_CSRET_ATTR(UnusedResult)
4468 }
4469
4470 /// See AbstractAttribute::getAsStr().
4471 const std::string getAsStr(Attributor *A) const override {
4472 return isAssumedDead()
4473 ? "assumed-dead"
4474 : (getAssumed() ? "assumed-dead-users" : "assumed-live");
4475 }
4476
4477private:
4478 bool IsAssumedSideEffectFree = true;
4479};
4480
4481struct AAIsDeadReturned : public AAIsDeadValueImpl {
4482 AAIsDeadReturned(const IRPosition &IRP, Attributor &A)
4483 : AAIsDeadValueImpl(IRP, A) {}
4484
4485 /// See AbstractAttribute::updateImpl(...).
4486 ChangeStatus updateImpl(Attributor &A) override {
4487
4488 bool UsedAssumedInformation = false;
4489 A.checkForAllInstructions([](Instruction &) { return true; }, *this,
4490 {Instruction::Ret}, UsedAssumedInformation);
4491
4492 auto PredForCallSite = [&](AbstractCallSite ACS) {
4493 if (ACS.isCallbackCall() || !ACS.getInstruction())
4494 return false;
4495 return areAllUsesAssumedDead(A, *ACS.getInstruction());
4496 };
4497
4498 if (!A.checkForAllCallSites(PredForCallSite, *this, true,
4499 UsedAssumedInformation))
4500 return indicatePessimisticFixpoint();
4501
4502 return ChangeStatus::UNCHANGED;
4503 }
4504
4505 /// See AbstractAttribute::manifest(...).
4506 ChangeStatus manifest(Attributor &A) override {
4507 // TODO: Rewrite the signature to return void?
4508 bool AnyChange = false;
4509 UndefValue &UV = *UndefValue::get(getAssociatedFunction()->getReturnType());
4510 auto RetInstPred = [&](Instruction &I) {
4511 ReturnInst &RI = cast<ReturnInst>(I);
4513 AnyChange |= A.changeUseAfterManifest(RI.getOperandUse(0), UV);
4514 return true;
4515 };
4516 bool UsedAssumedInformation = false;
4517 A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret},
4518 UsedAssumedInformation);
4519 return AnyChange ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
4520 }
4521
4522 /// See AbstractAttribute::trackStatistics()
4523 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(IsDead) }
4524};
4525
4526struct AAIsDeadFunction : public AAIsDead {
4527 AAIsDeadFunction(const IRPosition &IRP, Attributor &A) : AAIsDead(IRP, A) {}
4528
4529 /// See AbstractAttribute::initialize(...).
4530 void initialize(Attributor &A) override {
4531 Function *F = getAnchorScope();
4532 assert(F && "Did expect an anchor function");
4533 if (!isAssumedDeadInternalFunction(A)) {
4534 ToBeExploredFrom.insert(&F->getEntryBlock().front());
4535 assumeLive(A, F->getEntryBlock());
4536 }
4537 }
4538
4539 bool isAssumedDeadInternalFunction(Attributor &A) {
4540 if (!getAnchorScope()->hasLocalLinkage())
4541 return false;
4542 // An AA that will not be updated is fixed pessimistically right after
4543 // initialization, so an assumed-dead result would be discarded. Checking
4544 // the call sites recursively initializes the liveness of every internal
4545 // caller, which in CGSCC cleanup repeats for each callee SCC.
4546 if (!A.shouldUpdateAA<AAIsDead>(getIRPosition()))
4547 return false;
4548 bool UsedAssumedInformation = false;
4549 return A.checkForAllCallSites([](AbstractCallSite) { return false; }, *this,
4550 true, UsedAssumedInformation);
4551 }
4552
4553 /// See AbstractAttribute::getAsStr().
4554 const std::string getAsStr(Attributor *A) const override {
4555 return "Live[#BB " + std::to_string(AssumedLiveBlocks.size()) + "/" +
4556 std::to_string(getAnchorScope()->size()) + "][#TBEP " +
4557 std::to_string(ToBeExploredFrom.size()) + "][#KDE " +
4558 std::to_string(KnownDeadEnds.size()) + "]";
4559 }
4560
4561 /// See AbstractAttribute::manifest(...).
4562 ChangeStatus manifest(Attributor &A) override {
4563 assert(getState().isValidState() &&
4564 "Attempted to manifest an invalid state!");
4565
4566 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
4567 Function &F = *getAnchorScope();
4568
4569 if (AssumedLiveBlocks.empty()) {
4570 A.deleteAfterManifest(F);
4571 return ChangeStatus::CHANGED;
4572 }
4573
4574 // Flag to determine if we can change an invoke to a call assuming the
4575 // callee is nounwind. This is not possible if the personality of the
4576 // function allows to catch asynchronous exceptions.
4577 bool Invoke2CallAllowed = !mayCatchAsynchronousExceptions(F);
4578
4579 KnownDeadEnds.set_union(ToBeExploredFrom);
4580 for (const Instruction *DeadEndI : KnownDeadEnds) {
4581 auto *CB = dyn_cast<CallBase>(DeadEndI);
4582 if (!CB)
4583 continue;
4584 bool IsKnownNoReturn;
4586 A, this, IRPosition::callsite_function(*CB), DepClassTy::OPTIONAL,
4587 IsKnownNoReturn);
4588 if (MayReturn && (!Invoke2CallAllowed || !isa<InvokeInst>(CB)))
4589 continue;
4590
4591 if (auto *II = dyn_cast<InvokeInst>(DeadEndI))
4592 A.registerInvokeWithDeadSuccessor(const_cast<InvokeInst &>(*II));
4593 else
4594 A.changeToUnreachableAfterManifest(
4595 const_cast<Instruction *>(DeadEndI->getNextNode()));
4596 HasChanged = ChangeStatus::CHANGED;
4597 }
4598
4599 STATS_DECL(AAIsDead, BasicBlock, "Number of dead basic blocks deleted.");
4600 for (BasicBlock &BB : F)
4601 if (!AssumedLiveBlocks.count(&BB)) {
4602 A.deleteAfterManifest(BB);
4603 ++BUILD_STAT_NAME(AAIsDead, BasicBlock);
4604 HasChanged = ChangeStatus::CHANGED;
4605 }
4606
4607 return HasChanged;
4608 }
4609
4610 /// See AbstractAttribute::updateImpl(...).
4611 ChangeStatus updateImpl(Attributor &A) override;
4612
4613 bool isEdgeDead(const BasicBlock *From, const BasicBlock *To) const override {
4614 assert(From->getParent() == getAnchorScope() &&
4615 To->getParent() == getAnchorScope() &&
4616 "Used AAIsDead of the wrong function");
4617 return isValidState() && !AssumedLiveEdges.count(std::make_pair(From, To));
4618 }
4619
4620 /// See AbstractAttribute::trackStatistics()
4621 void trackStatistics() const override {}
4622
4623 /// Returns true if the function is assumed dead.
4624 bool isAssumedDead() const override { return false; }
4625
4626 /// See AAIsDead::isKnownDead().
4627 bool isKnownDead() const override { return false; }
4628
4629 /// See AAIsDead::isAssumedDead(BasicBlock *).
4630 bool isAssumedDead(const BasicBlock *BB) const override {
4631 assert(BB->getParent() == getAnchorScope() &&
4632 "BB must be in the same anchor scope function.");
4633
4634 if (!getAssumed())
4635 return false;
4636 return !AssumedLiveBlocks.count(BB);
4637 }
4638
4639 /// See AAIsDead::isKnownDead(BasicBlock *).
4640 bool isKnownDead(const BasicBlock *BB) const override {
4641 return getKnown() && isAssumedDead(BB);
4642 }
4643
4644 /// See AAIsDead::isAssumed(Instruction *I).
4645 bool isAssumedDead(const Instruction *I) const override {
4646 assert(I->getParent()->getParent() == getAnchorScope() &&
4647 "Instruction must be in the same anchor scope function.");
4648
4649 if (!getAssumed())
4650 return false;
4651
4652 // If it is not in AssumedLiveBlocks then it for sure dead.
4653 // Otherwise, it can still be after noreturn call in a live block.
4654 if (!AssumedLiveBlocks.count(I->getParent()))
4655 return true;
4656
4657 // If it is not after a liveness barrier it is live.
4658 const Instruction *PrevI = I->getPrevNode();
4659 while (PrevI) {
4660 if (KnownDeadEnds.count(PrevI) || ToBeExploredFrom.count(PrevI))
4661 return true;
4662 PrevI = PrevI->getPrevNode();
4663 }
4664 return false;
4665 }
4666
4667 /// See AAIsDead::isKnownDead(Instruction *I).
4668 bool isKnownDead(const Instruction *I) const override {
4669 return getKnown() && isAssumedDead(I);
4670 }
4671
4672 /// Assume \p BB is (partially) live now and indicate to the Attributor \p A
4673 /// that internal function called from \p BB should now be looked at.
4674 bool assumeLive(Attributor &A, const BasicBlock &BB) {
4675 if (!AssumedLiveBlocks.insert(&BB).second)
4676 return false;
4677
4678 if (!A.isDuringDeduction())
4679 return true;
4680
4681 // We assume that all of BB is (probably) live now and if there are calls to
4682 // internal functions we will assume that those are now live as well. This
4683 // is a performance optimization for blocks with calls to a lot of internal
4684 // functions. It can however cause dead functions to be treated as live.
4685 for (const Instruction &I : BB)
4686 if (const auto *CB = dyn_cast<CallBase>(&I))
4688 if (F->hasLocalLinkage()) {
4689 LLVM_DEBUG({
4690 dbgs() << "[AAIsDead] Seeding live internal callee ";
4691 F->printAsOperand(dbgs(), /*PrintType=*/false);
4692 dbgs() << " from ";
4693 BB.getParent()->printAsOperand(dbgs(), /*PrintType=*/false);
4694 dbgs() << "\n";
4695 });
4696 A.markLiveInternalFunction(*F);
4697 }
4698 return true;
4699 }
4700
4701 /// Collection of instructions that need to be explored again, e.g., we
4702 /// did assume they do not transfer control to (one of their) successors.
4703 SmallSetVector<const Instruction *, 8> ToBeExploredFrom;
4704
4705 /// Collection of instructions that are known to not transfer control.
4706 SmallSetVector<const Instruction *, 8> KnownDeadEnds;
4707
4708 /// Collection of all assumed live edges
4709 DenseSet<std::pair<const BasicBlock *, const BasicBlock *>> AssumedLiveEdges;
4710
4711 /// Collection of all assumed live BasicBlocks.
4712 DenseSet<const BasicBlock *> AssumedLiveBlocks;
4713};
4714
4715static bool
4716identifyAliveSuccessors(Attributor &A, const CallBase &CB,
4717 AbstractAttribute &AA,
4718 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4719 const IRPosition &IPos = IRPosition::callsite_function(CB);
4720
4721 bool IsKnownNoReturn;
4723 A, &AA, IPos, DepClassTy::OPTIONAL, IsKnownNoReturn))
4724 return !IsKnownNoReturn;
4725 if (CB.isTerminator())
4726 AliveSuccessors.push_back(&CB.getSuccessor(0)->front());
4727 else
4728 AliveSuccessors.push_back(CB.getNextNode());
4729 return false;
4730}
4731
4732static bool
4733identifyAliveSuccessors(Attributor &A, const InvokeInst &II,
4734 AbstractAttribute &AA,
4735 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4736 bool UsedAssumedInformation =
4737 identifyAliveSuccessors(A, cast<CallBase>(II), AA, AliveSuccessors);
4738
4739 // First, determine if we can change an invoke to a call assuming the
4740 // callee is nounwind. This is not possible if the personality of the
4741 // function allows to catch asynchronous exceptions.
4742 if (AAIsDeadFunction::mayCatchAsynchronousExceptions(*II.getFunction())) {
4743 AliveSuccessors.push_back(&II.getUnwindDest()->front());
4744 } else {
4745 const IRPosition &IPos = IRPosition::callsite_function(II);
4746
4747 bool IsKnownNoUnwind;
4749 A, &AA, IPos, DepClassTy::OPTIONAL, IsKnownNoUnwind)) {
4750 UsedAssumedInformation |= !IsKnownNoUnwind;
4751 } else {
4752 AliveSuccessors.push_back(&II.getUnwindDest()->front());
4753 }
4754 }
4755 return UsedAssumedInformation;
4756}
4757
4758static bool
4759identifyAliveSuccessors(Attributor &, const UncondBrInst &BI,
4760 AbstractAttribute &,
4761 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4762 AliveSuccessors.push_back(&BI.getSuccessor()->front());
4763 return false;
4764}
4765
4766static bool
4767identifyAliveSuccessors(Attributor &A, const CondBrInst &BI,
4768 AbstractAttribute &AA,
4769 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4770 bool UsedAssumedInformation = false;
4771 std::optional<Constant *> C =
4772 A.getAssumedConstant(*BI.getCondition(), AA, UsedAssumedInformation);
4773 if (!C || isa_and_nonnull<UndefValue>(*C)) {
4774 // No value yet, assume both edges are dead.
4775 } else if (isa_and_nonnull<ConstantInt>(*C)) {
4776 const BasicBlock *SuccBB =
4777 BI.getSuccessor(1 - cast<ConstantInt>(*C)->getValue().getZExtValue());
4778 AliveSuccessors.push_back(&SuccBB->front());
4779 } else {
4780 AliveSuccessors.push_back(&BI.getSuccessor(0)->front());
4781 AliveSuccessors.push_back(&BI.getSuccessor(1)->front());
4782 UsedAssumedInformation = false;
4783 }
4784 return UsedAssumedInformation;
4785}
4786
4787static bool
4788identifyAliveSuccessors(Attributor &A, const SwitchInst &SI,
4789 AbstractAttribute &AA,
4790 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4791 bool UsedAssumedInformation = false;
4793 if (!A.getAssumedSimplifiedValues(IRPosition::value(*SI.getCondition()), &AA,
4795 UsedAssumedInformation)) {
4796 // Something went wrong, assume all successors are live.
4797 for (const BasicBlock *SuccBB : successors(SI.getParent()))
4798 AliveSuccessors.push_back(&SuccBB->front());
4799 return false;
4800 }
4801
4802 if (Values.empty() ||
4803 (Values.size() == 1 &&
4804 isa_and_nonnull<UndefValue>(Values.front().getValue()))) {
4805 // No valid value yet, assume all edges are dead.
4806 return UsedAssumedInformation;
4807 }
4808
4809 Type &Ty = *SI.getCondition()->getType();
4810 SmallPtrSet<ConstantInt *, 8> Constants;
4811 auto CheckForConstantInt = [&](Value *V) {
4812 if (auto *CI = dyn_cast_if_present<ConstantInt>(AA::getWithType(*V, Ty))) {
4813 Constants.insert(CI);
4814 return true;
4815 }
4816 return false;
4817 };
4818
4819 if (!all_of(Values, [&](AA::ValueAndContext &VAC) {
4820 return CheckForConstantInt(VAC.getValue());
4821 })) {
4822 for (const BasicBlock *SuccBB : successors(SI.getParent()))
4823 AliveSuccessors.push_back(&SuccBB->front());
4824 return UsedAssumedInformation;
4825 }
4826
4827 unsigned MatchedCases = 0;
4828 for (const auto &CaseIt : SI.cases()) {
4829 if (Constants.count(CaseIt.getCaseValue())) {
4830 ++MatchedCases;
4831 AliveSuccessors.push_back(&CaseIt.getCaseSuccessor()->front());
4832 }
4833 }
4834
4835 // If all potential values have been matched, we will not visit the default
4836 // case.
4837 if (MatchedCases < Constants.size())
4838 AliveSuccessors.push_back(&SI.getDefaultDest()->front());
4839 return UsedAssumedInformation;
4840}
4841
4842ChangeStatus AAIsDeadFunction::updateImpl(Attributor &A) {
4844
4845 if (AssumedLiveBlocks.empty()) {
4846 if (isAssumedDeadInternalFunction(A))
4848
4849 Function *F = getAnchorScope();
4850 ToBeExploredFrom.insert(&F->getEntryBlock().front());
4851 assumeLive(A, F->getEntryBlock());
4852 Change = ChangeStatus::CHANGED;
4853 }
4854
4855 LLVM_DEBUG(dbgs() << "[AAIsDead] Live [" << AssumedLiveBlocks.size() << "/"
4856 << getAnchorScope()->size() << "] BBs and "
4857 << ToBeExploredFrom.size() << " exploration points and "
4858 << KnownDeadEnds.size() << " known dead ends\n");
4859
4860 // Copy and clear the list of instructions we need to explore from. It is
4861 // refilled with instructions the next update has to look at.
4862 SmallVector<const Instruction *, 8> Worklist(ToBeExploredFrom.begin(),
4863 ToBeExploredFrom.end());
4864 decltype(ToBeExploredFrom) NewToBeExploredFrom;
4865
4867 while (!Worklist.empty()) {
4868 const Instruction *I = Worklist.pop_back_val();
4869 LLVM_DEBUG(dbgs() << "[AAIsDead] Exploration inst: " << *I << "\n");
4870
4871 // Fast forward for uninteresting instructions. We could look for UB here
4872 // though.
4873 while (!I->isTerminator() && !isa<CallBase>(I))
4874 I = I->getNextNode();
4875
4876 AliveSuccessors.clear();
4877
4878 bool UsedAssumedInformation = false;
4879 switch (I->getOpcode()) {
4880 // TODO: look for (assumed) UB to backwards propagate "deadness".
4881 default:
4882 assert(I->isTerminator() &&
4883 "Expected non-terminators to be handled already!");
4884 for (const BasicBlock *SuccBB : successors(I->getParent()))
4885 AliveSuccessors.push_back(&SuccBB->front());
4886 break;
4887 case Instruction::Call:
4888 UsedAssumedInformation = identifyAliveSuccessors(A, cast<CallInst>(*I),
4889 *this, AliveSuccessors);
4890 break;
4891 case Instruction::Invoke:
4892 UsedAssumedInformation = identifyAliveSuccessors(A, cast<InvokeInst>(*I),
4893 *this, AliveSuccessors);
4894 break;
4895 case Instruction::UncondBr:
4896 UsedAssumedInformation = identifyAliveSuccessors(
4897 A, cast<UncondBrInst>(*I), *this, AliveSuccessors);
4898 break;
4899 case Instruction::CondBr:
4900 UsedAssumedInformation = identifyAliveSuccessors(A, cast<CondBrInst>(*I),
4901 *this, AliveSuccessors);
4902 break;
4903 case Instruction::Switch:
4904 UsedAssumedInformation = identifyAliveSuccessors(A, cast<SwitchInst>(*I),
4905 *this, AliveSuccessors);
4906 break;
4907 }
4908
4909 if (UsedAssumedInformation) {
4910 NewToBeExploredFrom.insert(I);
4911 } else if (AliveSuccessors.empty() ||
4912 (I->isTerminator() &&
4913 AliveSuccessors.size() < I->getNumSuccessors())) {
4914 if (KnownDeadEnds.insert(I))
4915 Change = ChangeStatus::CHANGED;
4916 }
4917
4918 LLVM_DEBUG(dbgs() << "[AAIsDead] #AliveSuccessors: "
4919 << AliveSuccessors.size() << " UsedAssumedInformation: "
4920 << UsedAssumedInformation << "\n");
4921
4922 for (const Instruction *AliveSuccessor : AliveSuccessors) {
4923 if (!I->isTerminator()) {
4924 assert(AliveSuccessors.size() == 1 &&
4925 "Non-terminator expected to have a single successor!");
4926 Worklist.push_back(AliveSuccessor);
4927 } else {
4928 // record the assumed live edge
4929 auto Edge = std::make_pair(I->getParent(), AliveSuccessor->getParent());
4930 if (AssumedLiveEdges.insert(Edge).second)
4931 Change = ChangeStatus::CHANGED;
4932 if (assumeLive(A, *AliveSuccessor->getParent()))
4933 Worklist.push_back(AliveSuccessor);
4934 }
4935 }
4936 }
4937
4938 // Check if the content of ToBeExploredFrom changed, ignore the order.
4939 if (NewToBeExploredFrom.size() != ToBeExploredFrom.size() ||
4940 llvm::any_of(NewToBeExploredFrom, [&](const Instruction *I) {
4941 return !ToBeExploredFrom.count(I);
4942 })) {
4943 Change = ChangeStatus::CHANGED;
4944 ToBeExploredFrom = std::move(NewToBeExploredFrom);
4945 }
4946
4947 // If we know everything is live there is no need to query for liveness.
4948 // Instead, indicating a pessimistic fixpoint will cause the state to be
4949 // "invalid" and all queries to be answered conservatively without lookups.
4950 // To be in this state we have to (1) finished the exploration and (3) not
4951 // discovered any non-trivial dead end and (2) not ruled unreachable code
4952 // dead.
4953 if (ToBeExploredFrom.empty() &&
4954 getAnchorScope()->size() == AssumedLiveBlocks.size() &&
4955 llvm::all_of(KnownDeadEnds, [](const Instruction *DeadEndI) {
4956 return DeadEndI->isTerminator() && DeadEndI->getNumSuccessors() == 0;
4957 }))
4958 return indicatePessimisticFixpoint();
4959 return Change;
4960}
4961
4962/// Liveness information for a call sites.
4963struct AAIsDeadCallSite final : AAIsDeadFunction {
4964 AAIsDeadCallSite(const IRPosition &IRP, Attributor &A)
4965 : AAIsDeadFunction(IRP, A) {}
4966
4967 /// See AbstractAttribute::initialize(...).
4968 void initialize(Attributor &A) override {
4969 // TODO: Once we have call site specific value information we can provide
4970 // call site specific liveness information and then it makes
4971 // sense to specialize attributes for call sites instead of
4972 // redirecting requests to the callee.
4973 llvm_unreachable("Abstract attributes for liveness are not "
4974 "supported for call sites yet!");
4975 }
4976
4977 /// See AbstractAttribute::updateImpl(...).
4978 ChangeStatus updateImpl(Attributor &A) override {
4979 return indicatePessimisticFixpoint();
4980 }
4981
4982 /// See AbstractAttribute::trackStatistics()
4983 void trackStatistics() const override {}
4984};
4985} // namespace
4986
4987/// -------------------- Dereferenceable Argument Attribute --------------------
4988
4989namespace {
4990struct AADereferenceableImpl : AADereferenceable {
4991 AADereferenceableImpl(const IRPosition &IRP, Attributor &A)
4992 : AADereferenceable(IRP, A) {}
4993 using StateType = DerefState;
4994
4995 /// See AbstractAttribute::initialize(...).
4996 void initialize(Attributor &A) override {
4997 Value &V = *getAssociatedValue().stripPointerCasts();
4999 A.getAttrs(getIRPosition(),
5000 {Attribute::Dereferenceable, Attribute::DereferenceableOrNull},
5001 Attrs, /* IgnoreSubsumingPositions */ false);
5002 for (const Attribute &Attr : Attrs)
5003 takeKnownDerefBytesMaximum(Attr.getValueAsInt());
5004
5005 // Ensure we initialize the non-null AA (if necessary).
5006 bool IsKnownNonNull;
5008 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNonNull);
5009
5010 bool CanBeNull;
5011 takeKnownDerefBytesMaximum(V.getPointerDereferenceableBytes(
5012 A.getDataLayout(), CanBeNull, /*CanBeFreed=*/nullptr));
5013
5014 if (Instruction *CtxI = getCtxI())
5015 followUsesInMBEC(*this, A, getState(), *CtxI);
5016 }
5017
5018 /// See AbstractAttribute::getState()
5019 /// {
5020 StateType &getState() override { return *this; }
5021 const StateType &getState() const override { return *this; }
5022 /// }
5023
5024 /// Helper function for collecting accessed bytes in must-be-executed-context
5025 void addAccessedBytesForUse(Attributor &A, const Use *U, const Instruction *I,
5026 DerefState &State) {
5027 const Value *UseV = U->get();
5028 if (!UseV->getType()->isPointerTy())
5029 return;
5030
5031 std::optional<MemoryLocation> Loc = MemoryLocation::getOrNone(I);
5032 if (!Loc || Loc->Ptr != UseV || !Loc->Size.isPrecise() || I->isVolatile())
5033 return;
5034
5035 int64_t Offset;
5037 Loc->Ptr, Offset, A.getDataLayout(), /*AllowNonInbounds*/ true);
5038 if (Base && Base == &getAssociatedValue())
5039 State.addAccessedBytes(Offset, Loc->Size.getValue());
5040 }
5041
5042 /// See followUsesInMBEC
5043 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
5044 AADereferenceable::StateType &State) {
5045 bool IsNonNull = false;
5046 bool TrackUse = false;
5047 int64_t DerefBytes = getKnownNonNullAndDerefBytesForUse(
5048 A, *this, getAssociatedValue(), U, I, IsNonNull, TrackUse);
5049 LLVM_DEBUG(dbgs() << "[AADereferenceable] Deref bytes: " << DerefBytes
5050 << " for instruction " << *I << "\n");
5051
5052 addAccessedBytesForUse(A, U, I, State);
5053 State.takeKnownDerefBytesMaximum(DerefBytes);
5054 return TrackUse;
5055 }
5056
5057 /// See AbstractAttribute::manifest(...).
5058 ChangeStatus manifest(Attributor &A) override {
5059 ChangeStatus Change = AADereferenceable::manifest(A);
5060 bool IsKnownNonNull;
5061 bool IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>(
5062 A, this, getIRPosition(), DepClassTy::NONE, IsKnownNonNull);
5063 if (IsAssumedNonNull &&
5064 A.hasAttr(getIRPosition(), Attribute::DereferenceableOrNull)) {
5065 A.removeAttrs(getIRPosition(), {Attribute::DereferenceableOrNull});
5066 return ChangeStatus::CHANGED;
5067 }
5068 return Change;
5069 }
5070
5071 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
5072 SmallVectorImpl<Attribute> &Attrs) const override {
5073 // TODO: Add *_globally support
5074 bool IsKnownNonNull;
5075 bool IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>(
5076 A, this, getIRPosition(), DepClassTy::NONE, IsKnownNonNull);
5077 if (IsAssumedNonNull)
5078 Attrs.emplace_back(Attribute::getWithDereferenceableBytes(
5079 Ctx, getAssumedDereferenceableBytes()));
5080 else
5081 Attrs.emplace_back(Attribute::getWithDereferenceableOrNullBytes(
5082 Ctx, getAssumedDereferenceableBytes()));
5083 }
5084
5085 /// See AbstractAttribute::getAsStr().
5086 const std::string getAsStr(Attributor *A) const override {
5087 if (!getAssumedDereferenceableBytes())
5088 return "unknown-dereferenceable";
5089 bool IsKnownNonNull;
5090 bool IsAssumedNonNull = false;
5091 if (A)
5093 *A, this, getIRPosition(), DepClassTy::NONE, IsKnownNonNull);
5094 return std::string("dereferenceable") +
5095 (IsAssumedNonNull ? "" : "_or_null") +
5096 (isAssumedGlobal() ? "_globally" : "") + "<" +
5097 std::to_string(getKnownDereferenceableBytes()) + "-" +
5098 std::to_string(getAssumedDereferenceableBytes()) + ">" +
5099 (!A ? " [non-null is unknown]" : "");
5100 }
5101};
5102
5103/// Dereferenceable attribute for a floating value.
5104struct AADereferenceableFloating : AADereferenceableImpl {
5105 AADereferenceableFloating(const IRPosition &IRP, Attributor &A)
5106 : AADereferenceableImpl(IRP, A) {}
5107
5108 /// See AbstractAttribute::updateImpl(...).
5109 ChangeStatus updateImpl(Attributor &A) override {
5110 bool Stripped;
5111 bool UsedAssumedInformation = false;
5113 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
5114 AA::AnyScope, UsedAssumedInformation)) {
5115 Values.push_back({getAssociatedValue(), getCtxI()});
5116 Stripped = false;
5117 } else {
5118 Stripped = Values.size() != 1 ||
5119 Values.front().getValue() != &getAssociatedValue();
5120 }
5121
5122 const DataLayout &DL = A.getDataLayout();
5123 DerefState T;
5124
5125 auto VisitValueCB = [&](const Value &V) -> bool {
5126 unsigned IdxWidth =
5127 DL.getIndexSizeInBits(V.getType()->getPointerAddressSpace());
5128 APInt Offset(IdxWidth, 0);
5130 A, *this, &V, DL, Offset, /* GetMinOffset */ false,
5131 /* AllowNonInbounds */ true);
5132
5133 const auto *AA = A.getAAFor<AADereferenceable>(
5134 *this, IRPosition::value(*Base), DepClassTy::REQUIRED);
5135 int64_t DerefBytes = 0;
5136 if (!AA || (!Stripped && this == AA)) {
5137 // Use IR information if we did not strip anything.
5138 // TODO: track globally.
5139 bool CanBeNull;
5140 DerefBytes = Base->getPointerDereferenceableBytes(
5141 DL, CanBeNull, /*CanBeFreed=*/nullptr);
5142 T.GlobalState.indicatePessimisticFixpoint();
5143 } else {
5144 const DerefState &DS = AA->getState();
5145 DerefBytes = DS.DerefBytesState.getAssumed();
5146 T.GlobalState &= DS.GlobalState;
5147 }
5148
5149 // For now we do not try to "increase" dereferenceability due to negative
5150 // indices as we first have to come up with code to deal with loops and
5151 // for overflows of the dereferenceable bytes.
5152 int64_t OffsetSExt = Offset.getSExtValue();
5153 if (OffsetSExt < 0)
5154 OffsetSExt = 0;
5155
5156 T.takeAssumedDerefBytesMinimum(
5157 std::max(int64_t(0), DerefBytes - OffsetSExt));
5158
5159 if (this == AA) {
5160 if (!Stripped) {
5161 // If nothing was stripped IR information is all we got.
5162 T.takeKnownDerefBytesMaximum(
5163 std::max(int64_t(0), DerefBytes - OffsetSExt));
5164 T.indicatePessimisticFixpoint();
5165 } else if (OffsetSExt > 0) {
5166 // If something was stripped but there is circular reasoning we look
5167 // for the offset. If it is positive we basically decrease the
5168 // dereferenceable bytes in a circular loop now, which will simply
5169 // drive them down to the known value in a very slow way which we
5170 // can accelerate.
5171 T.indicatePessimisticFixpoint();
5172 }
5173 }
5174
5175 return T.isValidState();
5176 };
5177
5178 for (const auto &VAC : Values)
5179 if (!VisitValueCB(*VAC.getValue()))
5180 return indicatePessimisticFixpoint();
5181
5182 return clampStateAndIndicateChange(getState(), T);
5183 }
5184
5185 /// See AbstractAttribute::trackStatistics()
5186 void trackStatistics() const override {
5187 STATS_DECLTRACK_FLOATING_ATTR(dereferenceable)
5188 }
5189};
5190
5191/// Dereferenceable attribute for a return value.
5192struct AADereferenceableReturned final
5193 : AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl> {
5194 using Base =
5195 AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl>;
5196 AADereferenceableReturned(const IRPosition &IRP, Attributor &A)
5197 : Base(IRP, A) {}
5198
5199 /// See AbstractAttribute::trackStatistics()
5200 void trackStatistics() const override {
5201 STATS_DECLTRACK_FNRET_ATTR(dereferenceable)
5202 }
5203};
5204
5205/// Dereferenceable attribute for an argument
5206struct AADereferenceableArgument final
5207 : AAArgumentFromCallSiteArguments<AADereferenceable,
5208 AADereferenceableImpl> {
5209 using Base =
5210 AAArgumentFromCallSiteArguments<AADereferenceable, AADereferenceableImpl>;
5211 AADereferenceableArgument(const IRPosition &IRP, Attributor &A)
5212 : Base(IRP, A) {}
5213
5214 /// See AbstractAttribute::trackStatistics()
5215 void trackStatistics() const override {
5216 STATS_DECLTRACK_ARG_ATTR(dereferenceable)
5217 }
5218};
5219
5220/// Dereferenceable attribute for a call site argument.
5221struct AADereferenceableCallSiteArgument final : AADereferenceableFloating {
5222 AADereferenceableCallSiteArgument(const IRPosition &IRP, Attributor &A)
5223 : AADereferenceableFloating(IRP, A) {}
5224
5225 /// See AbstractAttribute::trackStatistics()
5226 void trackStatistics() const override {
5227 STATS_DECLTRACK_CSARG_ATTR(dereferenceable)
5228 }
5229};
5230
5231/// Dereferenceable attribute deduction for a call site return value.
5232struct AADereferenceableCallSiteReturned final
5233 : AACalleeToCallSite<AADereferenceable, AADereferenceableImpl> {
5234 using Base = AACalleeToCallSite<AADereferenceable, AADereferenceableImpl>;
5235 AADereferenceableCallSiteReturned(const IRPosition &IRP, Attributor &A)
5236 : Base(IRP, A) {}
5237
5238 /// See AbstractAttribute::trackStatistics()
5239 void trackStatistics() const override {
5240 STATS_DECLTRACK_CS_ATTR(dereferenceable);
5241 }
5242};
5243} // namespace
5244
5245// ------------------------ Align Argument Attribute ------------------------
5246
5247namespace {
5248
5249static unsigned getKnownAlignForUse(Attributor &A, AAAlign &QueryingAA,
5250 Value &AssociatedValue, const Use *U,
5251 const Instruction *I, bool &TrackUse) {
5252 // We need to follow common pointer manipulation uses to the accesses they
5253 // feed into.
5254 if (isa<CastInst>(I)) {
5255 // Follow all but ptr2int casts.
5256 TrackUse = !isa<PtrToIntInst>(I);
5257 return 0;
5258 }
5259 if (auto *GEP = dyn_cast<GetElementPtrInst>(I)) {
5260 if (GEP->hasAllConstantIndices())
5261 TrackUse = true;
5262 return 0;
5263 }
5264 if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(I))
5265 switch (II->getIntrinsicID()) {
5266 case Intrinsic::ptrmask: {
5267 // Is it appropriate to pull attribute in initialization?
5268 const auto *ConstVals = A.getAAFor<AAPotentialConstantValues>(
5269 QueryingAA, IRPosition::value(*II->getOperand(1)), DepClassTy::NONE);
5270 const auto *AlignAA = A.getAAFor<AAAlign>(
5271 QueryingAA, IRPosition::value(*II), DepClassTy::NONE);
5272 if (ConstVals && ConstVals->isValidState() && ConstVals->isAtFixpoint()) {
5273 unsigned ShiftValue = std::min(ConstVals->getAssumedMinTrailingZeros(),
5275 Align ConstAlign = Align::fromLog2(ShiftValue);
5276 if (ConstAlign >= AlignAA->getKnownAlign())
5277 return Align(1).value();
5278 }
5279 if (AlignAA)
5280 return AlignAA->getKnownAlign().value();
5281 break;
5282 }
5283 case Intrinsic::amdgcn_make_buffer_rsrc: {
5284 const auto *AlignAA = A.getAAFor<AAAlign>(
5285 QueryingAA, IRPosition::value(*II), DepClassTy::NONE);
5286 if (AlignAA)
5287 return AlignAA->getKnownAlign().value();
5288 break;
5289 }
5290 default:
5291 break;
5292 }
5293
5294 MaybeAlign MA;
5295 if (const auto *CB = dyn_cast<CallBase>(I)) {
5296 if (CB->isBundleOperand(U) || CB->isCallee(U))
5297 return 0;
5298
5299 unsigned ArgNo = CB->getArgOperandNo(U);
5300 IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo);
5301 // As long as we only use known information there is no need to track
5302 // dependences here.
5303 auto *AlignAA = A.getAAFor<AAAlign>(QueryingAA, IRP, DepClassTy::NONE);
5304 if (AlignAA)
5305 MA = MaybeAlign(AlignAA->getKnownAlign());
5306 }
5307
5308 const DataLayout &DL = A.getDataLayout();
5309 const Value *UseV = U->get();
5310 if (auto *SI = dyn_cast<StoreInst>(I)) {
5311 if (SI->getPointerOperand() == UseV)
5312 MA = SI->getAlign();
5313 } else if (auto *LI = dyn_cast<LoadInst>(I)) {
5314 if (LI->getPointerOperand() == UseV)
5315 MA = LI->getAlign();
5316 } else if (auto *AI = dyn_cast<AtomicRMWInst>(I)) {
5317 if (AI->getPointerOperand() == UseV)
5318 MA = AI->getAlign();
5319 } else if (auto *AI = dyn_cast<AtomicCmpXchgInst>(I)) {
5320 if (AI->getPointerOperand() == UseV)
5321 MA = AI->getAlign();
5322 }
5323
5324 if (!MA || *MA <= QueryingAA.getKnownAlign())
5325 return 0;
5326
5327 unsigned Alignment = MA->value();
5328 int64_t Offset;
5329
5330 if (const Value *Base = GetPointerBaseWithConstantOffset(UseV, Offset, DL)) {
5331 if (Base == &AssociatedValue) {
5332 // BasePointerAddr + Offset = Alignment * Q for some integer Q.
5333 // So we can say that the maximum power of two which is a divisor of
5334 // gcd(Offset, Alignment) is an alignment.
5335
5336 uint32_t gcd = std::gcd(uint32_t(abs((int32_t)Offset)), Alignment);
5338 }
5339 }
5340
5341 return Alignment;
5342}
5343
5344struct AAAlignImpl : AAAlign {
5345 AAAlignImpl(const IRPosition &IRP, Attributor &A) : AAAlign(IRP, A) {}
5346
5347 /// See AbstractAttribute::initialize(...).
5348 void initialize(Attributor &A) override {
5350 A.getAttrs(getIRPosition(), {Attribute::Alignment}, Attrs);
5351 for (const Attribute &Attr : Attrs)
5352 takeKnownMaximum(Attr.getValueAsInt());
5353
5354 Value &V = *getAssociatedValue().stripPointerCasts();
5355 takeKnownMaximum(V.getPointerAlignment(A.getDataLayout()).value());
5356
5357 if (Instruction *CtxI = getCtxI())
5358 followUsesInMBEC(*this, A, getState(), *CtxI);
5359 }
5360
5361 /// See AbstractAttribute::manifest(...).
5362 ChangeStatus manifest(Attributor &A) override {
5363 ChangeStatus InstrChanged = ChangeStatus::UNCHANGED;
5364
5365 // Check for users that allow alignment annotations.
5366 Value &AssociatedValue = getAssociatedValue();
5367 if (isa<ConstantData>(AssociatedValue))
5368 return ChangeStatus::UNCHANGED;
5369
5370 for (const Use &U : AssociatedValue.uses()) {
5371 if (auto *SI = dyn_cast<StoreInst>(U.getUser())) {
5372 if (SI->getPointerOperand() == &AssociatedValue)
5373 if (SI->getAlign() < getAssumedAlign()) {
5374 STATS_DECLTRACK(AAAlign, Store,
5375 "Number of times alignment added to a store");
5376 SI->setAlignment(getAssumedAlign());
5377 InstrChanged = ChangeStatus::CHANGED;
5378 }
5379 } else if (auto *LI = dyn_cast<LoadInst>(U.getUser())) {
5380 if (LI->getPointerOperand() == &AssociatedValue)
5381 if (LI->getAlign() < getAssumedAlign()) {
5382 LI->setAlignment(getAssumedAlign());
5383 STATS_DECLTRACK(AAAlign, Load,
5384 "Number of times alignment added to a load");
5385 InstrChanged = ChangeStatus::CHANGED;
5386 }
5387 } else if (auto *RMW = dyn_cast<AtomicRMWInst>(U.getUser())) {
5388 if (RMW->getPointerOperand() == &AssociatedValue) {
5389 if (RMW->getAlign() < getAssumedAlign()) {
5390 STATS_DECLTRACK(AAAlign, AtomicRMW,
5391 "Number of times alignment added to atomicrmw");
5392
5393 RMW->setAlignment(getAssumedAlign());
5394 InstrChanged = ChangeStatus::CHANGED;
5395 }
5396 }
5397 } else if (auto *CAS = dyn_cast<AtomicCmpXchgInst>(U.getUser())) {
5398 if (CAS->getPointerOperand() == &AssociatedValue) {
5399 if (CAS->getAlign() < getAssumedAlign()) {
5400 STATS_DECLTRACK(AAAlign, AtomicCmpXchg,
5401 "Number of times alignment added to cmpxchg");
5402 CAS->setAlignment(getAssumedAlign());
5403 InstrChanged = ChangeStatus::CHANGED;
5404 }
5405 }
5406 }
5407 }
5408
5409 ChangeStatus Changed = AAAlign::manifest(A);
5410
5411 Align InheritAlign =
5412 getAssociatedValue().getPointerAlignment(A.getDataLayout());
5413 if (InheritAlign >= getAssumedAlign())
5414 return InstrChanged;
5415 return Changed | InstrChanged;
5416 }
5417
5418 // TODO: Provide a helper to determine the implied ABI alignment and check in
5419 // the existing manifest method and a new one for AAAlignImpl that value
5420 // to avoid making the alignment explicit if it did not improve.
5421
5422 /// See AbstractAttribute::getDeducedAttributes
5423 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
5424 SmallVectorImpl<Attribute> &Attrs) const override {
5425 if (getAssumedAlign() > 1)
5426 Attrs.emplace_back(
5427 Attribute::getWithAlignment(Ctx, Align(getAssumedAlign())));
5428 }
5429
5430 /// See followUsesInMBEC
5431 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
5432 AAAlign::StateType &State) {
5433 bool TrackUse = false;
5434
5435 unsigned int KnownAlign =
5436 getKnownAlignForUse(A, *this, getAssociatedValue(), U, I, TrackUse);
5437 State.takeKnownMaximum(KnownAlign);
5438
5439 return TrackUse;
5440 }
5441
5442 /// See AbstractAttribute::getAsStr().
5443 const std::string getAsStr(Attributor *A) const override {
5444 return "align<" + std::to_string(getKnownAlign().value()) + "-" +
5445 std::to_string(getAssumedAlign().value()) + ">";
5446 }
5447};
5448
5449/// Align attribute for a floating value.
5450struct AAAlignFloating : AAAlignImpl {
5451 AAAlignFloating(const IRPosition &IRP, Attributor &A) : AAAlignImpl(IRP, A) {}
5452
5453 /// See AbstractAttribute::updateImpl(...).
5454 ChangeStatus updateImpl(Attributor &A) override {
5455 const DataLayout &DL = A.getDataLayout();
5456
5457 bool Stripped;
5458 bool UsedAssumedInformation = false;
5460 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
5461 AA::AnyScope, UsedAssumedInformation)) {
5462 Values.push_back({getAssociatedValue(), getCtxI()});
5463 Stripped = false;
5464 } else {
5465 Stripped = Values.size() != 1 ||
5466 Values.front().getValue() != &getAssociatedValue();
5467 }
5468
5469 StateType T;
5470 auto VisitValueCB = [&](Value &V) -> bool {
5472 return true;
5473 const auto *AA = A.getAAFor<AAAlign>(*this, IRPosition::value(V),
5474 DepClassTy::REQUIRED);
5475 if (!AA || (!Stripped && this == AA)) {
5476 int64_t Offset;
5477 unsigned Alignment = 1;
5478 if (const Value *Base =
5480 // TODO: Use AAAlign for the base too.
5481 Align PA = Base->getPointerAlignment(DL);
5482 // BasePointerAddr + Offset = Alignment * Q for some integer Q.
5483 // So we can say that the maximum power of two which is a divisor of
5484 // gcd(Offset, Alignment) is an alignment.
5485
5486 uint32_t gcd =
5487 std::gcd(uint32_t(abs((int32_t)Offset)), uint32_t(PA.value()));
5489 } else {
5490 Alignment = V.getPointerAlignment(DL).value();
5491 }
5492 // Use only IR information if we did not strip anything.
5493 T.takeKnownMaximum(Alignment);
5494 T.indicatePessimisticFixpoint();
5495 } else {
5496 // Use abstract attribute information.
5497 const AAAlign::StateType &DS = AA->getState();
5498 T ^= DS;
5499 }
5500 return T.isValidState();
5501 };
5502
5503 for (const auto &VAC : Values) {
5504 if (!VisitValueCB(*VAC.getValue()))
5505 return indicatePessimisticFixpoint();
5506 }
5507
5508 // TODO: If we know we visited all incoming values, thus no are assumed
5509 // dead, we can take the known information from the state T.
5510 return clampStateAndIndicateChange(getState(), T);
5511 }
5512
5513 /// See AbstractAttribute::trackStatistics()
5514 void trackStatistics() const override { STATS_DECLTRACK_FLOATING_ATTR(align) }
5515};
5516
5517/// Align attribute for function return value.
5518struct AAAlignReturned final
5519 : AAReturnedFromReturnedValues<AAAlign, AAAlignImpl> {
5520 using Base = AAReturnedFromReturnedValues<AAAlign, AAAlignImpl>;
5521 AAAlignReturned(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {}
5522
5523 /// See AbstractAttribute::trackStatistics()
5524 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(aligned) }
5525};
5526
5527/// Align attribute for function argument.
5528struct AAAlignArgument final
5529 : AAArgumentFromCallSiteArguments<AAAlign, AAAlignImpl> {
5530 using Base = AAArgumentFromCallSiteArguments<AAAlign, AAAlignImpl>;
5531 AAAlignArgument(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {}
5532
5533 /// See AbstractAttribute::manifest(...).
5534 ChangeStatus manifest(Attributor &A) override {
5535 // If the associated argument is involved in a must-tail call we give up
5536 // because we would need to keep the argument alignments of caller and
5537 // callee in-sync. Just does not seem worth the trouble right now.
5538 if (A.getInfoCache().isInvolvedInMustTailCall(*getAssociatedArgument()))
5539 return ChangeStatus::UNCHANGED;
5540 return Base::manifest(A);
5541 }
5542
5543 /// See AbstractAttribute::trackStatistics()
5544 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(aligned) }
5545};
5546
5547struct AAAlignCallSiteArgument final : AAAlignFloating {
5548 AAAlignCallSiteArgument(const IRPosition &IRP, Attributor &A)
5549 : AAAlignFloating(IRP, A) {}
5550
5551 /// See AbstractAttribute::manifest(...).
5552 ChangeStatus manifest(Attributor &A) override {
5553 // If the associated argument is involved in a must-tail call we give up
5554 // because we would need to keep the argument alignments of caller and
5555 // callee in-sync. Just does not seem worth the trouble right now.
5556 if (Argument *Arg = getAssociatedArgument())
5557 if (A.getInfoCache().isInvolvedInMustTailCall(*Arg))
5558 return ChangeStatus::UNCHANGED;
5559 ChangeStatus Changed = AAAlignImpl::manifest(A);
5560 Align InheritAlign =
5561 getAssociatedValue().getPointerAlignment(A.getDataLayout());
5562 if (InheritAlign >= getAssumedAlign())
5563 Changed = ChangeStatus::UNCHANGED;
5564 return Changed;
5565 }
5566
5567 /// See AbstractAttribute::updateImpl(Attributor &A).
5568 ChangeStatus updateImpl(Attributor &A) override {
5569 ChangeStatus Changed = AAAlignFloating::updateImpl(A);
5570 if (Argument *Arg = getAssociatedArgument()) {
5571 // We only take known information from the argument
5572 // so we do not need to track a dependence.
5573 const auto *ArgAlignAA = A.getAAFor<AAAlign>(
5574 *this, IRPosition::argument(*Arg), DepClassTy::NONE);
5575 if (ArgAlignAA)
5576 takeKnownMaximum(ArgAlignAA->getKnownAlign().value());
5577 }
5578 return Changed;
5579 }
5580
5581 /// See AbstractAttribute::trackStatistics()
5582 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(aligned) }
5583};
5584
5585/// Align attribute deduction for a call site return value.
5586struct AAAlignCallSiteReturned final
5587 : AACalleeToCallSite<AAAlign, AAAlignImpl> {
5588 using Base = AACalleeToCallSite<AAAlign, AAAlignImpl>;
5589 AAAlignCallSiteReturned(const IRPosition &IRP, Attributor &A)
5590 : Base(IRP, A) {}
5591
5592 ChangeStatus updateImpl(Attributor &A) override {
5593 Instruction *I = getIRPosition().getCtxI();
5594 if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) {
5595 switch (II->getIntrinsicID()) {
5596 case Intrinsic::ptrmask: {
5598 bool Valid = false;
5599
5600 const auto *ConstVals = A.getAAFor<AAPotentialConstantValues>(
5601 *this, IRPosition::value(*II->getOperand(1)), DepClassTy::REQUIRED);
5602 if (ConstVals && ConstVals->isValidState()) {
5603 unsigned ShiftValue =
5604 std::min(ConstVals->getAssumedMinTrailingZeros(),
5605 Value::MaxAlignmentExponent);
5606 Alignment = Align::fromLog2(ShiftValue);
5607 Valid = true;
5608 }
5609
5610 const auto *AlignAA =
5611 A.getAAFor<AAAlign>(*this, IRPosition::value(*(II->getOperand(0))),
5612 DepClassTy::REQUIRED);
5613 if (AlignAA) {
5614 Alignment = std::max(AlignAA->getAssumedAlign(), Alignment);
5615 Valid = true;
5616 }
5617
5618 if (Valid)
5620 this->getState(),
5621 std::min(this->getAssumedAlign(), Alignment).value());
5622 break;
5623 }
5624 // FIXME: Should introduce target specific sub-attributes and letting
5625 // getAAfor<AAAlign> lead to create sub-attribute to handle target
5626 // specific intrinsics.
5627 case Intrinsic::amdgcn_make_buffer_rsrc: {
5628 const auto *AlignAA =
5629 A.getAAFor<AAAlign>(*this, IRPosition::value(*(II->getOperand(0))),
5630 DepClassTy::REQUIRED);
5631 if (AlignAA)
5633 this->getState(), AlignAA->getAssumedAlign().value());
5634 break;
5635 }
5636 default:
5637 break;
5638 }
5639 }
5640 return Base::updateImpl(A);
5641 };
5642 /// See AbstractAttribute::trackStatistics()
5643 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(align); }
5644};
5645} // namespace
5646
5647/// ------------------ Function No-Return Attribute ----------------------------
5648namespace {
5649struct AANoReturnImpl : public AANoReturn {
5650 AANoReturnImpl(const IRPosition &IRP, Attributor &A) : AANoReturn(IRP, A) {}
5651
5652 /// See AbstractAttribute::initialize(...).
5653 void initialize(Attributor &A) override {
5654 bool IsKnown;
5656 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
5657 (void)IsKnown;
5658 }
5659
5660 /// See AbstractAttribute::getAsStr().
5661 const std::string getAsStr(Attributor *A) const override {
5662 return getAssumed() ? "noreturn" : "may-return";
5663 }
5664
5665 /// See AbstractAttribute::updateImpl(Attributor &A).
5666 ChangeStatus updateImpl(Attributor &A) override {
5667 auto CheckForNoReturn = [](Instruction &) { return false; };
5668 bool UsedAssumedInformation = false;
5669 if (!A.checkForAllInstructions(CheckForNoReturn, *this,
5670 {(unsigned)Instruction::Ret},
5671 UsedAssumedInformation))
5672 return indicatePessimisticFixpoint();
5673 return ChangeStatus::UNCHANGED;
5674 }
5675};
5676
5677struct AANoReturnFunction final : AANoReturnImpl {
5678 AANoReturnFunction(const IRPosition &IRP, Attributor &A)
5679 : AANoReturnImpl(IRP, A) {}
5680
5681 /// See AbstractAttribute::trackStatistics()
5682 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(noreturn) }
5683};
5684
5685/// NoReturn attribute deduction for a call sites.
5686struct AANoReturnCallSite final
5687 : AACalleeToCallSite<AANoReturn, AANoReturnImpl> {
5688 AANoReturnCallSite(const IRPosition &IRP, Attributor &A)
5689 : AACalleeToCallSite<AANoReturn, AANoReturnImpl>(IRP, A) {}
5690
5691 /// See AbstractAttribute::trackStatistics()
5692 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(noreturn); }
5693};
5694} // namespace
5695
5696/// ----------------------- Instance Info ---------------------------------
5697
5698namespace {
5699/// A class to hold the state of for no-capture attributes.
5700struct AAInstanceInfoImpl : public AAInstanceInfo {
5701 AAInstanceInfoImpl(const IRPosition &IRP, Attributor &A)
5702 : AAInstanceInfo(IRP, A) {}
5703
5704 /// See AbstractAttribute::initialize(...).
5705 void initialize(Attributor &A) override {
5706 Value &V = getAssociatedValue();
5707 if (auto *C = dyn_cast<Constant>(&V)) {
5708 if (C->isThreadDependent())
5709 indicatePessimisticFixpoint();
5710 else
5711 indicateOptimisticFixpoint();
5712 return;
5713 }
5714 if (auto *CB = dyn_cast<CallBase>(&V))
5715 if (CB->arg_size() == 0 && !CB->mayHaveSideEffects() &&
5716 !CB->mayReadFromMemory()) {
5717 indicateOptimisticFixpoint();
5718 return;
5719 }
5720 if (auto *I = dyn_cast<Instruction>(&V)) {
5721 const auto *CI =
5722 A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>(
5723 *I->getFunction());
5724 if (mayBeInCycle(CI, I, /* HeaderOnly */ false)) {
5725 indicatePessimisticFixpoint();
5726 return;
5727 }
5728 }
5729 }
5730
5731 /// See AbstractAttribute::updateImpl(...).
5732 ChangeStatus updateImpl(Attributor &A) override {
5733 ChangeStatus Changed = ChangeStatus::UNCHANGED;
5734
5735 Value &V = getAssociatedValue();
5736 const Function *Scope = nullptr;
5737 if (auto *I = dyn_cast<Instruction>(&V))
5738 Scope = I->getFunction();
5739 if (auto *A = dyn_cast<Argument>(&V)) {
5740 Scope = A->getParent();
5741 if (!Scope->hasLocalLinkage())
5742 return Changed;
5743 }
5744 if (!Scope)
5745 return indicateOptimisticFixpoint();
5746
5747 bool IsKnownNoRecurse;
5749 A, this, IRPosition::function(*Scope), DepClassTy::OPTIONAL,
5750 IsKnownNoRecurse))
5751 return Changed;
5752
5753 auto UsePred = [&](const Use &U, bool &Follow) {
5754 const Instruction *UserI = dyn_cast<Instruction>(U.getUser());
5755 if (!UserI || isa<GetElementPtrInst>(UserI) || isa<CastInst>(UserI) ||
5756 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) {
5757 Follow = true;
5758 return true;
5759 }
5760 if (isa<LoadInst>(UserI) || isa<CmpInst>(UserI) ||
5761 (isa<StoreInst>(UserI) &&
5762 cast<StoreInst>(UserI)->getValueOperand() != U.get()))
5763 return true;
5764 if (auto *CB = dyn_cast<CallBase>(UserI)) {
5765 // This check is not guaranteeing uniqueness but for now that we cannot
5766 // end up with two versions of \p U thinking it was one.
5768 if (!Callee || !Callee->hasLocalLinkage())
5769 return true;
5770 if (!CB->isArgOperand(&U))
5771 return false;
5772 const auto *ArgInstanceInfoAA = A.getAAFor<AAInstanceInfo>(
5774 DepClassTy::OPTIONAL);
5775 if (!ArgInstanceInfoAA ||
5776 !ArgInstanceInfoAA->isAssumedUniqueForAnalysis())
5777 return false;
5778 // If this call base might reach the scope again we might forward the
5779 // argument back here. This is very conservative.
5781 A, *CB, *Scope, *this, /* ExclusionSet */ nullptr,
5782 [Scope](const Function &Fn) { return &Fn != Scope; }))
5783 return false;
5784 return true;
5785 }
5786 return false;
5787 };
5788
5789 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) {
5790 if (auto *SI = dyn_cast<StoreInst>(OldU.getUser())) {
5791 auto *Ptr = SI->getPointerOperand()->stripPointerCasts();
5792 if ((isa<AllocaInst>(Ptr) || isNoAliasCall(Ptr)) &&
5793 AA::isDynamicallyUnique(A, *this, *Ptr))
5794 return true;
5795 }
5796 return false;
5797 };
5798
5799 if (!A.checkForAllUses(UsePred, *this, V, /* CheckBBLivenessOnly */ true,
5800 DepClassTy::OPTIONAL,
5801 /* IgnoreDroppableUses */ true, EquivalentUseCB))
5802 return indicatePessimisticFixpoint();
5803
5804 return Changed;
5805 }
5806
5807 /// See AbstractState::getAsStr().
5808 const std::string getAsStr(Attributor *A) const override {
5809 return isAssumedUniqueForAnalysis() ? "<unique [fAa]>" : "<unknown>";
5810 }
5811
5812 /// See AbstractAttribute::trackStatistics()
5813 void trackStatistics() const override {}
5814};
5815
5816/// InstanceInfo attribute for floating values.
5817struct AAInstanceInfoFloating : AAInstanceInfoImpl {
5818 AAInstanceInfoFloating(const IRPosition &IRP, Attributor &A)
5819 : AAInstanceInfoImpl(IRP, A) {}
5820};
5821
5822/// NoCapture attribute for function arguments.
5823struct AAInstanceInfoArgument final : AAInstanceInfoFloating {
5824 AAInstanceInfoArgument(const IRPosition &IRP, Attributor &A)
5825 : AAInstanceInfoFloating(IRP, A) {}
5826};
5827
5828/// InstanceInfo attribute for call site arguments.
5829struct AAInstanceInfoCallSiteArgument final : AAInstanceInfoImpl {
5830 AAInstanceInfoCallSiteArgument(const IRPosition &IRP, Attributor &A)
5831 : AAInstanceInfoImpl(IRP, A) {}
5832
5833 /// See AbstractAttribute::updateImpl(...).
5834 ChangeStatus updateImpl(Attributor &A) override {
5835 // TODO: Once we have call site specific value information we can provide
5836 // call site specific liveness information and then it makes
5837 // sense to specialize attributes for call sites arguments instead of
5838 // redirecting requests to the callee argument.
5839 Argument *Arg = getAssociatedArgument();
5840 if (!Arg)
5841 return indicatePessimisticFixpoint();
5842 const IRPosition &ArgPos = IRPosition::argument(*Arg);
5843 auto *ArgAA =
5844 A.getAAFor<AAInstanceInfo>(*this, ArgPos, DepClassTy::REQUIRED);
5845 if (!ArgAA)
5846 return indicatePessimisticFixpoint();
5847 return clampStateAndIndicateChange(getState(), ArgAA->getState());
5848 }
5849};
5850
5851/// InstanceInfo attribute for function return value.
5852struct AAInstanceInfoReturned final : AAInstanceInfoImpl {
5853 AAInstanceInfoReturned(const IRPosition &IRP, Attributor &A)
5854 : AAInstanceInfoImpl(IRP, A) {
5855 llvm_unreachable("InstanceInfo is not applicable to function returns!");
5856 }
5857
5858 /// See AbstractAttribute::initialize(...).
5859 void initialize(Attributor &A) override {
5860 llvm_unreachable("InstanceInfo is not applicable to function returns!");
5861 }
5862
5863 /// See AbstractAttribute::updateImpl(...).
5864 ChangeStatus updateImpl(Attributor &A) override {
5865 llvm_unreachable("InstanceInfo is not applicable to function returns!");
5866 }
5867};
5868
5869/// InstanceInfo attribute deduction for a call site return value.
5870struct AAInstanceInfoCallSiteReturned final : AAInstanceInfoFloating {
5871 AAInstanceInfoCallSiteReturned(const IRPosition &IRP, Attributor &A)
5872 : AAInstanceInfoFloating(IRP, A) {}
5873};
5874} // namespace
5875
5876/// ----------------------- Variable Capturing ---------------------------------
5878 Attribute::AttrKind ImpliedAttributeKind,
5879 bool IgnoreSubsumingPositions) {
5880 assert(ImpliedAttributeKind == Attribute::Captures &&
5881 "Unexpected attribute kind");
5882 Value &V = IRP.getAssociatedValue();
5883 if (!isa<Constant>(V) && !IRP.isArgumentPosition())
5884 return V.use_empty();
5885
5886 // You cannot "capture" null if it is not a valid pointer.
5887 if (isa<UndefValue>(V) ||
5891 return true;
5892 }
5893
5895 A.getAttrs(IRP, {Attribute::Captures}, Attrs,
5896 /* IgnoreSubsumingPositions */ true);
5897 for (const Attribute &Attr : Attrs)
5898 if (capturesNothing(Attr.getCaptureInfo()))
5899 return true;
5900
5902 if (Argument *Arg = IRP.getAssociatedArgument()) {
5904 A.getAttrs(IRPosition::argument(*Arg),
5905 {Attribute::Captures, Attribute::ByVal}, Attrs,
5906 /* IgnoreSubsumingPositions */ true);
5907 bool ArgNoCapture = any_of(Attrs, [](Attribute Attr) {
5908 return Attr.getKindAsEnum() == Attribute::ByVal ||
5910 });
5911 if (ArgNoCapture) {
5912 A.manifestAttrs(IRP, Attribute::getWithCaptureInfo(
5913 V.getContext(), CaptureInfo::none()));
5914 return true;
5915 }
5916 }
5917
5918 if (const Function *F = IRP.getAssociatedFunction()) {
5919 // Check what state the associated function can actually capture.
5922 if (State.isKnown(NO_CAPTURE)) {
5923 A.manifestAttrs(IRP, Attribute::getWithCaptureInfo(V.getContext(),
5925 return true;
5926 }
5927 }
5928
5929 return false;
5930}
5931
5932/// Set the NOT_CAPTURED_IN_MEM and NOT_CAPTURED_IN_RET bits in \p Known
5933/// depending on the ability of the function associated with \p IRP to capture
5934/// state in memory and through "returning/throwing", respectively.
5936 const Function &F,
5937 BitIntegerState &State) {
5938 // TODO: Once we have memory behavior attributes we should use them here.
5939
5940 // If we know we cannot communicate or write to memory, we do not care about
5941 // ptr2int anymore.
5942 bool ReadOnly = F.onlyReadsMemory();
5943 bool NoThrow = F.doesNotThrow();
5944 bool IsVoidReturn = F.getReturnType()->isVoidTy();
5945 if (ReadOnly && NoThrow && IsVoidReturn) {
5946 State.addKnownBits(NO_CAPTURE);
5947 return;
5948 }
5949
5950 // A function cannot capture state in memory if it only reads memory, it can
5951 // however return/throw state and the state might be influenced by the
5952 // pointer value, e.g., loading from a returned pointer might reveal a bit.
5953 if (ReadOnly)
5954 State.addKnownBits(NOT_CAPTURED_IN_MEM);
5955
5956 // A function cannot communicate state back if it does not through
5957 // exceptions and doesn not return values.
5958 if (NoThrow && IsVoidReturn)
5959 State.addKnownBits(NOT_CAPTURED_IN_RET);
5960
5961 // Check existing "returned" attributes.
5962 int ArgNo = IRP.getCalleeArgNo();
5963 if (!NoThrow || ArgNo < 0 ||
5964 !F.getAttributes().hasAttrSomewhere(Attribute::Returned))
5965 return;
5966
5967 for (unsigned U = 0, E = F.arg_size(); U < E; ++U)
5968 if (F.hasParamAttribute(U, Attribute::Returned)) {
5969 if (U == unsigned(ArgNo))
5970 State.removeAssumedBits(NOT_CAPTURED_IN_RET);
5971 else if (ReadOnly)
5972 State.addKnownBits(NO_CAPTURE);
5973 else
5974 State.addKnownBits(NOT_CAPTURED_IN_RET);
5975 break;
5976 }
5977}
5978
5979namespace {
5980/// A class to hold the state of for no-capture attributes.
5981struct AANoCaptureImpl : public AANoCapture {
5982 AANoCaptureImpl(const IRPosition &IRP, Attributor &A) : AANoCapture(IRP, A) {}
5983
5984 /// See AbstractAttribute::initialize(...).
5985 void initialize(Attributor &A) override {
5986 bool IsKnown;
5988 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
5989 (void)IsKnown;
5990 }
5991
5992 /// See AbstractAttribute::updateImpl(...).
5993 ChangeStatus updateImpl(Attributor &A) override;
5994
5995 /// see AbstractAttribute::isAssumedNoCaptureMaybeReturned(...).
5996 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
5997 SmallVectorImpl<Attribute> &Attrs) const override {
5998 if (!isAssumedNoCaptureMaybeReturned())
5999 return;
6000
6001 if (isArgumentPosition()) {
6002 if (isAssumedNoCapture())
6003 Attrs.emplace_back(Attribute::get(Ctx, Attribute::Captures));
6004 else if (ManifestInternal)
6005 Attrs.emplace_back(Attribute::get(Ctx, "no-capture-maybe-returned"));
6006 }
6007 }
6008
6009 /// See AbstractState::getAsStr().
6010 const std::string getAsStr(Attributor *A) const override {
6011 if (isKnownNoCapture())
6012 return "known not-captured";
6013 if (isAssumedNoCapture())
6014 return "assumed not-captured";
6015 if (isKnownNoCaptureMaybeReturned())
6016 return "known not-captured-maybe-returned";
6017 if (isAssumedNoCaptureMaybeReturned())
6018 return "assumed not-captured-maybe-returned";
6019 return "assumed-captured";
6020 }
6021
6022 /// Check the use \p U and update \p State accordingly. Return true if we
6023 /// should continue to update the state.
6024 bool checkUse(Attributor &A, AANoCapture::StateType &State, const Use &U,
6025 bool &Follow) {
6026 Instruction *UInst = cast<Instruction>(U.getUser());
6027 LLVM_DEBUG(dbgs() << "[AANoCapture] Check use: " << *U.get() << " in "
6028 << *UInst << "\n");
6029
6030 // Deal with ptr2int by following uses.
6031 if (isa<PtrToIntInst>(UInst)) {
6032 LLVM_DEBUG(dbgs() << " - ptr2int assume the worst!\n");
6033 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
6034 /* Return */ true);
6035 }
6036
6037 // For stores we already checked if we can follow them, if they make it
6038 // here we give up.
6039 if (isa<StoreInst>(UInst))
6040 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
6041 /* Return */ true);
6042
6043 // Explicitly catch return instructions.
6044 if (isa<ReturnInst>(UInst)) {
6045 if (UInst->getFunction() == getAnchorScope())
6046 return isCapturedIn(State, /* Memory */ false, /* Integer */ false,
6047 /* Return */ true);
6048 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
6049 /* Return */ true);
6050 }
6051
6052 // For now we only use special logic for call sites. However, the tracker
6053 // itself knows about a lot of other non-capturing cases already.
6054 auto *CB = dyn_cast<CallBase>(UInst);
6055 if (!CB || !CB->isArgOperand(&U))
6056 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
6057 /* Return */ true);
6058
6059 unsigned ArgNo = CB->getArgOperandNo(&U);
6060 const IRPosition &CSArgPos = IRPosition::callsite_argument(*CB, ArgNo);
6061 // If we have a abstract no-capture attribute for the argument we can use
6062 // it to justify a non-capture attribute here. This allows recursion!
6063 bool IsKnownNoCapture;
6064 const AANoCapture *ArgNoCaptureAA = nullptr;
6065 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
6066 A, this, CSArgPos, DepClassTy::REQUIRED, IsKnownNoCapture, false,
6067 &ArgNoCaptureAA);
6068 if (IsAssumedNoCapture)
6069 return isCapturedIn(State, /* Memory */ false, /* Integer */ false,
6070 /* Return */ false);
6071 if (ArgNoCaptureAA && ArgNoCaptureAA->isAssumedNoCaptureMaybeReturned()) {
6072 Follow = true;
6073 return isCapturedIn(State, /* Memory */ false, /* Integer */ false,
6074 /* Return */ false);
6075 }
6076
6077 // Lastly, we could not find a reason no-capture can be assumed so we don't.
6078 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
6079 /* Return */ true);
6080 }
6081
6082 /// Update \p State according to \p CapturedInMem, \p CapturedInInt, and
6083 /// \p CapturedInRet, then return true if we should continue updating the
6084 /// state.
6085 static bool isCapturedIn(AANoCapture::StateType &State, bool CapturedInMem,
6086 bool CapturedInInt, bool CapturedInRet) {
6087 LLVM_DEBUG(dbgs() << " - captures [Mem " << CapturedInMem << "|Int "
6088 << CapturedInInt << "|Ret " << CapturedInRet << "]\n");
6089 if (CapturedInMem)
6090 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_MEM);
6091 if (CapturedInInt)
6092 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_INT);
6093 if (CapturedInRet)
6094 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_RET);
6095 return State.isAssumed(AANoCapture::NO_CAPTURE_MAYBE_RETURNED);
6096 }
6097};
6098
6099ChangeStatus AANoCaptureImpl::updateImpl(Attributor &A) {
6100 const IRPosition &IRP = getIRPosition();
6101 Value *V = isArgumentPosition() ? IRP.getAssociatedArgument()
6102 : &IRP.getAssociatedValue();
6103 if (!V)
6104 return indicatePessimisticFixpoint();
6105
6106 const Function *F =
6107 isArgumentPosition() ? IRP.getAssociatedFunction() : IRP.getAnchorScope();
6108
6109 // TODO: Is the checkForAllUses below useful for constants?
6110 if (!F)
6111 return indicatePessimisticFixpoint();
6112
6114 const IRPosition &FnPos = IRPosition::function(*F);
6115
6116 // Readonly means we cannot capture through memory.
6117 bool IsKnown;
6118 if (AA::isAssumedReadOnly(A, FnPos, *this, IsKnown)) {
6119 T.addKnownBits(NOT_CAPTURED_IN_MEM);
6120 if (IsKnown)
6121 addKnownBits(NOT_CAPTURED_IN_MEM);
6122 }
6123
6124 // Make sure all returned values are different than the underlying value.
6125 // TODO: we could do this in a more sophisticated way inside
6126 // AAReturnedValues, e.g., track all values that escape through returns
6127 // directly somehow.
6128 auto CheckReturnedArgs = [&](bool &UsedAssumedInformation) {
6130 if (!A.getAssumedSimplifiedValues(IRPosition::returned(*F), this, Values,
6132 UsedAssumedInformation))
6133 return false;
6134 bool SeenConstant = false;
6135 for (const AA::ValueAndContext &VAC : Values) {
6136 if (isa<Constant>(VAC.getValue())) {
6137 if (SeenConstant)
6138 return false;
6139 SeenConstant = true;
6140 } else if (!isa<Argument>(VAC.getValue()) ||
6141 VAC.getValue() == getAssociatedArgument())
6142 return false;
6143 }
6144 return true;
6145 };
6146
6147 bool IsKnownNoUnwind;
6149 A, this, FnPos, DepClassTy::OPTIONAL, IsKnownNoUnwind)) {
6150 bool IsVoidTy = F->getReturnType()->isVoidTy();
6151 bool UsedAssumedInformation = false;
6152 if (IsVoidTy || CheckReturnedArgs(UsedAssumedInformation)) {
6153 T.addKnownBits(NOT_CAPTURED_IN_RET);
6154 if (T.isKnown(NOT_CAPTURED_IN_MEM))
6156 if (IsKnownNoUnwind && (IsVoidTy || !UsedAssumedInformation)) {
6157 addKnownBits(NOT_CAPTURED_IN_RET);
6158 if (isKnown(NOT_CAPTURED_IN_MEM))
6159 return indicateOptimisticFixpoint();
6160 }
6161 }
6162 }
6163
6164 auto UseCheck = [&](const Use &U, bool &Follow) -> bool {
6165 // TODO(captures): Make this more precise.
6166 UseCaptureInfo CI = DetermineUseCaptureKind(U, /*Base=*/nullptr);
6167 if (capturesNothing(CI))
6168 return true;
6169 if (CI.isPassthrough()) {
6170 Follow = true;
6171 return true;
6172 }
6173 return checkUse(A, T, U, Follow);
6174 };
6175
6176 if (!A.checkForAllUses(UseCheck, *this, *V))
6177 return indicatePessimisticFixpoint();
6178
6179 AANoCapture::StateType &S = getState();
6180 auto Assumed = S.getAssumed();
6181 S.intersectAssumedBits(T.getAssumed());
6182 if (!isAssumedNoCaptureMaybeReturned())
6183 return indicatePessimisticFixpoint();
6184 return Assumed == S.getAssumed() ? ChangeStatus::UNCHANGED
6186}
6187
6188/// NoCapture attribute for function arguments.
6189struct AANoCaptureArgument final : AANoCaptureImpl {
6190 AANoCaptureArgument(const IRPosition &IRP, Attributor &A)
6191 : AANoCaptureImpl(IRP, A) {}
6192
6193 /// See AbstractAttribute::trackStatistics()
6194 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nocapture) }
6195};
6196
6197/// NoCapture attribute for call site arguments.
6198struct AANoCaptureCallSiteArgument final : AANoCaptureImpl {
6199 AANoCaptureCallSiteArgument(const IRPosition &IRP, Attributor &A)
6200 : AANoCaptureImpl(IRP, A) {}
6201
6202 /// See AbstractAttribute::updateImpl(...).
6203 ChangeStatus updateImpl(Attributor &A) override {
6204 // TODO: Once we have call site specific value information we can provide
6205 // call site specific liveness information and then it makes
6206 // sense to specialize attributes for call sites arguments instead of
6207 // redirecting requests to the callee argument.
6208 Argument *Arg = getAssociatedArgument();
6209 if (!Arg)
6210 return indicatePessimisticFixpoint();
6211 const IRPosition &ArgPos = IRPosition::argument(*Arg);
6212 bool IsKnownNoCapture;
6213 const AANoCapture *ArgAA = nullptr;
6215 A, this, ArgPos, DepClassTy::REQUIRED, IsKnownNoCapture, false,
6216 &ArgAA))
6217 return ChangeStatus::UNCHANGED;
6218 if (!ArgAA || !ArgAA->isAssumedNoCaptureMaybeReturned())
6219 return indicatePessimisticFixpoint();
6220 return clampStateAndIndicateChange(getState(), ArgAA->getState());
6221 }
6222
6223 /// See AbstractAttribute::trackStatistics()
6224 void trackStatistics() const override {
6226 };
6227};
6228
6229/// NoCapture attribute for floating values.
6230struct AANoCaptureFloating final : AANoCaptureImpl {
6231 AANoCaptureFloating(const IRPosition &IRP, Attributor &A)
6232 : AANoCaptureImpl(IRP, A) {}
6233
6234 /// See AbstractAttribute::trackStatistics()
6235 void trackStatistics() const override {
6237 }
6238};
6239
6240/// NoCapture attribute for function return value.
6241struct AANoCaptureReturned final : AANoCaptureImpl {
6242 AANoCaptureReturned(const IRPosition &IRP, Attributor &A)
6243 : AANoCaptureImpl(IRP, A) {
6244 llvm_unreachable("NoCapture is not applicable to function returns!");
6245 }
6246
6247 /// See AbstractAttribute::initialize(...).
6248 void initialize(Attributor &A) override {
6249 llvm_unreachable("NoCapture is not applicable to function returns!");
6250 }
6251
6252 /// See AbstractAttribute::updateImpl(...).
6253 ChangeStatus updateImpl(Attributor &A) override {
6254 llvm_unreachable("NoCapture is not applicable to function returns!");
6255 }
6256
6257 /// See AbstractAttribute::trackStatistics()
6258 void trackStatistics() const override {}
6259};
6260
6261/// NoCapture attribute deduction for a call site return value.
6262struct AANoCaptureCallSiteReturned final : AANoCaptureImpl {
6263 AANoCaptureCallSiteReturned(const IRPosition &IRP, Attributor &A)
6264 : AANoCaptureImpl(IRP, A) {}
6265
6266 /// See AbstractAttribute::initialize(...).
6267 void initialize(Attributor &A) override {
6268 const Function *F = getAnchorScope();
6269 // Check what state the associated function can actually capture.
6270 determineFunctionCaptureCapabilities(getIRPosition(), *F, *this);
6271 }
6272
6273 /// See AbstractAttribute::trackStatistics()
6274 void trackStatistics() const override {
6276 }
6277};
6278} // namespace
6279
6280/// ------------------ Value Simplify Attribute ----------------------------
6281
6282bool ValueSimplifyStateType::unionAssumed(std::optional<Value *> Other) {
6283 // FIXME: Add a typecast support.
6286 if (SimplifiedAssociatedValue == std::optional<Value *>(nullptr))
6287 return false;
6288
6289 LLVM_DEBUG({
6291 dbgs() << "[ValueSimplify] is assumed to be "
6292 << **SimplifiedAssociatedValue << "\n";
6293 else
6294 dbgs() << "[ValueSimplify] is assumed to be <none>\n";
6295 });
6296 return true;
6297}
6298
6299namespace {
6300struct AAValueSimplifyImpl : AAValueSimplify {
6301 AAValueSimplifyImpl(const IRPosition &IRP, Attributor &A)
6302 : AAValueSimplify(IRP, A) {}
6303
6304 /// See AbstractAttribute::initialize(...).
6305 void initialize(Attributor &A) override {
6306 if (getAssociatedValue().getType()->isVoidTy())
6307 indicatePessimisticFixpoint();
6308 if (A.hasSimplificationCallback(getIRPosition()))
6309 indicatePessimisticFixpoint();
6310 }
6311
6312 /// See AbstractAttribute::getAsStr().
6313 const std::string getAsStr(Attributor *A) const override {
6314 LLVM_DEBUG({
6315 dbgs() << "SAV: " << (bool)SimplifiedAssociatedValue << " ";
6316 if (SimplifiedAssociatedValue && *SimplifiedAssociatedValue)
6317 dbgs() << "SAV: " << **SimplifiedAssociatedValue << " ";
6318 });
6319 return isValidState() ? (isAtFixpoint() ? "simplified" : "maybe-simple")
6320 : "not-simple";
6321 }
6322
6323 /// See AbstractAttribute::trackStatistics()
6324 void trackStatistics() const override {}
6325
6326 /// See AAValueSimplify::getAssumedSimplifiedValue()
6327 std::optional<Value *>
6328 getAssumedSimplifiedValue(Attributor &A) const override {
6329 return SimplifiedAssociatedValue;
6330 }
6331
6332 /// Ensure the return value is \p V with type \p Ty, if not possible return
6333 /// nullptr. If \p Check is true we will only verify such an operation would
6334 /// suceed and return a non-nullptr value if that is the case. No IR is
6335 /// generated or modified.
6336 static Value *ensureType(Attributor &A, Value &V, Type &Ty, Instruction *CtxI,
6337 bool Check) {
6338 if (auto *TypedV = AA::getWithType(V, Ty))
6339 return TypedV;
6340 if (CtxI && V.getType()->canLosslesslyBitCastTo(&Ty))
6341 return Check ? &V
6342 : BitCastInst::CreatePointerBitCastOrAddrSpaceCast(
6343 &V, &Ty, "", CtxI->getIterator());
6344 return nullptr;
6345 }
6346
6347 /// Reproduce \p I with type \p Ty or return nullptr if that is not posisble.
6348 /// If \p Check is true we will only verify such an operation would suceed and
6349 /// return a non-nullptr value if that is the case. No IR is generated or
6350 /// modified.
6351 static Value *reproduceInst(Attributor &A,
6352 const AbstractAttribute &QueryingAA,
6353 Instruction &I, Type &Ty, Instruction *CtxI,
6354 bool Check, ValueToValueMapTy &VMap) {
6355 assert(CtxI && "Cannot reproduce an instruction without context!");
6356 if (Check && (I.mayReadFromMemory() ||
6357 !isSafeToSpeculativelyExecute(&I, CtxI, /* DT */ nullptr,
6358 /* TLI */ nullptr)))
6359 return nullptr;
6360 for (Value *Op : I.operands()) {
6361 Value *NewOp = reproduceValue(A, QueryingAA, *Op, Ty, CtxI, Check, VMap);
6362 if (!NewOp) {
6363 assert(Check && "Manifest of new value unexpectedly failed!");
6364 return nullptr;
6365 }
6366 if (!Check)
6367 VMap[Op] = NewOp;
6368 }
6369 if (Check)
6370 return &I;
6371
6372 Instruction *CloneI = I.clone();
6373 // TODO: Try to salvage debug information here.
6374 CloneI->setDebugLoc(DebugLoc());
6375 VMap[&I] = CloneI;
6376 CloneI->insertBefore(CtxI->getIterator());
6377 RemapInstruction(CloneI, VMap);
6378 return CloneI;
6379 }
6380
6381 /// Reproduce \p V with type \p Ty or return nullptr if that is not posisble.
6382 /// If \p Check is true we will only verify such an operation would suceed and
6383 /// return a non-nullptr value if that is the case. No IR is generated or
6384 /// modified.
6385 static Value *reproduceValue(Attributor &A,
6386 const AbstractAttribute &QueryingAA, Value &V,
6387 Type &Ty, Instruction *CtxI, bool Check,
6388 ValueToValueMapTy &VMap) {
6389 if (const auto &NewV = VMap.lookup(&V))
6390 return NewV;
6391 bool UsedAssumedInformation = false;
6392 std::optional<Value *> SimpleV = A.getAssumedSimplified(
6393 V, QueryingAA, UsedAssumedInformation, AA::Interprocedural);
6394 if (!SimpleV.has_value())
6395 return PoisonValue::get(&Ty);
6396 Value *EffectiveV = &V;
6397 if (*SimpleV)
6398 EffectiveV = *SimpleV;
6399 if (auto *C = dyn_cast<Constant>(EffectiveV))
6400 return C;
6401 if (CtxI && AA::isValidAtPosition(AA::ValueAndContext(*EffectiveV, *CtxI),
6402 A.getInfoCache()))
6403 return ensureType(A, *EffectiveV, Ty, CtxI, Check);
6404 if (auto *I = dyn_cast<Instruction>(EffectiveV))
6405 if (Value *NewV = reproduceInst(A, QueryingAA, *I, Ty, CtxI, Check, VMap))
6406 return ensureType(A, *NewV, Ty, CtxI, Check);
6407 return nullptr;
6408 }
6409
6410 /// Return a value we can use as replacement for the associated one, or
6411 /// nullptr if we don't have one that makes sense.
6412 Value *manifestReplacementValue(Attributor &A, Instruction *CtxI) const {
6413 Value *NewV = SimplifiedAssociatedValue
6414 ? *SimplifiedAssociatedValue
6415 : UndefValue::get(getAssociatedType());
6416 if (NewV && NewV != &getAssociatedValue()) {
6417 ValueToValueMapTy VMap;
6418 // First verify we can reprduce the value with the required type at the
6419 // context location before we actually start modifying the IR.
6420 if (reproduceValue(A, *this, *NewV, *getAssociatedType(), CtxI,
6421 /* CheckOnly */ true, VMap))
6422 return reproduceValue(A, *this, *NewV, *getAssociatedType(), CtxI,
6423 /* CheckOnly */ false, VMap);
6424 }
6425 return nullptr;
6426 }
6427
6428 /// Helper function for querying AAValueSimplify and updating candidate.
6429 /// \param IRP The value position we are trying to unify with SimplifiedValue
6430 bool checkAndUpdate(Attributor &A, const AbstractAttribute &QueryingAA,
6431 const IRPosition &IRP, bool Simplify = true) {
6432 bool UsedAssumedInformation = false;
6433 std::optional<Value *> QueryingValueSimplified = &IRP.getAssociatedValue();
6434 if (Simplify)
6435 QueryingValueSimplified = A.getAssumedSimplified(
6436 IRP, QueryingAA, UsedAssumedInformation, AA::Interprocedural);
6437 return unionAssumed(QueryingValueSimplified);
6438 }
6439
6440 /// Returns a candidate is found or not
6441 template <typename AAType> bool askSimplifiedValueFor(Attributor &A) {
6442 if (!getAssociatedValue().getType()->isIntegerTy())
6443 return false;
6444
6445 // This will also pass the call base context.
6446 const auto *AA =
6447 A.getAAFor<AAType>(*this, getIRPosition(), DepClassTy::NONE);
6448 if (!AA)
6449 return false;
6450
6451 std::optional<Constant *> COpt = AA->getAssumedConstant(A);
6452
6453 if (!COpt) {
6454 SimplifiedAssociatedValue = std::nullopt;
6455 A.recordDependence(*AA, *this, DepClassTy::OPTIONAL);
6456 return true;
6457 }
6458 if (auto *C = *COpt) {
6459 SimplifiedAssociatedValue = C;
6460 A.recordDependence(*AA, *this, DepClassTy::OPTIONAL);
6461 return true;
6462 }
6463 return false;
6464 }
6465
6466 bool askSimplifiedValueForOtherAAs(Attributor &A) {
6467 if (askSimplifiedValueFor<AAValueConstantRange>(A))
6468 return true;
6469 if (askSimplifiedValueFor<AAPotentialConstantValues>(A))
6470 return true;
6471 return false;
6472 }
6473
6474 /// See AbstractAttribute::manifest(...).
6475 ChangeStatus manifest(Attributor &A) override {
6476 ChangeStatus Changed = ChangeStatus::UNCHANGED;
6477 for (auto &U : getAssociatedValue().uses()) {
6478 // Check if we need to adjust the insertion point to make sure the IR is
6479 // valid.
6480 Instruction *IP = dyn_cast<Instruction>(U.getUser());
6481 if (auto *PHI = dyn_cast_or_null<PHINode>(IP))
6482 IP = PHI->getIncomingBlock(U)->getTerminator();
6483 if (auto *NewV = manifestReplacementValue(A, IP)) {
6484 LLVM_DEBUG(dbgs() << "[ValueSimplify] " << getAssociatedValue()
6485 << " -> " << *NewV << " :: " << *this << "\n");
6486 if (A.changeUseAfterManifest(U, *NewV))
6487 Changed = ChangeStatus::CHANGED;
6488 }
6489 }
6490
6491 return Changed | AAValueSimplify::manifest(A);
6492 }
6493
6494 /// See AbstractState::indicatePessimisticFixpoint(...).
6495 ChangeStatus indicatePessimisticFixpoint() override {
6496 SimplifiedAssociatedValue = &getAssociatedValue();
6497 return AAValueSimplify::indicatePessimisticFixpoint();
6498 }
6499};
6500
6501struct AAValueSimplifyArgument final : AAValueSimplifyImpl {
6502 AAValueSimplifyArgument(const IRPosition &IRP, Attributor &A)
6503 : AAValueSimplifyImpl(IRP, A) {}
6504
6505 void initialize(Attributor &A) override {
6506 AAValueSimplifyImpl::initialize(A);
6507 if (A.hasAttr(getIRPosition(),
6508 {Attribute::InAlloca, Attribute::Preallocated,
6509 Attribute::StructRet, Attribute::Nest, Attribute::ByVal},
6510 /* IgnoreSubsumingPositions */ true))
6511 indicatePessimisticFixpoint();
6512 }
6513
6514 /// See AbstractAttribute::updateImpl(...).
6515 ChangeStatus updateImpl(Attributor &A) override {
6516 // Byval is only replacable if it is readonly otherwise we would write into
6517 // the replaced value and not the copy that byval creates implicitly.
6518 Argument *Arg = getAssociatedArgument();
6519 if (Arg->hasByValAttr()) {
6520 // TODO: We probably need to verify synchronization is not an issue, e.g.,
6521 // there is no race by not copying a constant byval.
6522 bool IsKnown;
6523 if (!AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown))
6524 return indicatePessimisticFixpoint();
6525 }
6526
6527 auto Before = SimplifiedAssociatedValue;
6528
6529 auto PredForCallSite = [&](AbstractCallSite ACS) {
6530 const IRPosition &ACSArgPos =
6531 IRPosition::callsite_argument(ACS, getCallSiteArgNo());
6532 // Check if a coresponding argument was found or if it is on not
6533 // associated (which can happen for callback calls).
6534 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
6535 return false;
6536
6537 // Simplify the argument operand explicitly and check if the result is
6538 // valid in the current scope. This avoids refering to simplified values
6539 // in other functions, e.g., we don't want to say a an argument in a
6540 // static function is actually an argument in a different function.
6541 bool UsedAssumedInformation = false;
6542 std::optional<Constant *> SimpleArgOp =
6543 A.getAssumedConstant(ACSArgPos, *this, UsedAssumedInformation);
6544 if (!SimpleArgOp)
6545 return true;
6546 if (!*SimpleArgOp)
6547 return false;
6548 if (!AA::isDynamicallyUnique(A, *this, **SimpleArgOp))
6549 return false;
6550 return unionAssumed(*SimpleArgOp);
6551 };
6552
6553 // Generate a answer specific to a call site context.
6554 bool Success;
6555 bool UsedAssumedInformation = false;
6556 if (hasCallBaseContext() &&
6557 getCallBaseContext()->getCalledOperand() == Arg->getParent())
6558 Success = PredForCallSite(
6559 AbstractCallSite(&getCallBaseContext()->getCalledOperandUse()));
6560 else
6561 Success = A.checkForAllCallSites(PredForCallSite, *this, true,
6562 UsedAssumedInformation);
6563
6564 if (!Success)
6565 if (!askSimplifiedValueForOtherAAs(A))
6566 return indicatePessimisticFixpoint();
6567
6568 // If a candidate was found in this update, return CHANGED.
6569 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED
6570 : ChangeStatus ::CHANGED;
6571 }
6572
6573 /// See AbstractAttribute::trackStatistics()
6574 void trackStatistics() const override {
6575 STATS_DECLTRACK_ARG_ATTR(value_simplify)
6576 }
6577};
6578
6579struct AAValueSimplifyReturned : AAValueSimplifyImpl {
6580 AAValueSimplifyReturned(const IRPosition &IRP, Attributor &A)
6581 : AAValueSimplifyImpl(IRP, A) {}
6582
6583 /// See AAValueSimplify::getAssumedSimplifiedValue()
6584 std::optional<Value *>
6585 getAssumedSimplifiedValue(Attributor &A) const override {
6586 if (!isValidState())
6587 return nullptr;
6588 return SimplifiedAssociatedValue;
6589 }
6590
6591 /// See AbstractAttribute::updateImpl(...).
6592 ChangeStatus updateImpl(Attributor &A) override {
6593 auto Before = SimplifiedAssociatedValue;
6594
6595 auto ReturnInstCB = [&](Instruction &I) {
6596 auto &RI = cast<ReturnInst>(I);
6597 return checkAndUpdate(
6598 A, *this,
6599 IRPosition::value(*RI.getReturnValue(), getCallBaseContext()));
6600 };
6601
6602 bool UsedAssumedInformation = false;
6603 if (!A.checkForAllInstructions(ReturnInstCB, *this, {Instruction::Ret},
6604 UsedAssumedInformation))
6605 if (!askSimplifiedValueForOtherAAs(A))
6606 return indicatePessimisticFixpoint();
6607
6608 // If a candidate was found in this update, return CHANGED.
6609 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED
6610 : ChangeStatus ::CHANGED;
6611 }
6612
6613 ChangeStatus manifest(Attributor &A) override {
6614 // We queried AAValueSimplify for the returned values so they will be
6615 // replaced if a simplified form was found. Nothing to do here.
6616 return ChangeStatus::UNCHANGED;
6617 }
6618
6619 /// See AbstractAttribute::trackStatistics()
6620 void trackStatistics() const override {
6621 STATS_DECLTRACK_FNRET_ATTR(value_simplify)
6622 }
6623};
6624
6625struct AAValueSimplifyFloating : AAValueSimplifyImpl {
6626 AAValueSimplifyFloating(const IRPosition &IRP, Attributor &A)
6627 : AAValueSimplifyImpl(IRP, A) {}
6628
6629 /// See AbstractAttribute::initialize(...).
6630 void initialize(Attributor &A) override {
6631 AAValueSimplifyImpl::initialize(A);
6632 Value &V = getAnchorValue();
6633
6634 // TODO: add other stuffs
6635 if (isa<Constant>(V))
6636 indicatePessimisticFixpoint();
6637 }
6638
6639 /// See AbstractAttribute::updateImpl(...).
6640 ChangeStatus updateImpl(Attributor &A) override {
6641 auto Before = SimplifiedAssociatedValue;
6642 if (!askSimplifiedValueForOtherAAs(A))
6643 return indicatePessimisticFixpoint();
6644
6645 // If a candidate was found in this update, return CHANGED.
6646 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED
6647 : ChangeStatus ::CHANGED;
6648 }
6649
6650 /// See AbstractAttribute::trackStatistics()
6651 void trackStatistics() const override {
6652 STATS_DECLTRACK_FLOATING_ATTR(value_simplify)
6653 }
6654};
6655
6656struct AAValueSimplifyFunction : AAValueSimplifyImpl {
6657 AAValueSimplifyFunction(const IRPosition &IRP, Attributor &A)
6658 : AAValueSimplifyImpl(IRP, A) {}
6659
6660 /// See AbstractAttribute::initialize(...).
6661 void initialize(Attributor &A) override {
6662 SimplifiedAssociatedValue = nullptr;
6663 indicateOptimisticFixpoint();
6664 }
6665 /// See AbstractAttribute::initialize(...).
6666 ChangeStatus updateImpl(Attributor &A) override {
6668 "AAValueSimplify(Function|CallSite)::updateImpl will not be called");
6669 }
6670 /// See AbstractAttribute::trackStatistics()
6671 void trackStatistics() const override {
6672 STATS_DECLTRACK_FN_ATTR(value_simplify)
6673 }
6674};
6675
6676struct AAValueSimplifyCallSite : AAValueSimplifyFunction {
6677 AAValueSimplifyCallSite(const IRPosition &IRP, Attributor &A)
6678 : AAValueSimplifyFunction(IRP, A) {}
6679 /// See AbstractAttribute::trackStatistics()
6680 void trackStatistics() const override {
6681 STATS_DECLTRACK_CS_ATTR(value_simplify)
6682 }
6683};
6684
6685struct AAValueSimplifyCallSiteReturned : AAValueSimplifyImpl {
6686 AAValueSimplifyCallSiteReturned(const IRPosition &IRP, Attributor &A)
6687 : AAValueSimplifyImpl(IRP, A) {}
6688
6689 void initialize(Attributor &A) override {
6690 AAValueSimplifyImpl::initialize(A);
6691 Function *Fn = getAssociatedFunction();
6692 assert(Fn && "Did expect an associted function");
6693 for (Argument &Arg : Fn->args()) {
6694 if (Arg.hasReturnedAttr()) {
6695 auto IRP = IRPosition::callsite_argument(*cast<CallBase>(getCtxI()),
6696 Arg.getArgNo());
6698 checkAndUpdate(A, *this, IRP))
6699 indicateOptimisticFixpoint();
6700 else
6701 indicatePessimisticFixpoint();
6702 return;
6703 }
6704 }
6705 }
6706
6707 /// See AbstractAttribute::updateImpl(...).
6708 ChangeStatus updateImpl(Attributor &A) override {
6709 return indicatePessimisticFixpoint();
6710 }
6711
6712 void trackStatistics() const override {
6713 STATS_DECLTRACK_CSRET_ATTR(value_simplify)
6714 }
6715};
6716
6717struct AAValueSimplifyCallSiteArgument : AAValueSimplifyFloating {
6718 AAValueSimplifyCallSiteArgument(const IRPosition &IRP, Attributor &A)
6719 : AAValueSimplifyFloating(IRP, A) {}
6720
6721 /// See AbstractAttribute::manifest(...).
6722 ChangeStatus manifest(Attributor &A) override {
6723 ChangeStatus Changed = ChangeStatus::UNCHANGED;
6724 // TODO: We should avoid simplification duplication to begin with.
6725 auto *FloatAA = A.lookupAAFor<AAValueSimplify>(
6726 IRPosition::value(getAssociatedValue()), this, DepClassTy::NONE);
6727 if (FloatAA && FloatAA->getState().isValidState())
6728 return Changed;
6729
6730 if (auto *NewV = manifestReplacementValue(A, getCtxI())) {
6731 Use &U = cast<CallBase>(&getAnchorValue())
6732 ->getArgOperandUse(getCallSiteArgNo());
6733 if (A.changeUseAfterManifest(U, *NewV))
6734 Changed = ChangeStatus::CHANGED;
6735 }
6736
6737 return Changed | AAValueSimplify::manifest(A);
6738 }
6739
6740 void trackStatistics() const override {
6741 STATS_DECLTRACK_CSARG_ATTR(value_simplify)
6742 }
6743};
6744} // namespace
6745
6746/// ----------------------- Heap-To-Stack Conversion ---------------------------
6747namespace {
6748struct AAHeapToStackFunction final : public AAHeapToStack {
6749
6750 static bool isGlobalizedLocal(const CallBase &CB) {
6751 Attribute A = CB.getFnAttr("alloc-family");
6752 return A.isValid() && A.getValueAsString() == "__kmpc_alloc_shared";
6753 }
6754
6755 struct AllocationInfo {
6756 /// The call that allocates the memory.
6757 CallBase *const CB;
6758
6759 /// Whether this allocation is an OpenMP globalized local variable.
6760 bool IsGlobalizedLocal = false;
6761
6762 /// The status wrt. a rewrite.
6763 enum {
6764 STACK_DUE_TO_USE,
6765 STACK_DUE_TO_FREE,
6766 INVALID,
6767 } Status = STACK_DUE_TO_USE;
6768
6769 /// Flag to indicate if we encountered a use that might free this allocation
6770 /// but which is not in the deallocation infos.
6771 bool HasPotentiallyFreeingUnknownUses = false;
6772
6773 /// Flag to indicate that we should place the new alloca in the function
6774 /// entry block rather than where the call site (CB) is.
6775 bool MoveAllocaIntoEntry = true;
6776
6777 /// The set of free calls that use this allocation.
6778 SmallSetVector<CallBase *, 1> PotentialFreeCalls{};
6779 };
6780
6781 struct DeallocationInfo {
6782 /// The call that deallocates the memory.
6783 CallBase *const CB;
6784 /// The value freed by the call.
6785 Value *FreedOp;
6786
6787 /// Flag to indicate if we don't know all objects this deallocation might
6788 /// free.
6789 bool MightFreeUnknownObjects = false;
6790
6791 /// The set of allocation calls that are potentially freed.
6792 SmallSetVector<CallBase *, 1> PotentialAllocationCalls{};
6793 };
6794
6795 AAHeapToStackFunction(const IRPosition &IRP, Attributor &A)
6796 : AAHeapToStack(IRP, A) {}
6797
6798 ~AAHeapToStackFunction() override {
6799 // Ensure we call the destructor so we release any memory allocated in the
6800 // sets.
6801 for (auto &It : AllocationInfos)
6802 It.second->~AllocationInfo();
6803 for (auto &It : DeallocationInfos)
6804 It.second->~DeallocationInfo();
6805 }
6806
6807 void initialize(Attributor &A) override {
6808 AAHeapToStack::initialize(A);
6809
6810 const Function *F = getAnchorScope();
6811 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
6812
6813 auto AllocationIdentifierCB = [&](Instruction &I) {
6814 CallBase *CB = dyn_cast<CallBase>(&I);
6815 if (!CB)
6816 return true;
6817 if (Value *FreedOp = getFreedOperand(CB, TLI)) {
6818 DeallocationInfos[CB] = new (A.Allocator) DeallocationInfo{CB, FreedOp};
6819 return true;
6820 }
6821 // To do heap to stack, we need to know that the allocation itself is
6822 // removable once uses are rewritten, and that we can initialize the
6823 // alloca to the same pattern as the original allocation result.
6824 if (isRemovableAlloc(CB, TLI)) {
6825 auto *I8Ty = Type::getInt8Ty(CB->getParent()->getContext());
6826 if (nullptr != getInitialValueOfAllocation(CB, TLI, I8Ty)) {
6827 AllocationInfo *AI = new (A.Allocator) AllocationInfo{CB};
6828 AllocationInfos[CB] = AI;
6829 AI->IsGlobalizedLocal = isGlobalizedLocal(*CB);
6830 }
6831 }
6832 return true;
6833 };
6834
6835 bool UsedAssumedInformation = false;
6836 bool Success = A.checkForAllCallLikeInstructions(
6837 AllocationIdentifierCB, *this, UsedAssumedInformation,
6838 /* CheckBBLivenessOnly */ false,
6839 /* CheckPotentiallyDead */ true);
6840 (void)Success;
6841 assert(Success && "Did not expect the call base visit callback to fail!");
6842
6844 [](const IRPosition &, const AbstractAttribute *,
6845 bool &) -> std::optional<Value *> { return nullptr; };
6846 for (const auto &It : AllocationInfos)
6847 A.registerSimplificationCallback(IRPosition::callsite_returned(*It.first),
6848 SCB);
6849 for (const auto &It : DeallocationInfos)
6850 A.registerSimplificationCallback(IRPosition::callsite_returned(*It.first),
6851 SCB);
6852 }
6853
6854 const std::string getAsStr(Attributor *A) const override {
6855 unsigned NumH2SMallocs = 0, NumInvalidMallocs = 0;
6856 for (const auto &It : AllocationInfos) {
6857 if (It.second->Status == AllocationInfo::INVALID)
6858 ++NumInvalidMallocs;
6859 else
6860 ++NumH2SMallocs;
6861 }
6862 return "[H2S] Mallocs Good/Bad: " + std::to_string(NumH2SMallocs) + "/" +
6863 std::to_string(NumInvalidMallocs);
6864 }
6865
6866 /// See AbstractAttribute::trackStatistics().
6867 void trackStatistics() const override {
6868 STATS_DECL(
6869 MallocCalls, Function,
6870 "Number of malloc/calloc/aligned_alloc calls converted to allocas");
6871 for (const auto &It : AllocationInfos)
6872 if (It.second->Status != AllocationInfo::INVALID)
6873 ++BUILD_STAT_NAME(MallocCalls, Function);
6874 }
6875
6876 bool isAssumedHeapToStack(const CallBase &CB) const override {
6877 if (isValidState())
6878 if (AllocationInfo *AI =
6879 AllocationInfos.lookup(const_cast<CallBase *>(&CB)))
6880 return AI->Status != AllocationInfo::INVALID;
6881 return false;
6882 }
6883
6884 bool isAssumedHeapToStackRemovedFree(CallBase &CB) const override {
6885 if (!isValidState())
6886 return false;
6887
6888 for (const auto &It : AllocationInfos) {
6889 AllocationInfo &AI = *It.second;
6890 if (AI.Status == AllocationInfo::INVALID)
6891 continue;
6892
6893 if (AI.PotentialFreeCalls.count(&CB))
6894 return true;
6895 }
6896
6897 return false;
6898 }
6899
6900 ChangeStatus manifest(Attributor &A) override {
6901 assert(getState().isValidState() &&
6902 "Attempted to manifest an invalid state!");
6903
6904 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
6905 Function *F = getAnchorScope();
6906 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
6907
6908 for (auto &It : AllocationInfos) {
6909 AllocationInfo &AI = *It.second;
6910 if (AI.Status == AllocationInfo::INVALID)
6911 continue;
6912
6913 for (CallBase *FreeCall : AI.PotentialFreeCalls) {
6914 LLVM_DEBUG(dbgs() << "H2S: Removing free call: " << *FreeCall << "\n");
6915 A.deleteAfterManifest(*FreeCall);
6916 HasChanged = ChangeStatus::CHANGED;
6917 }
6918
6919 LLVM_DEBUG(dbgs() << "H2S: Removing malloc-like call: " << *AI.CB
6920 << "\n");
6921
6922 auto Remark = [&](OptimizationRemark OR) {
6923 if (AI.IsGlobalizedLocal)
6924 return OR << "Moving globalized variable to the stack.";
6925 return OR << "Moving memory allocation from the heap to the stack.";
6926 };
6927 if (AI.IsGlobalizedLocal)
6928 A.emitRemark<OptimizationRemark>(AI.CB, "OMP110", Remark);
6929 else
6930 A.emitRemark<OptimizationRemark>(AI.CB, "HeapToStack", Remark);
6931
6932 const DataLayout &DL = A.getInfoCache().getDL();
6933 Value *Size;
6934 std::optional<APInt> SizeAPI = getSize(A, *this, AI);
6935 if (SizeAPI) {
6936 Size = ConstantInt::get(AI.CB->getContext(), *SizeAPI);
6937 } else {
6938 ObjectSizeOpts Opts;
6939 ObjectSizeOffsetEvaluator Eval(*AI.CB->getModule(), TLI, Opts);
6940 SizeOffsetValue SizeOffsetPair = Eval.compute(AI.CB);
6941 assert(SizeOffsetPair != ObjectSizeOffsetEvaluator::unknown() &&
6942 cast<ConstantInt>(SizeOffsetPair.Offset)->isZero());
6943 Size = SizeOffsetPair.Size;
6944 }
6945
6946 BasicBlock::iterator IP = AI.MoveAllocaIntoEntry
6947 ? F->getEntryBlock().begin()
6948 : AI.CB->getIterator();
6949
6950 Align Alignment(1);
6951 if (MaybeAlign RetAlign = AI.CB->getRetAlign())
6952 Alignment = std::max(Alignment, *RetAlign);
6953 if (Value *Align = getAllocAlignment(AI.CB, TLI)) {
6954 std::optional<APInt> AlignmentAPI = getAPInt(A, *this, *Align);
6955 assert(AlignmentAPI && AlignmentAPI->getZExtValue() > 0 &&
6956 "Expected an alignment during manifest!");
6957 Alignment =
6958 std::max(Alignment, assumeAligned(AlignmentAPI->getZExtValue()));
6959 }
6960
6961 // TODO: Hoist the alloca towards the function entry.
6962 unsigned AS = DL.getAllocaAddrSpace();
6963 Instruction *Alloca =
6964 new AllocaInst(Type::getInt8Ty(F->getContext()), AS, Size, Alignment,
6965 AI.CB->getName() + ".h2s", IP);
6966
6967 if (Alloca->getType() != AI.CB->getType())
6968 Alloca = BitCastInst::CreatePointerBitCastOrAddrSpaceCast(
6969 Alloca, AI.CB->getType(), "malloc_cast", AI.CB->getIterator());
6970
6971 auto *I8Ty = Type::getInt8Ty(F->getContext());
6972 auto *InitVal = getInitialValueOfAllocation(AI.CB, TLI, I8Ty);
6973 assert(InitVal &&
6974 "Must be able to materialize initial memory state of allocation");
6975
6976 A.changeAfterManifest(IRPosition::inst(*AI.CB), *Alloca);
6977
6978 if (auto *II = dyn_cast<InvokeInst>(AI.CB)) {
6979 auto *NBB = II->getNormalDest();
6980 UncondBrInst::Create(NBB, AI.CB->getParent());
6981 A.deleteAfterManifest(*AI.CB);
6982 } else {
6983 A.deleteAfterManifest(*AI.CB);
6984 }
6985
6986 // Initialize the alloca with the same value as used by the allocation
6987 // function. We can skip undef as the initial value of an alloc is
6988 // undef, and the memset would simply end up being DSEd.
6989 if (!isa<UndefValue>(InitVal)) {
6990 IRBuilder<> Builder(Alloca->getNextNode());
6991 // TODO: Use alignment above if align!=1
6992 Builder.CreateMemSet(Alloca, InitVal, Size, std::nullopt);
6993 }
6994 HasChanged = ChangeStatus::CHANGED;
6995 }
6996
6997 return HasChanged;
6998 }
6999
7000 std::optional<APInt> getAPInt(Attributor &A, const AbstractAttribute &AA,
7001 Value &V) {
7002 bool UsedAssumedInformation = false;
7003 std::optional<Constant *> SimpleV =
7004 A.getAssumedConstant(V, AA, UsedAssumedInformation);
7005 if (!SimpleV)
7006 return APInt(64, 0);
7007 if (auto *CI = dyn_cast_or_null<ConstantInt>(*SimpleV))
7008 return CI->getValue();
7009 return std::nullopt;
7010 }
7011
7012 std::optional<APInt> getSize(Attributor &A, const AbstractAttribute &AA,
7013 AllocationInfo &AI) {
7014 auto Mapper = [&](const Value *V) -> const Value * {
7015 bool UsedAssumedInformation = false;
7016 if (std::optional<Constant *> SimpleV =
7017 A.getAssumedConstant(*V, AA, UsedAssumedInformation))
7018 if (*SimpleV)
7019 return *SimpleV;
7020 return V;
7021 };
7022
7023 const Function *F = getAnchorScope();
7024 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
7025 return getAllocSize(AI.CB, TLI, Mapper);
7026 }
7027
7028 /// Collection of all malloc-like calls in a function with associated
7029 /// information.
7030 MapVector<CallBase *, AllocationInfo *> AllocationInfos;
7031
7032 /// Collection of all free-like calls in a function with associated
7033 /// information.
7034 MapVector<CallBase *, DeallocationInfo *> DeallocationInfos;
7035
7036 ChangeStatus updateImpl(Attributor &A) override;
7037};
7038
7039ChangeStatus AAHeapToStackFunction::updateImpl(Attributor &A) {
7041 const Function *F = getAnchorScope();
7042 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
7043
7044 const auto *LivenessAA =
7045 A.getAAFor<AAIsDead>(*this, IRPosition::function(*F), DepClassTy::NONE);
7046
7047 MustBeExecutedContextExplorer *Explorer =
7048 A.getInfoCache().getMustBeExecutedContextExplorer();
7049
7050 bool StackIsAccessibleByOtherThreads =
7051 A.getInfoCache().stackIsAccessibleByOtherThreads();
7052
7053 LoopInfo *LI =
7054 A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(*F);
7055 std::optional<bool> MayContainIrreducibleControl;
7056 auto IsInLoop = [&](BasicBlock &BB) {
7057 if (&F->getEntryBlock() == &BB)
7058 return false;
7059 if (!MayContainIrreducibleControl.has_value())
7060 MayContainIrreducibleControl = mayContainIrreducibleControl(*F, LI);
7061 if (*MayContainIrreducibleControl)
7062 return true;
7063 if (!LI)
7064 return true;
7065 return LI->getLoopFor(&BB) != nullptr;
7066 };
7067
7068 // Flag to ensure we update our deallocation information at most once per
7069 // updateImpl call and only if we use the free check reasoning.
7070 bool HasUpdatedFrees = false;
7071
7072 auto UpdateFrees = [&]() {
7073 HasUpdatedFrees = true;
7074
7075 for (auto &It : DeallocationInfos) {
7076 DeallocationInfo &DI = *It.second;
7077 // For now we cannot use deallocations that have unknown inputs, skip
7078 // them.
7079 if (DI.MightFreeUnknownObjects)
7080 continue;
7081
7082 // No need to analyze dead calls, ignore them instead.
7083 bool UsedAssumedInformation = false;
7084 if (A.isAssumedDead(*DI.CB, this, LivenessAA, UsedAssumedInformation,
7085 /* CheckBBLivenessOnly */ true))
7086 continue;
7087
7088 // Use the non-optimistic version to get the freed object.
7089 Value *Obj = getUnderlyingObject(DI.FreedOp);
7090 if (!Obj) {
7091 LLVM_DEBUG(dbgs() << "[H2S] Unknown underlying object for free!\n");
7092 DI.MightFreeUnknownObjects = true;
7093 continue;
7094 }
7095
7096 // Free of null and undef can be ignored as no-ops (or UB in the latter
7097 // case).
7099 continue;
7100
7101 CallBase *ObjCB = dyn_cast<CallBase>(Obj);
7102 if (!ObjCB) {
7103 LLVM_DEBUG(dbgs() << "[H2S] Free of a non-call object: " << *Obj
7104 << "\n");
7105 DI.MightFreeUnknownObjects = true;
7106 continue;
7107 }
7108
7109 AllocationInfo *AI = AllocationInfos.lookup(ObjCB);
7110 if (!AI) {
7111 LLVM_DEBUG(dbgs() << "[H2S] Free of a non-allocation object: " << *Obj
7112 << "\n");
7113 DI.MightFreeUnknownObjects = true;
7114 continue;
7115 }
7116
7117 DI.PotentialAllocationCalls.insert(ObjCB);
7118 }
7119 };
7120
7121 auto FreeCheck = [&](AllocationInfo &AI) {
7122 // If the stack is not accessible by other threads, the "must-free" logic
7123 // doesn't apply as the pointer could be shared and needs to be places in
7124 // "shareable" memory.
7125 if (!StackIsAccessibleByOtherThreads) {
7126 bool IsKnownNoSycn;
7128 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNoSycn)) {
7129 LLVM_DEBUG(
7130 dbgs() << "[H2S] found an escaping use, stack is not accessible by "
7131 "other threads and function is not nosync:\n");
7132 return false;
7133 }
7134 }
7135 if (!HasUpdatedFrees)
7136 UpdateFrees();
7137
7138 // TODO: Allow multi exit functions that have different free calls.
7139 if (AI.PotentialFreeCalls.size() != 1) {
7140 LLVM_DEBUG(dbgs() << "[H2S] did not find one free call but "
7141 << AI.PotentialFreeCalls.size() << "\n");
7142 return false;
7143 }
7144 CallBase *UniqueFree = *AI.PotentialFreeCalls.begin();
7145 DeallocationInfo *DI = DeallocationInfos.lookup(UniqueFree);
7146 if (!DI) {
7147 LLVM_DEBUG(
7148 dbgs() << "[H2S] unique free call was not known as deallocation call "
7149 << *UniqueFree << "\n");
7150 return false;
7151 }
7152 if (DI->MightFreeUnknownObjects) {
7153 LLVM_DEBUG(
7154 dbgs() << "[H2S] unique free call might free unknown allocations\n");
7155 return false;
7156 }
7157 if (DI->PotentialAllocationCalls.empty())
7158 return true;
7159 if (DI->PotentialAllocationCalls.size() > 1) {
7160 LLVM_DEBUG(dbgs() << "[H2S] unique free call might free "
7161 << DI->PotentialAllocationCalls.size()
7162 << " different allocations\n");
7163 return false;
7164 }
7165 if (*DI->PotentialAllocationCalls.begin() != AI.CB) {
7166 LLVM_DEBUG(
7167 dbgs()
7168 << "[H2S] unique free call not known to free this allocation but "
7169 << **DI->PotentialAllocationCalls.begin() << "\n");
7170 return false;
7171 }
7172
7173 // __kmpc_alloc_shared and __kmpc_free_shared are by construction matched.
7174 if (!AI.IsGlobalizedLocal) {
7175 Instruction *CtxI = isa<InvokeInst>(AI.CB) ? AI.CB : AI.CB->getNextNode();
7176 if (!Explorer || !Explorer->findInContextOf(UniqueFree, CtxI)) {
7177 LLVM_DEBUG(dbgs() << "[H2S] unique free call might not be executed "
7178 "with the allocation "
7179 << *UniqueFree << "\n");
7180 return false;
7181 }
7182 }
7183 return true;
7184 };
7185
7186 auto UsesCheck = [&](AllocationInfo &AI) {
7187 bool ValidUsesOnly = true;
7188
7189 auto Pred = [&](const Use &U, bool &Follow) -> bool {
7190 Instruction *UserI = cast<Instruction>(U.getUser());
7191 if (isa<LoadInst>(UserI))
7192 return true;
7193 if (auto *SI = dyn_cast<StoreInst>(UserI)) {
7194 if (SI->getValueOperand() == U.get()) {
7196 << "[H2S] escaping store to memory: " << *UserI << "\n");
7197 ValidUsesOnly = false;
7198 } else {
7199 // A store into the malloc'ed memory is fine.
7200 }
7201 return true;
7202 }
7203 if (auto *CB = dyn_cast<CallBase>(UserI)) {
7204 if (!CB->isArgOperand(&U) || CB->isLifetimeStartOrEnd())
7205 return true;
7206 if (DeallocationInfos.count(CB)) {
7207 AI.PotentialFreeCalls.insert(CB);
7208 return true;
7209 }
7210
7211 unsigned ArgNo = CB->getArgOperandNo(&U);
7212 auto CBIRP = IRPosition::callsite_argument(*CB, ArgNo);
7213
7214 bool IsKnownNoCapture;
7215 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
7216 A, this, CBIRP, DepClassTy::OPTIONAL, IsKnownNoCapture);
7217
7218 // If a call site argument use is nofree, we are fine.
7219 bool IsKnownNoFree;
7220 bool IsAssumedNoFree = AA::hasAssumedIRAttr<Attribute::NoFree>(
7221 A, this, CBIRP, DepClassTy::OPTIONAL, IsKnownNoFree);
7222
7223 if (!IsAssumedNoCapture ||
7224 (!AI.IsGlobalizedLocal && !IsAssumedNoFree)) {
7225 AI.HasPotentiallyFreeingUnknownUses |= !IsAssumedNoFree;
7226
7227 // Emit a missed remark if this is missed OpenMP globalization.
7228 auto Remark = [&](OptimizationRemarkMissed ORM) {
7229 return ORM
7230 << "Could not move globalized variable to the stack. "
7231 "Variable is potentially captured in call. Mark "
7232 "parameter as `__attribute__((noescape))` to override.";
7233 };
7234
7235 if (ValidUsesOnly && AI.IsGlobalizedLocal)
7236 A.emitRemark<OptimizationRemarkMissed>(CB, "OMP113", Remark);
7237
7238 LLVM_DEBUG(dbgs() << "[H2S] Bad user: " << *UserI << "\n");
7239 ValidUsesOnly = false;
7240 }
7241 return true;
7242 }
7243
7244 if (isa<GetElementPtrInst>(UserI) || isa<BitCastInst>(UserI) ||
7245 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) {
7246 Follow = true;
7247 return true;
7248 }
7249 // Unknown user for which we can not track uses further (in a way that
7250 // makes sense).
7251 LLVM_DEBUG(dbgs() << "[H2S] Unknown user: " << *UserI << "\n");
7252 ValidUsesOnly = false;
7253 return true;
7254 };
7255 if (!A.checkForAllUses(Pred, *this, *AI.CB, /* CheckBBLivenessOnly */ false,
7256 DepClassTy::OPTIONAL, /* IgnoreDroppableUses */ true,
7257 [&](const Use &OldU, const Use &NewU) {
7258 auto *SI = dyn_cast<StoreInst>(OldU.getUser());
7259 return !SI || StackIsAccessibleByOtherThreads ||
7260 AA::isAssumedThreadLocalObject(
7261 A, *SI->getPointerOperand(), *this);
7262 }))
7263 return false;
7264 return ValidUsesOnly;
7265 };
7266
7267 // The actual update starts here. We look at all allocations and depending on
7268 // their status perform the appropriate check(s).
7269 for (auto &It : AllocationInfos) {
7270 AllocationInfo &AI = *It.second;
7271 if (AI.Status == AllocationInfo::INVALID)
7272 continue;
7273
7274 if (Value *Align = getAllocAlignment(AI.CB, TLI)) {
7275 std::optional<APInt> APAlign = getAPInt(A, *this, *Align);
7276 if (!APAlign) {
7277 // Can't generate an alloca which respects the required alignment
7278 // on the allocation.
7279 LLVM_DEBUG(dbgs() << "[H2S] Unknown allocation alignment: " << *AI.CB
7280 << "\n");
7281 AI.Status = AllocationInfo::INVALID;
7283 continue;
7284 }
7285 if (APAlign->ugt(llvm::Value::MaximumAlignment) ||
7286 !APAlign->isPowerOf2()) {
7287 LLVM_DEBUG(dbgs() << "[H2S] Invalid allocation alignment: " << APAlign
7288 << "\n");
7289 AI.Status = AllocationInfo::INVALID;
7291 continue;
7292 }
7293 }
7294
7295 std::optional<APInt> Size = getSize(A, *this, AI);
7296 if (!AI.IsGlobalizedLocal && MaxHeapToStackSize != -1) {
7297 if (!Size || Size->ugt(MaxHeapToStackSize)) {
7298 LLVM_DEBUG({
7299 if (!Size)
7300 dbgs() << "[H2S] Unknown allocation size: " << *AI.CB << "\n";
7301 else
7302 dbgs() << "[H2S] Allocation size too large: " << *AI.CB << " vs. "
7303 << MaxHeapToStackSize << "\n";
7304 });
7305
7306 AI.Status = AllocationInfo::INVALID;
7308 continue;
7309 }
7310 }
7311
7312 switch (AI.Status) {
7313 case AllocationInfo::STACK_DUE_TO_USE:
7314 if (UsesCheck(AI))
7315 break;
7316 AI.Status = AllocationInfo::STACK_DUE_TO_FREE;
7317 [[fallthrough]];
7318 case AllocationInfo::STACK_DUE_TO_FREE:
7319 if (FreeCheck(AI))
7320 break;
7321 AI.Status = AllocationInfo::INVALID;
7323 break;
7324 case AllocationInfo::INVALID:
7325 llvm_unreachable("Invalid allocations should never reach this point!");
7326 };
7327
7328 // Check if we still think we can move it into the entry block. If the
7329 // alloca comes from a converted __kmpc_alloc_shared then we can usually
7330 // ignore the potential complications associated with loops.
7331 bool IsGlobalizedLocal = AI.IsGlobalizedLocal;
7332 if (AI.MoveAllocaIntoEntry &&
7333 (!Size.has_value() ||
7334 (!IsGlobalizedLocal && IsInLoop(*AI.CB->getParent()))))
7335 AI.MoveAllocaIntoEntry = false;
7336 }
7337
7338 return Changed;
7339}
7340} // namespace
7341
7342/// ----------------------- Privatizable Pointers ------------------------------
7343namespace {
7344struct AAPrivatizablePtrImpl : public AAPrivatizablePtr {
7345 AAPrivatizablePtrImpl(const IRPosition &IRP, Attributor &A)
7346 : AAPrivatizablePtr(IRP, A), PrivatizableType(std::nullopt) {}
7347
7348 ChangeStatus indicatePessimisticFixpoint() override {
7349 AAPrivatizablePtr::indicatePessimisticFixpoint();
7350 PrivatizableType = nullptr;
7351 return ChangeStatus::CHANGED;
7352 }
7353
7354 /// Identify the type we can chose for a private copy of the underlying
7355 /// argument. std::nullopt means it is not clear yet, nullptr means there is
7356 /// none.
7357 virtual std::optional<Type *> identifyPrivatizableType(Attributor &A) = 0;
7358
7359 /// Return a privatizable type that encloses both T0 and T1.
7360 /// TODO: This is merely a stub for now as we should manage a mapping as well.
7361 std::optional<Type *> combineTypes(std::optional<Type *> T0,
7362 std::optional<Type *> T1) {
7363 if (!T0)
7364 return T1;
7365 if (!T1)
7366 return T0;
7367 if (T0 == T1)
7368 return T0;
7369 return nullptr;
7370 }
7371
7372 std::optional<Type *> getPrivatizableType() const override {
7373 return PrivatizableType;
7374 }
7375
7376 const std::string getAsStr(Attributor *A) const override {
7377 return isAssumedPrivatizablePtr() ? "[priv]" : "[no-priv]";
7378 }
7379
7380protected:
7381 std::optional<Type *> PrivatizableType;
7382};
7383
7384// TODO: Do this for call site arguments (probably also other values) as well.
7385
7386struct AAPrivatizablePtrArgument final : public AAPrivatizablePtrImpl {
7387 AAPrivatizablePtrArgument(const IRPosition &IRP, Attributor &A)
7388 : AAPrivatizablePtrImpl(IRP, A) {}
7389
7390 /// See AAPrivatizablePtrImpl::identifyPrivatizableType(...)
7391 std::optional<Type *> identifyPrivatizableType(Attributor &A) override {
7392 // If this is a byval argument and we know all the call sites (so we can
7393 // rewrite them), there is no need to check them explicitly.
7394 bool UsedAssumedInformation = false;
7396 A.getAttrs(getIRPosition(), {Attribute::ByVal}, Attrs,
7397 /* IgnoreSubsumingPositions */ true);
7398 if (!Attrs.empty() &&
7399 A.checkForAllCallSites([](AbstractCallSite ACS) { return true; }, *this,
7400 true, UsedAssumedInformation))
7401 return Attrs[0].getValueAsType();
7402
7403 std::optional<Type *> Ty;
7404 unsigned ArgNo = getIRPosition().getCallSiteArgNo();
7405
7406 // Make sure the associated call site argument has the same type at all call
7407 // sites and it is an allocation we know is safe to privatize, for now that
7408 // means we only allow alloca instructions.
7409 // TODO: We can additionally analyze the accesses in the callee to create
7410 // the type from that information instead. That is a little more
7411 // involved and will be done in a follow up patch.
7412 auto CallSiteCheck = [&](AbstractCallSite ACS) {
7413 IRPosition ACSArgPos = IRPosition::callsite_argument(ACS, ArgNo);
7414 // Check if a coresponding argument was found or if it is one not
7415 // associated (which can happen for callback calls).
7416 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
7417 return false;
7418
7419 // Check that all call sites agree on a type.
7420 auto *PrivCSArgAA =
7421 A.getAAFor<AAPrivatizablePtr>(*this, ACSArgPos, DepClassTy::REQUIRED);
7422 if (!PrivCSArgAA)
7423 return false;
7424 std::optional<Type *> CSTy = PrivCSArgAA->getPrivatizableType();
7425
7426 LLVM_DEBUG({
7427 dbgs() << "[AAPrivatizablePtr] ACSPos: " << ACSArgPos << ", CSTy: ";
7428 if (CSTy && *CSTy)
7429 (*CSTy)->print(dbgs());
7430 else if (CSTy)
7431 dbgs() << "<nullptr>";
7432 else
7433 dbgs() << "<none>";
7434 });
7435
7436 Ty = combineTypes(Ty, CSTy);
7437
7438 LLVM_DEBUG({
7439 dbgs() << " : New Type: ";
7440 if (Ty && *Ty)
7441 (*Ty)->print(dbgs());
7442 else if (Ty)
7443 dbgs() << "<nullptr>";
7444 else
7445 dbgs() << "<none>";
7446 dbgs() << "\n";
7447 });
7448
7449 return !Ty || *Ty;
7450 };
7451
7452 if (!A.checkForAllCallSites(CallSiteCheck, *this, true,
7453 UsedAssumedInformation))
7454 return nullptr;
7455 return Ty;
7456 }
7457
7458 /// See AbstractAttribute::updateImpl(...).
7459 ChangeStatus updateImpl(Attributor &A) override {
7460 PrivatizableType = identifyPrivatizableType(A);
7461 if (!PrivatizableType)
7462 return ChangeStatus::UNCHANGED;
7463 if (!*PrivatizableType)
7464 return indicatePessimisticFixpoint();
7465
7466 // The dependence is optional so we don't give up once we give up on the
7467 // alignment.
7468 A.getAAFor<AAAlign>(*this, IRPosition::value(getAssociatedValue()),
7469 DepClassTy::OPTIONAL);
7470
7471 // Avoid arguments with padding for now.
7472 if (!A.hasAttr(getIRPosition(), Attribute::ByVal) &&
7473 !isDenselyPacked(*PrivatizableType, A.getInfoCache().getDL())) {
7474 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Padding detected\n");
7475 return indicatePessimisticFixpoint();
7476 }
7477
7478 // Collect the types that will replace the privatizable type in the function
7479 // signature.
7480 SmallVector<Type *, 16> ReplacementTypes;
7481 identifyReplacementTypes(*PrivatizableType, ReplacementTypes);
7482
7483 // Verify callee and caller agree on how the promoted argument would be
7484 // passed.
7485 Function &Fn = *getIRPosition().getAnchorScope();
7486 const auto *TTI =
7487 A.getInfoCache().getAnalysisResultForFunction<TargetIRAnalysis>(Fn);
7488 if (!TTI) {
7489 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Missing TTI for function "
7490 << Fn.getName() << "\n");
7491 return indicatePessimisticFixpoint();
7492 }
7493
7494 auto CallSiteCheck = [&](AbstractCallSite ACS) {
7495 CallBase *CB = ACS.getInstruction();
7496 return TTI->areTypesABICompatible(
7497 CB->getCaller(),
7499 ReplacementTypes);
7500 };
7501 bool UsedAssumedInformation = false;
7502 if (!A.checkForAllCallSites(CallSiteCheck, *this, true,
7503 UsedAssumedInformation)) {
7504 LLVM_DEBUG(
7505 dbgs() << "[AAPrivatizablePtr] ABI incompatibility detected for "
7506 << Fn.getName() << "\n");
7507 return indicatePessimisticFixpoint();
7508 }
7509
7510 // Register a rewrite of the argument.
7511 Argument *Arg = getAssociatedArgument();
7512 if (!A.isValidFunctionSignatureRewrite(*Arg, ReplacementTypes)) {
7513 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Rewrite not valid\n");
7514 return indicatePessimisticFixpoint();
7515 }
7516
7517 unsigned ArgNo = Arg->getArgNo();
7518
7519 // Helper to check if for the given call site the associated argument is
7520 // passed to a callback where the privatization would be different.
7521 auto IsCompatiblePrivArgOfCallback = [&](CallBase &CB) {
7522 SmallVector<const Use *, 4> CallbackUses;
7523 AbstractCallSite::getCallbackUses(CB, CallbackUses);
7524 for (const Use *U : CallbackUses) {
7525 AbstractCallSite CBACS(U);
7526 assert(CBACS && CBACS.isCallbackCall());
7527 for (Argument &CBArg : CBACS.getCalledFunction()->args()) {
7528 int CBArgNo = CBACS.getCallArgOperandNo(CBArg);
7529
7530 LLVM_DEBUG({
7531 dbgs()
7532 << "[AAPrivatizablePtr] Argument " << *Arg
7533 << "check if can be privatized in the context of its parent ("
7534 << Arg->getParent()->getName()
7535 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7536 "callback ("
7537 << CBArgNo << "@" << CBACS.getCalledFunction()->getName()
7538 << ")\n[AAPrivatizablePtr] " << CBArg << " : "
7539 << CBACS.getCallArgOperand(CBArg) << " vs "
7540 << CB.getArgOperand(ArgNo) << "\n"
7541 << "[AAPrivatizablePtr] " << CBArg << " : "
7542 << CBACS.getCallArgOperandNo(CBArg) << " vs " << ArgNo << "\n";
7543 });
7544
7545 if (CBArgNo != int(ArgNo))
7546 continue;
7547 const auto *CBArgPrivAA = A.getAAFor<AAPrivatizablePtr>(
7548 *this, IRPosition::argument(CBArg), DepClassTy::REQUIRED);
7549 if (CBArgPrivAA && CBArgPrivAA->isValidState()) {
7550 auto CBArgPrivTy = CBArgPrivAA->getPrivatizableType();
7551 if (!CBArgPrivTy)
7552 continue;
7553 if (*CBArgPrivTy == PrivatizableType)
7554 continue;
7555 }
7556
7557 LLVM_DEBUG({
7558 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
7559 << " cannot be privatized in the context of its parent ("
7560 << Arg->getParent()->getName()
7561 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7562 "callback ("
7563 << CBArgNo << "@" << CBACS.getCalledFunction()->getName()
7564 << ").\n[AAPrivatizablePtr] for which the argument "
7565 "privatization is not compatible.\n";
7566 });
7567 return false;
7568 }
7569 }
7570 return true;
7571 };
7572
7573 // Helper to check if for the given call site the associated argument is
7574 // passed to a direct call where the privatization would be different.
7575 auto IsCompatiblePrivArgOfDirectCS = [&](AbstractCallSite ACS) {
7576 CallBase *DC = cast<CallBase>(ACS.getInstruction());
7577 int DCArgNo = ACS.getCallArgOperandNo(ArgNo);
7578 assert(DCArgNo >= 0 && unsigned(DCArgNo) < DC->arg_size() &&
7579 "Expected a direct call operand for callback call operand");
7580
7581 Function *DCCallee =
7583 LLVM_DEBUG({
7584 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
7585 << " check if be privatized in the context of its parent ("
7586 << Arg->getParent()->getName()
7587 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7588 "direct call of ("
7589 << DCArgNo << "@" << DCCallee->getName() << ").\n";
7590 });
7591
7592 if (unsigned(DCArgNo) < DCCallee->arg_size()) {
7593 const auto *DCArgPrivAA = A.getAAFor<AAPrivatizablePtr>(
7594 *this, IRPosition::argument(*DCCallee->getArg(DCArgNo)),
7595 DepClassTy::REQUIRED);
7596 if (DCArgPrivAA && DCArgPrivAA->isValidState()) {
7597 auto DCArgPrivTy = DCArgPrivAA->getPrivatizableType();
7598 if (!DCArgPrivTy)
7599 return true;
7600 if (*DCArgPrivTy == PrivatizableType)
7601 return true;
7602 }
7603 }
7604
7605 LLVM_DEBUG({
7606 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
7607 << " cannot be privatized in the context of its parent ("
7608 << Arg->getParent()->getName()
7609 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7610 "direct call of ("
7612 << ").\n[AAPrivatizablePtr] for which the argument "
7613 "privatization is not compatible.\n";
7614 });
7615 return false;
7616 };
7617
7618 // Helper to check if the associated argument is used at the given abstract
7619 // call site in a way that is incompatible with the privatization assumed
7620 // here.
7621 auto IsCompatiblePrivArgOfOtherCallSite = [&](AbstractCallSite ACS) {
7622 if (ACS.isDirectCall())
7623 return IsCompatiblePrivArgOfCallback(*ACS.getInstruction());
7624 if (ACS.isCallbackCall())
7625 return IsCompatiblePrivArgOfDirectCS(ACS);
7626 return false;
7627 };
7628
7629 if (!A.checkForAllCallSites(IsCompatiblePrivArgOfOtherCallSite, *this, true,
7630 UsedAssumedInformation))
7631 return indicatePessimisticFixpoint();
7632
7633 return ChangeStatus::UNCHANGED;
7634 }
7635
7636 /// Given a type to private \p PrivType, collect the constituates (which are
7637 /// used) in \p ReplacementTypes.
7638 static void
7639 identifyReplacementTypes(Type *PrivType,
7640 SmallVectorImpl<Type *> &ReplacementTypes) {
7641 // TODO: For now we expand the privatization type to the fullest which can
7642 // lead to dead arguments that need to be removed later.
7643 assert(PrivType && "Expected privatizable type!");
7644
7645 // Traverse the type, extract constituate types on the outermost level.
7646 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) {
7647 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++)
7648 ReplacementTypes.push_back(PrivStructType->getElementType(u));
7649 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) {
7650 ReplacementTypes.append(PrivArrayType->getNumElements(),
7651 PrivArrayType->getElementType());
7652 } else {
7653 ReplacementTypes.push_back(PrivType);
7654 }
7655 }
7656
7657 /// Initialize \p Base according to the type \p PrivType at position \p IP.
7658 /// The values needed are taken from the arguments of \p F starting at
7659 /// position \p ArgNo.
7660 static void createInitialization(Type *PrivType, Value &Base, Function &F,
7661 unsigned ArgNo, BasicBlock::iterator IP) {
7662 assert(PrivType && "Expected privatizable type!");
7663
7664 IRBuilder<NoFolder> IRB(IP);
7665 const DataLayout &DL = F.getDataLayout();
7666
7667 // Traverse the type, build GEPs and stores.
7668 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) {
7669 const StructLayout *PrivStructLayout = DL.getStructLayout(PrivStructType);
7670 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++) {
7671 Value *Ptr =
7672 constructPointer(&Base, PrivStructLayout->getElementOffset(u), IRB);
7673 new StoreInst(F.getArg(ArgNo + u), Ptr, IP);
7674 }
7675 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) {
7676 Type *PointeeTy = PrivArrayType->getElementType();
7677 uint64_t PointeeTySize = DL.getTypeStoreSize(PointeeTy);
7678 for (unsigned u = 0, e = PrivArrayType->getNumElements(); u < e; u++) {
7679 Value *Ptr = constructPointer(&Base, u * PointeeTySize, IRB);
7680 new StoreInst(F.getArg(ArgNo + u), Ptr, IP);
7681 }
7682 } else {
7683 new StoreInst(F.getArg(ArgNo), &Base, IP);
7684 }
7685 }
7686
7687 /// Extract values from \p Base according to the type \p PrivType at the
7688 /// call position \p ACS. The values are appended to \p ReplacementValues.
7689 void createReplacementValues(Align Alignment, Type *PrivType,
7690 AbstractCallSite ACS, Value *Base,
7691 SmallVectorImpl<Value *> &ReplacementValues) {
7692 assert(Base && "Expected base value!");
7693 assert(PrivType && "Expected privatizable type!");
7694 Instruction *IP = ACS.getInstruction();
7695
7696 IRBuilder<NoFolder> IRB(IP);
7697 const DataLayout &DL = IP->getDataLayout();
7698
7699 // Traverse the type, build GEPs and loads.
7700 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) {
7701 const StructLayout *PrivStructLayout = DL.getStructLayout(PrivStructType);
7702 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++) {
7703 Type *PointeeTy = PrivStructType->getElementType(u);
7704 Value *Ptr =
7705 constructPointer(Base, PrivStructLayout->getElementOffset(u), IRB);
7706 LoadInst *L = new LoadInst(PointeeTy, Ptr, "", IP->getIterator());
7707 L->setAlignment(Alignment);
7708 ReplacementValues.push_back(L);
7709 }
7710 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) {
7711 Type *PointeeTy = PrivArrayType->getElementType();
7712 uint64_t PointeeTySize = DL.getTypeStoreSize(PointeeTy);
7713 for (unsigned u = 0, e = PrivArrayType->getNumElements(); u < e; u++) {
7714 Value *Ptr = constructPointer(Base, u * PointeeTySize, IRB);
7715 LoadInst *L = new LoadInst(PointeeTy, Ptr, "", IP->getIterator());
7716 L->setAlignment(Alignment);
7717 ReplacementValues.push_back(L);
7718 }
7719 } else {
7720 LoadInst *L = new LoadInst(PrivType, Base, "", IP->getIterator());
7721 L->setAlignment(Alignment);
7722 ReplacementValues.push_back(L);
7723 }
7724 }
7725
7726 /// See AbstractAttribute::manifest(...)
7727 ChangeStatus manifest(Attributor &A) override {
7728 if (!PrivatizableType)
7729 return ChangeStatus::UNCHANGED;
7730 assert(*PrivatizableType && "Expected privatizable type!");
7731
7732 // Collect all tail calls in the function as we cannot allow new allocas to
7733 // escape into tail recursion.
7734 // TODO: Be smarter about new allocas escaping into tail calls.
7736 bool UsedAssumedInformation = false;
7737 if (!A.checkForAllInstructions(
7738 [&](Instruction &I) {
7739 CallInst &CI = cast<CallInst>(I);
7740 if (CI.isTailCall())
7741 TailCalls.push_back(&CI);
7742 return true;
7743 },
7744 *this, {Instruction::Call}, UsedAssumedInformation))
7745 return ChangeStatus::UNCHANGED;
7746
7747 Argument *Arg = getAssociatedArgument();
7748 // Query AAAlign attribute for alignment of associated argument to
7749 // determine the best alignment of loads.
7750 const auto *AlignAA =
7751 A.getAAFor<AAAlign>(*this, IRPosition::value(*Arg), DepClassTy::NONE);
7752
7753 // Callback to repair the associated function. A new alloca is placed at the
7754 // beginning and initialized with the values passed through arguments. The
7755 // new alloca replaces the use of the old pointer argument.
7757 [=](const Attributor::ArgumentReplacementInfo &ARI,
7758 Function &ReplacementFn, Function::arg_iterator ArgIt) {
7759 BasicBlock &EntryBB = ReplacementFn.getEntryBlock();
7761 const DataLayout &DL = IP->getDataLayout();
7762 unsigned AS = DL.getAllocaAddrSpace();
7763 Instruction *AI = new AllocaInst(*PrivatizableType, AS,
7764 Arg->getName() + ".priv", IP);
7765 createInitialization(*PrivatizableType, *AI, ReplacementFn,
7766 ArgIt->getArgNo(), IP);
7767
7768 if (AI->getType() != Arg->getType())
7769 AI = BitCastInst::CreatePointerBitCastOrAddrSpaceCast(
7770 AI, Arg->getType(), "", IP);
7771 Arg->replaceAllUsesWith(AI);
7772
7773 for (CallInst *CI : TailCalls)
7774 CI->setTailCall(false);
7775 };
7776
7777 // Callback to repair a call site of the associated function. The elements
7778 // of the privatizable type are loaded prior to the call and passed to the
7779 // new function version.
7781 [=](const Attributor::ArgumentReplacementInfo &ARI,
7782 AbstractCallSite ACS, SmallVectorImpl<Value *> &NewArgOperands) {
7783 // When no alignment is specified for the load instruction,
7784 // natural alignment is assumed.
7785 createReplacementValues(
7786 AlignAA ? AlignAA->getAssumedAlign() : Align(0),
7787 *PrivatizableType, ACS,
7788 ACS.getCallArgOperand(ARI.getReplacedArg().getArgNo()),
7789 NewArgOperands);
7790 };
7791
7792 // Collect the types that will replace the privatizable type in the function
7793 // signature.
7794 SmallVector<Type *, 16> ReplacementTypes;
7795 identifyReplacementTypes(*PrivatizableType, ReplacementTypes);
7796
7797 // Register a rewrite of the argument.
7798 if (A.registerFunctionSignatureRewrite(*Arg, ReplacementTypes,
7799 std::move(FnRepairCB),
7800 std::move(ACSRepairCB)))
7801 return ChangeStatus::CHANGED;
7802 return ChangeStatus::UNCHANGED;
7803 }
7804
7805 /// See AbstractAttribute::trackStatistics()
7806 void trackStatistics() const override {
7807 STATS_DECLTRACK_ARG_ATTR(privatizable_ptr);
7808 }
7809};
7810
7811struct AAPrivatizablePtrFloating : public AAPrivatizablePtrImpl {
7812 AAPrivatizablePtrFloating(const IRPosition &IRP, Attributor &A)
7813 : AAPrivatizablePtrImpl(IRP, A) {}
7814
7815 /// See AbstractAttribute::initialize(...).
7816 void initialize(Attributor &A) override {
7817 // TODO: We can privatize more than arguments.
7818 indicatePessimisticFixpoint();
7819 }
7820
7821 ChangeStatus updateImpl(Attributor &A) override {
7822 llvm_unreachable("AAPrivatizablePtr(Floating|Returned|CallSiteReturned)::"
7823 "updateImpl will not be called");
7824 }
7825
7826 /// See AAPrivatizablePtrImpl::identifyPrivatizableType(...)
7827 std::optional<Type *> identifyPrivatizableType(Attributor &A) override {
7828 Value *Obj = getUnderlyingObject(&getAssociatedValue());
7829 if (!Obj) {
7830 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] No underlying object found!\n");
7831 return nullptr;
7832 }
7833
7834 if (auto *AI = dyn_cast<AllocaInst>(Obj))
7835 if (auto *CI = dyn_cast<ConstantInt>(AI->getArraySize()))
7836 if (CI->isOne())
7837 return AI->getAllocatedType();
7838 if (auto *Arg = dyn_cast<Argument>(Obj)) {
7839 auto *PrivArgAA = A.getAAFor<AAPrivatizablePtr>(
7840 *this, IRPosition::argument(*Arg), DepClassTy::REQUIRED);
7841 if (PrivArgAA && PrivArgAA->isAssumedPrivatizablePtr())
7842 return PrivArgAA->getPrivatizableType();
7843 }
7844
7845 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Underlying object neither valid "
7846 "alloca nor privatizable argument: "
7847 << *Obj << "!\n");
7848 return nullptr;
7849 }
7850
7851 /// See AbstractAttribute::trackStatistics()
7852 void trackStatistics() const override {
7853 STATS_DECLTRACK_FLOATING_ATTR(privatizable_ptr);
7854 }
7855};
7856
7857struct AAPrivatizablePtrCallSiteArgument final
7858 : public AAPrivatizablePtrFloating {
7859 AAPrivatizablePtrCallSiteArgument(const IRPosition &IRP, Attributor &A)
7860 : AAPrivatizablePtrFloating(IRP, A) {}
7861
7862 /// See AbstractAttribute::initialize(...).
7863 void initialize(Attributor &A) override {
7864 if (A.hasAttr(getIRPosition(), Attribute::ByVal))
7865 indicateOptimisticFixpoint();
7866 }
7867
7868 /// See AbstractAttribute::updateImpl(...).
7869 ChangeStatus updateImpl(Attributor &A) override {
7870 PrivatizableType = identifyPrivatizableType(A);
7871 if (!PrivatizableType)
7872 return ChangeStatus::UNCHANGED;
7873 if (!*PrivatizableType)
7874 return indicatePessimisticFixpoint();
7875
7876 const IRPosition &IRP = getIRPosition();
7877 bool IsKnownNoCapture;
7878 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
7879 A, this, IRP, DepClassTy::REQUIRED, IsKnownNoCapture);
7880 if (!IsAssumedNoCapture) {
7881 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer might be captured!\n");
7882 return indicatePessimisticFixpoint();
7883 }
7884
7885 bool IsKnownNoAlias;
7887 A, this, IRP, DepClassTy::REQUIRED, IsKnownNoAlias)) {
7888 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer might alias!\n");
7889 return indicatePessimisticFixpoint();
7890 }
7891
7892 bool IsKnown;
7893 if (!AA::isAssumedReadOnly(A, IRP, *this, IsKnown)) {
7894 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer is written!\n");
7895 return indicatePessimisticFixpoint();
7896 }
7897
7898 return ChangeStatus::UNCHANGED;
7899 }
7900
7901 /// See AbstractAttribute::trackStatistics()
7902 void trackStatistics() const override {
7903 STATS_DECLTRACK_CSARG_ATTR(privatizable_ptr);
7904 }
7905};
7906
7907struct AAPrivatizablePtrCallSiteReturned final
7908 : public AAPrivatizablePtrFloating {
7909 AAPrivatizablePtrCallSiteReturned(const IRPosition &IRP, Attributor &A)
7910 : AAPrivatizablePtrFloating(IRP, A) {}
7911
7912 /// See AbstractAttribute::initialize(...).
7913 void initialize(Attributor &A) override {
7914 // TODO: We can privatize more than arguments.
7915 indicatePessimisticFixpoint();
7916 }
7917
7918 /// See AbstractAttribute::trackStatistics()
7919 void trackStatistics() const override {
7920 STATS_DECLTRACK_CSRET_ATTR(privatizable_ptr);
7921 }
7922};
7923
7924struct AAPrivatizablePtrReturned final : public AAPrivatizablePtrFloating {
7925 AAPrivatizablePtrReturned(const IRPosition &IRP, Attributor &A)
7926 : AAPrivatizablePtrFloating(IRP, A) {}
7927
7928 /// See AbstractAttribute::initialize(...).
7929 void initialize(Attributor &A) override {
7930 // TODO: We can privatize more than arguments.
7931 indicatePessimisticFixpoint();
7932 }
7933
7934 /// See AbstractAttribute::trackStatistics()
7935 void trackStatistics() const override {
7936 STATS_DECLTRACK_FNRET_ATTR(privatizable_ptr);
7937 }
7938};
7939} // namespace
7940
7941/// -------------------- Memory Behavior Attributes ----------------------------
7942/// Includes read-none, read-only, and write-only.
7943/// ----------------------------------------------------------------------------
7944namespace {
7945struct AAMemoryBehaviorImpl : public AAMemoryBehavior {
7946 AAMemoryBehaviorImpl(const IRPosition &IRP, Attributor &A)
7947 : AAMemoryBehavior(IRP, A) {}
7948
7949 /// See AbstractAttribute::initialize(...).
7950 void initialize(Attributor &A) override {
7951 intersectAssumedBits(BEST_STATE);
7952 getKnownStateFromValue(A, getIRPosition(), getState());
7953 AAMemoryBehavior::initialize(A);
7954 }
7955
7956 /// Return the memory behavior information encoded in the IR for \p IRP.
7957 static void getKnownStateFromValue(Attributor &A, const IRPosition &IRP,
7958 BitIntegerState &State,
7959 bool IgnoreSubsumingPositions = false) {
7961 A.getAttrs(IRP, AttrKinds, Attrs, IgnoreSubsumingPositions);
7962 for (const Attribute &Attr : Attrs) {
7963 switch (Attr.getKindAsEnum()) {
7964 case Attribute::ReadNone:
7965 State.addKnownBits(NO_ACCESSES);
7966 break;
7967 case Attribute::ReadOnly:
7968 State.addKnownBits(NO_WRITES);
7969 break;
7970 case Attribute::WriteOnly:
7971 State.addKnownBits(NO_READS);
7972 break;
7973 default:
7974 llvm_unreachable("Unexpected attribute!");
7975 }
7976 }
7977
7978 if (auto *I = dyn_cast<Instruction>(&IRP.getAnchorValue())) {
7979 if (!I->mayReadFromMemory())
7980 State.addKnownBits(NO_READS);
7981 if (!I->mayWriteToMemory())
7982 State.addKnownBits(NO_WRITES);
7983 }
7984 }
7985
7986 /// See AbstractAttribute::getDeducedAttributes(...).
7987 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
7988 SmallVectorImpl<Attribute> &Attrs) const override {
7989 assert(Attrs.size() == 0);
7990 if (isAssumedReadNone())
7991 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadNone));
7992 else if (isAssumedReadOnly())
7993 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadOnly));
7994 else if (isAssumedWriteOnly())
7995 Attrs.push_back(Attribute::get(Ctx, Attribute::WriteOnly));
7996 assert(Attrs.size() <= 1);
7997 }
7998
7999 /// See AbstractAttribute::manifest(...).
8000 ChangeStatus manifest(Attributor &A) override {
8001 const IRPosition &IRP = getIRPosition();
8002
8003 if (A.hasAttr(IRP, Attribute::ReadNone,
8004 /* IgnoreSubsumingPositions */ true))
8005 return ChangeStatus::UNCHANGED;
8006
8007 // Check if we would improve the existing attributes first.
8008 SmallVector<Attribute, 4> DeducedAttrs;
8009 getDeducedAttributes(A, IRP.getAnchorValue().getContext(), DeducedAttrs);
8010 if (llvm::all_of(DeducedAttrs, [&](const Attribute &Attr) {
8011 return A.hasAttr(IRP, Attr.getKindAsEnum(),
8012 /* IgnoreSubsumingPositions */ true);
8013 }))
8014 return ChangeStatus::UNCHANGED;
8015
8016 // Clear existing attributes.
8017 A.removeAttrs(IRP, AttrKinds);
8018 // Clear conflicting writable attribute.
8019 if (isAssumedReadOnly())
8020 A.removeAttrs(IRP, Attribute::Writable);
8021
8022 // Use the generic manifest method.
8023 return IRAttribute::manifest(A);
8024 }
8025
8026 /// See AbstractState::getAsStr().
8027 const std::string getAsStr(Attributor *A) const override {
8028 if (isAssumedReadNone())
8029 return "readnone";
8030 if (isAssumedReadOnly())
8031 return "readonly";
8032 if (isAssumedWriteOnly())
8033 return "writeonly";
8034 return "may-read/write";
8035 }
8036
8037 /// The set of IR attributes AAMemoryBehavior deals with.
8038 static const Attribute::AttrKind AttrKinds[3];
8039};
8040
8041const Attribute::AttrKind AAMemoryBehaviorImpl::AttrKinds[] = {
8042 Attribute::ReadNone, Attribute::ReadOnly, Attribute::WriteOnly};
8043
8044/// Memory behavior attribute for a floating value.
8045struct AAMemoryBehaviorFloating : AAMemoryBehaviorImpl {
8046 AAMemoryBehaviorFloating(const IRPosition &IRP, Attributor &A)
8047 : AAMemoryBehaviorImpl(IRP, A) {}
8048
8049 /// See AbstractAttribute::updateImpl(...).
8050 ChangeStatus updateImpl(Attributor &A) override;
8051
8052 /// See AbstractAttribute::trackStatistics()
8053 void trackStatistics() const override {
8054 if (isAssumedReadNone())
8056 else if (isAssumedReadOnly())
8058 else if (isAssumedWriteOnly())
8060 }
8061
8062private:
8063 /// Return true if users of \p UserI might access the underlying
8064 /// variable/location described by \p U and should therefore be analyzed.
8065 bool followUsersOfUseIn(Attributor &A, const Use &U,
8066 const Instruction *UserI);
8067
8068 /// Update the state according to the effect of use \p U in \p UserI.
8069 void analyzeUseIn(Attributor &A, const Use &U, const Instruction *UserI);
8070};
8071
8072/// Memory behavior attribute for function argument.
8073struct AAMemoryBehaviorArgument : AAMemoryBehaviorFloating {
8074 AAMemoryBehaviorArgument(const IRPosition &IRP, Attributor &A)
8075 : AAMemoryBehaviorFloating(IRP, A) {}
8076
8077 /// See AbstractAttribute::initialize(...).
8078 void initialize(Attributor &A) override {
8079 intersectAssumedBits(BEST_STATE);
8080 const IRPosition &IRP = getIRPosition();
8081 // TODO: Make IgnoreSubsumingPositions a property of an IRAttribute so we
8082 // can query it when we use has/getAttr. That would allow us to reuse the
8083 // initialize of the base class here.
8084 bool HasByVal = A.hasAttr(IRP, {Attribute::ByVal},
8085 /* IgnoreSubsumingPositions */ true);
8086 getKnownStateFromValue(A, IRP, getState(),
8087 /* IgnoreSubsumingPositions */ HasByVal);
8088 }
8089
8090 ChangeStatus manifest(Attributor &A) override {
8091 // TODO: Pointer arguments are not supported on vectors of pointers yet.
8092 if (!getAssociatedValue().getType()->isPointerTy())
8093 return ChangeStatus::UNCHANGED;
8094
8095 // TODO: From readattrs.ll: "inalloca parameters are always
8096 // considered written"
8097 if (A.hasAttr(getIRPosition(),
8098 {Attribute::InAlloca, Attribute::Preallocated})) {
8099 removeKnownBits(NO_WRITES);
8100 removeAssumedBits(NO_WRITES);
8101 }
8102 A.removeAttrs(getIRPosition(), AttrKinds);
8103 return AAMemoryBehaviorFloating::manifest(A);
8104 }
8105
8106 /// See AbstractAttribute::trackStatistics()
8107 void trackStatistics() const override {
8108 if (isAssumedReadNone())
8109 STATS_DECLTRACK_ARG_ATTR(readnone)
8110 else if (isAssumedReadOnly())
8111 STATS_DECLTRACK_ARG_ATTR(readonly)
8112 else if (isAssumedWriteOnly())
8113 STATS_DECLTRACK_ARG_ATTR(writeonly)
8114 }
8115};
8116
8117struct AAMemoryBehaviorCallSiteArgument final : AAMemoryBehaviorArgument {
8118 AAMemoryBehaviorCallSiteArgument(const IRPosition &IRP, Attributor &A)
8119 : AAMemoryBehaviorArgument(IRP, A) {}
8120
8121 /// See AbstractAttribute::initialize(...).
8122 void initialize(Attributor &A) override {
8123 // If we don't have an associated attribute this is either a variadic call
8124 // or an indirect call, either way, nothing to do here.
8125 Argument *Arg = getAssociatedArgument();
8126 if (!Arg) {
8127 indicatePessimisticFixpoint();
8128 return;
8129 }
8130 if (Arg->hasByValAttr()) {
8131 addKnownBits(NO_WRITES);
8132 removeKnownBits(NO_READS);
8133 removeAssumedBits(NO_READS);
8134 }
8135 AAMemoryBehaviorArgument::initialize(A);
8136 if (getAssociatedFunction()->isDeclaration())
8137 indicatePessimisticFixpoint();
8138 }
8139
8140 /// See AbstractAttribute::updateImpl(...).
8141 ChangeStatus updateImpl(Attributor &A) override {
8142 // TODO: Once we have call site specific value information we can provide
8143 // call site specific liveness liveness information and then it makes
8144 // sense to specialize attributes for call sites arguments instead of
8145 // redirecting requests to the callee argument.
8146 Argument *Arg = getAssociatedArgument();
8147 const IRPosition &ArgPos = IRPosition::argument(*Arg);
8148 auto *ArgAA =
8149 A.getAAFor<AAMemoryBehavior>(*this, ArgPos, DepClassTy::REQUIRED);
8150 if (!ArgAA)
8151 return indicatePessimisticFixpoint();
8152 return clampStateAndIndicateChange(getState(), ArgAA->getState());
8153 }
8154
8155 /// See AbstractAttribute::trackStatistics()
8156 void trackStatistics() const override {
8157 if (isAssumedReadNone())
8159 else if (isAssumedReadOnly())
8161 else if (isAssumedWriteOnly())
8163 }
8164};
8165
8166/// Memory behavior attribute for a call site return position.
8167struct AAMemoryBehaviorCallSiteReturned final : AAMemoryBehaviorFloating {
8168 AAMemoryBehaviorCallSiteReturned(const IRPosition &IRP, Attributor &A)
8169 : AAMemoryBehaviorFloating(IRP, A) {}
8170
8171 /// See AbstractAttribute::initialize(...).
8172 void initialize(Attributor &A) override {
8173 AAMemoryBehaviorImpl::initialize(A);
8174 }
8175 /// See AbstractAttribute::manifest(...).
8176 ChangeStatus manifest(Attributor &A) override {
8177 // We do not annotate returned values.
8178 return ChangeStatus::UNCHANGED;
8179 }
8180
8181 /// See AbstractAttribute::trackStatistics()
8182 void trackStatistics() const override {}
8183};
8184
8185/// An AA to represent the memory behavior function attributes.
8186struct AAMemoryBehaviorFunction final : public AAMemoryBehaviorImpl {
8187 AAMemoryBehaviorFunction(const IRPosition &IRP, Attributor &A)
8188 : AAMemoryBehaviorImpl(IRP, A) {}
8189
8190 /// See AbstractAttribute::updateImpl(Attributor &A).
8191 ChangeStatus updateImpl(Attributor &A) override;
8192
8193 /// See AbstractAttribute::manifest(...).
8194 ChangeStatus manifest(Attributor &A) override {
8195 // TODO: It would be better to merge this with AAMemoryLocation, so that
8196 // we could determine read/write per location. This would also have the
8197 // benefit of only one place trying to manifest the memory attribute.
8198 Function &F = cast<Function>(getAnchorValue());
8200 if (isAssumedReadNone())
8201 ME = MemoryEffects::none();
8202 else if (isAssumedReadOnly())
8204 else if (isAssumedWriteOnly())
8206
8207 A.removeAttrs(getIRPosition(), AttrKinds);
8208 // Clear conflicting writable attribute.
8209 if (ME.onlyReadsMemory())
8210 for (Argument &Arg : F.args())
8211 A.removeAttrs(IRPosition::argument(Arg), Attribute::Writable);
8212 return A.manifestAttrs(getIRPosition(),
8213 Attribute::getWithMemoryEffects(F.getContext(), ME));
8214 }
8215
8216 /// See AbstractAttribute::trackStatistics()
8217 void trackStatistics() const override {
8218 if (isAssumedReadNone())
8219 STATS_DECLTRACK_FN_ATTR(readnone)
8220 else if (isAssumedReadOnly())
8221 STATS_DECLTRACK_FN_ATTR(readonly)
8222 else if (isAssumedWriteOnly())
8223 STATS_DECLTRACK_FN_ATTR(writeonly)
8224 }
8225};
8226
8227/// AAMemoryBehavior attribute for call sites.
8228struct AAMemoryBehaviorCallSite final
8229 : AACalleeToCallSite<AAMemoryBehavior, AAMemoryBehaviorImpl> {
8230 AAMemoryBehaviorCallSite(const IRPosition &IRP, Attributor &A)
8231 : AACalleeToCallSite<AAMemoryBehavior, AAMemoryBehaviorImpl>(IRP, A) {}
8232
8233 /// See AbstractAttribute::manifest(...).
8234 ChangeStatus manifest(Attributor &A) override {
8235 // TODO: Deduplicate this with AAMemoryBehaviorFunction.
8236 CallBase &CB = cast<CallBase>(getAnchorValue());
8238 if (isAssumedReadNone())
8239 ME = MemoryEffects::none();
8240 else if (isAssumedReadOnly())
8242 else if (isAssumedWriteOnly())
8244
8245 A.removeAttrs(getIRPosition(), AttrKinds);
8246 // Clear conflicting writable attribute.
8247 if (ME.onlyReadsMemory())
8248 for (Use &U : CB.args())
8249 A.removeAttrs(IRPosition::callsite_argument(CB, U.getOperandNo()),
8250 Attribute::Writable);
8251 return A.manifestAttrs(
8252 getIRPosition(), Attribute::getWithMemoryEffects(CB.getContext(), ME));
8253 }
8254
8255 /// See AbstractAttribute::trackStatistics()
8256 void trackStatistics() const override {
8257 if (isAssumedReadNone())
8258 STATS_DECLTRACK_CS_ATTR(readnone)
8259 else if (isAssumedReadOnly())
8260 STATS_DECLTRACK_CS_ATTR(readonly)
8261 else if (isAssumedWriteOnly())
8262 STATS_DECLTRACK_CS_ATTR(writeonly)
8263 }
8264};
8265
8266ChangeStatus AAMemoryBehaviorFunction::updateImpl(Attributor &A) {
8267
8268 // The current assumed state used to determine a change.
8269 auto AssumedState = getAssumed();
8270
8271 auto CheckRWInst = [&](Instruction &I) {
8272 // If the instruction has an own memory behavior state, use it to restrict
8273 // the local state. No further analysis is required as the other memory
8274 // state is as optimistic as it gets.
8275 if (const auto *CB = dyn_cast<CallBase>(&I)) {
8276 const auto *MemBehaviorAA = A.getAAFor<AAMemoryBehavior>(
8278 if (MemBehaviorAA) {
8279 intersectAssumedBits(MemBehaviorAA->getAssumed());
8280 return !isAtFixpoint();
8281 }
8282 }
8283
8284 // Remove access kind modifiers if necessary.
8285 if (I.mayReadFromMemory())
8286 removeAssumedBits(NO_READS);
8287 if (I.mayWriteToMemory())
8288 removeAssumedBits(NO_WRITES);
8289 return !isAtFixpoint();
8290 };
8291
8292 bool UsedAssumedInformation = false;
8293 if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this,
8294 UsedAssumedInformation))
8295 return indicatePessimisticFixpoint();
8296
8297 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
8299}
8300
8301ChangeStatus AAMemoryBehaviorFloating::updateImpl(Attributor &A) {
8302
8303 const IRPosition &IRP = getIRPosition();
8304 const IRPosition &FnPos = IRPosition::function_scope(IRP);
8305 AAMemoryBehavior::StateType &S = getState();
8306
8307 // First, check the function scope. We take the known information and we avoid
8308 // work if the assumed information implies the current assumed information for
8309 // this attribute. This is a valid for all but byval arguments.
8310 Argument *Arg = IRP.getAssociatedArgument();
8311 AAMemoryBehavior::base_t FnMemAssumedState =
8313 if (!Arg || !Arg->hasByValAttr()) {
8314 const auto *FnMemAA =
8315 A.getAAFor<AAMemoryBehavior>(*this, FnPos, DepClassTy::OPTIONAL);
8316 if (FnMemAA) {
8317 FnMemAssumedState = FnMemAA->getAssumed();
8318 S.addKnownBits(FnMemAA->getKnown());
8319 if ((S.getAssumed() & FnMemAA->getAssumed()) == S.getAssumed())
8321 }
8322 }
8323
8324 // The current assumed state used to determine a change.
8325 auto AssumedState = S.getAssumed();
8326
8327 // Make sure the value is not captured (except through "return"), if
8328 // it is, any information derived would be irrelevant anyway as we cannot
8329 // check the potential aliases introduced by the capture. However, no need
8330 // to fall back to anythign less optimistic than the function state.
8331 bool IsKnownNoCapture;
8332 const AANoCapture *ArgNoCaptureAA = nullptr;
8333 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
8334 A, this, IRP, DepClassTy::OPTIONAL, IsKnownNoCapture, false,
8335 &ArgNoCaptureAA);
8336
8337 if (!IsAssumedNoCapture &&
8338 (!ArgNoCaptureAA || !ArgNoCaptureAA->isAssumedNoCaptureMaybeReturned())) {
8339 S.intersectAssumedBits(FnMemAssumedState);
8340 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
8342 }
8343
8344 // Visit and expand uses until all are analyzed or a fixpoint is reached.
8345 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
8346 Instruction *UserI = cast<Instruction>(U.getUser());
8347 LLVM_DEBUG(dbgs() << "[AAMemoryBehavior] Use: " << *U << " in " << *UserI
8348 << " \n");
8349
8350 // Droppable users, e.g., llvm::assume does not actually perform any action.
8351 if (UserI->isDroppable())
8352 return true;
8353
8354 // Check if the users of UserI should also be visited.
8355 Follow = followUsersOfUseIn(A, U, UserI);
8356
8357 // If UserI might touch memory we analyze the use in detail.
8358 if (UserI->mayReadOrWriteMemory())
8359 analyzeUseIn(A, U, UserI);
8360
8361 return !isAtFixpoint();
8362 };
8363
8364 if (!A.checkForAllUses(UsePred, *this, getAssociatedValue()))
8365 return indicatePessimisticFixpoint();
8366
8367 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
8369}
8370
8371bool AAMemoryBehaviorFloating::followUsersOfUseIn(Attributor &A, const Use &U,
8372 const Instruction *UserI) {
8373 // The loaded value is unrelated to the pointer argument, no need to
8374 // follow the users of the load.
8375 if (isa<LoadInst>(UserI) || isa<ReturnInst>(UserI))
8376 return false;
8377
8378 // By default we follow all uses assuming UserI might leak information on U,
8379 // we have special handling for call sites operands though.
8380 const auto *CB = dyn_cast<CallBase>(UserI);
8381 if (!CB || !CB->isArgOperand(&U))
8382 return true;
8383
8384 // If the use is a call argument known not to be captured, the users of
8385 // the call do not need to be visited because they have to be unrelated to
8386 // the input. Note that this check is not trivial even though we disallow
8387 // general capturing of the underlying argument. The reason is that the
8388 // call might the argument "through return", which we allow and for which we
8389 // need to check call users.
8390 if (U.get()->getType()->isPointerTy()) {
8391 unsigned ArgNo = CB->getArgOperandNo(&U);
8392 bool IsKnownNoCapture;
8394 A, this, IRPosition::callsite_argument(*CB, ArgNo),
8395 DepClassTy::OPTIONAL, IsKnownNoCapture);
8396 }
8397
8398 return true;
8399}
8400
8401void AAMemoryBehaviorFloating::analyzeUseIn(Attributor &A, const Use &U,
8402 const Instruction *UserI) {
8403 assert(UserI->mayReadOrWriteMemory());
8404
8405 switch (UserI->getOpcode()) {
8406 default:
8407 // TODO: Handle all atomics and other side-effect operations we know of.
8408 break;
8409 case Instruction::Load:
8410 // Loads cause the NO_READS property to disappear.
8411 removeAssumedBits(NO_READS);
8412 return;
8413
8414 case Instruction::Store:
8415 // Stores cause the NO_WRITES property to disappear if the use is the
8416 // pointer operand. Note that while capturing was taken care of somewhere
8417 // else we need to deal with stores of the value that is not looked through.
8418 if (cast<StoreInst>(UserI)->getPointerOperand() == U.get())
8419 removeAssumedBits(NO_WRITES);
8420 else
8421 indicatePessimisticFixpoint();
8422 return;
8423
8424 case Instruction::Call:
8425 case Instruction::CallBr:
8426 case Instruction::Invoke: {
8427 // For call sites we look at the argument memory behavior attribute (this
8428 // could be recursive!) in order to restrict our own state.
8429 const auto *CB = cast<CallBase>(UserI);
8430
8431 // Give up on operand bundles.
8432 if (CB->isBundleOperand(&U)) {
8433 indicatePessimisticFixpoint();
8434 return;
8435 }
8436
8437 // Calling a function does read the function pointer, maybe write it if the
8438 // function is self-modifying.
8439 if (CB->isCallee(&U)) {
8440 removeAssumedBits(NO_READS);
8441 break;
8442 }
8443
8444 // Adjust the possible access behavior based on the information on the
8445 // argument.
8446 IRPosition Pos;
8447 if (U.get()->getType()->isPointerTy())
8449 else
8451 const auto *MemBehaviorAA =
8452 A.getAAFor<AAMemoryBehavior>(*this, Pos, DepClassTy::OPTIONAL);
8453 if (!MemBehaviorAA)
8454 break;
8455 // "assumed" has at most the same bits as the MemBehaviorAA assumed
8456 // and at least "known".
8457 intersectAssumedBits(MemBehaviorAA->getAssumed());
8458 return;
8459 }
8460 };
8461
8462 // Generally, look at the "may-properties" and adjust the assumed state if we
8463 // did not trigger special handling before.
8464 if (UserI->mayReadFromMemory())
8465 removeAssumedBits(NO_READS);
8466 if (UserI->mayWriteToMemory())
8467 removeAssumedBits(NO_WRITES);
8468}
8469} // namespace
8470
8471/// -------------------- Memory Locations Attributes ---------------------------
8472/// Includes read-none, argmemonly, inaccessiblememonly,
8473/// inaccessiblememorargmemonly
8474/// ----------------------------------------------------------------------------
8475
8478 if (0 == (MLK & AAMemoryLocation::NO_LOCATIONS))
8479 return "all memory";
8481 return "no memory";
8482 std::string S = "memory:";
8483 if (0 == (MLK & AAMemoryLocation::NO_LOCAL_MEM))
8484 S += "stack,";
8485 if (0 == (MLK & AAMemoryLocation::NO_CONST_MEM))
8486 S += "constant,";
8488 S += "internal global,";
8490 S += "external global,";
8491 if (0 == (MLK & AAMemoryLocation::NO_ARGUMENT_MEM))
8492 S += "argument,";
8494 S += "inaccessible,";
8495 if (0 == (MLK & AAMemoryLocation::NO_MALLOCED_MEM))
8496 S += "malloced,";
8497 if (0 == (MLK & AAMemoryLocation::NO_UNKOWN_MEM))
8498 S += "unknown,";
8499 S.pop_back();
8500 return S;
8501}
8502
8503namespace {
8504struct AAMemoryLocationImpl : public AAMemoryLocation {
8505
8506 AAMemoryLocationImpl(const IRPosition &IRP, Attributor &A)
8507 : AAMemoryLocation(IRP, A), Allocator(A.Allocator) {
8508 AccessKind2Accesses.fill(nullptr);
8509 }
8510
8511 ~AAMemoryLocationImpl() override {
8512 // The AccessSets are allocated via a BumpPtrAllocator, we call
8513 // the destructor manually.
8514 for (AccessSet *AS : AccessKind2Accesses)
8515 if (AS)
8516 AS->~AccessSet();
8517 }
8518
8519 /// See AbstractAttribute::initialize(...).
8520 void initialize(Attributor &A) override {
8521 intersectAssumedBits(BEST_STATE);
8522 getKnownStateFromValue(A, getIRPosition(), getState());
8523 AAMemoryLocation::initialize(A);
8524 }
8525
8526 /// Return the memory behavior information encoded in the IR for \p IRP.
8527 static void getKnownStateFromValue(Attributor &A, const IRPosition &IRP,
8528 BitIntegerState &State,
8529 bool IgnoreSubsumingPositions = false) {
8530 // For internal functions we ignore `argmemonly` and
8531 // `inaccessiblememorargmemonly` as we might break it via interprocedural
8532 // constant propagation. It is unclear if this is the best way but it is
8533 // unlikely this will cause real performance problems. If we are deriving
8534 // attributes for the anchor function we even remove the attribute in
8535 // addition to ignoring it.
8536 // TODO: A better way to handle this would be to add ~NO_GLOBAL_MEM /
8537 // MemoryEffects::Other as a possible location.
8538 bool UseArgMemOnly = true;
8539 Function *AnchorFn = IRP.getAnchorScope();
8540 if (AnchorFn && A.isRunOn(*AnchorFn))
8541 UseArgMemOnly = !AnchorFn->hasLocalLinkage();
8542
8544 A.getAttrs(IRP, {Attribute::Memory}, Attrs, IgnoreSubsumingPositions);
8545 for (const Attribute &Attr : Attrs) {
8546 // TODO: We can map MemoryEffects to Attributor locations more precisely.
8547 MemoryEffects ME = Attr.getMemoryEffects();
8548 if (ME.doesNotAccessMemory()) {
8549 State.addKnownBits(NO_LOCAL_MEM | NO_CONST_MEM);
8550 continue;
8551 }
8552 if (ME.onlyAccessesInaccessibleMem()) {
8553 State.addKnownBits(inverseLocation(NO_INACCESSIBLE_MEM, true, true));
8554 continue;
8555 }
8556 if (ME.onlyAccessesArgPointees()) {
8557 if (UseArgMemOnly)
8558 State.addKnownBits(inverseLocation(NO_ARGUMENT_MEM, true, true));
8559 else {
8560 // Remove location information, only keep read/write info.
8561 ME = MemoryEffects(ME.getModRef());
8562 A.manifestAttrs(IRP,
8563 Attribute::getWithMemoryEffects(
8564 IRP.getAnchorValue().getContext(), ME),
8565 /*ForceReplace*/ true);
8566 }
8567 continue;
8568 }
8570 if (UseArgMemOnly)
8571 State.addKnownBits(inverseLocation(
8572 NO_INACCESSIBLE_MEM | NO_ARGUMENT_MEM, true, true));
8573 else {
8574 // Remove location information, only keep read/write info.
8575 ME = MemoryEffects(ME.getModRef());
8576 A.manifestAttrs(IRP,
8577 Attribute::getWithMemoryEffects(
8578 IRP.getAnchorValue().getContext(), ME),
8579 /*ForceReplace*/ true);
8580 }
8581 continue;
8582 }
8583 }
8584 }
8585
8586 /// See AbstractAttribute::getDeducedAttributes(...).
8587 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
8588 SmallVectorImpl<Attribute> &Attrs) const override {
8589 // TODO: We can map Attributor locations to MemoryEffects more precisely.
8590 assert(Attrs.size() == 0);
8591 if (getIRPosition().getPositionKind() == IRPosition::IRP_FUNCTION) {
8592 if (isAssumedReadNone())
8593 Attrs.push_back(
8594 Attribute::getWithMemoryEffects(Ctx, MemoryEffects::none()));
8595 else if (isAssumedInaccessibleMemOnly())
8596 Attrs.push_back(Attribute::getWithMemoryEffects(
8598 else if (isAssumedArgMemOnly())
8599 Attrs.push_back(
8600 Attribute::getWithMemoryEffects(Ctx, MemoryEffects::argMemOnly()));
8601 else if (isAssumedInaccessibleOrArgMemOnly())
8602 Attrs.push_back(Attribute::getWithMemoryEffects(
8604 }
8605 assert(Attrs.size() <= 1);
8606 }
8607
8608 /// See AbstractAttribute::manifest(...).
8609 ChangeStatus manifest(Attributor &A) override {
8610 // TODO: If AAMemoryLocation and AAMemoryBehavior are merged, we could
8611 // provide per-location modref information here.
8612 const IRPosition &IRP = getIRPosition();
8613
8614 SmallVector<Attribute, 1> DeducedAttrs;
8615 getDeducedAttributes(A, IRP.getAnchorValue().getContext(), DeducedAttrs);
8616 if (DeducedAttrs.size() != 1)
8617 return ChangeStatus::UNCHANGED;
8618 MemoryEffects ME = DeducedAttrs[0].getMemoryEffects();
8619
8620 return A.manifestAttrs(IRP, Attribute::getWithMemoryEffects(
8621 IRP.getAnchorValue().getContext(), ME));
8622 }
8623
8624 /// See AAMemoryLocation::checkForAllAccessesToMemoryKind(...).
8625 bool checkForAllAccessesToMemoryKind(
8626 function_ref<bool(const Instruction *, const Value *, AccessKind,
8627 MemoryLocationsKind)>
8628 Pred,
8629 MemoryLocationsKind RequestedMLK) const override {
8630 if (!isValidState())
8631 return false;
8632
8633 MemoryLocationsKind AssumedMLK = getAssumedNotAccessedLocation();
8634 if (AssumedMLK == NO_LOCATIONS)
8635 return true;
8636
8637 unsigned Idx = 0;
8638 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS;
8639 CurMLK *= 2, ++Idx) {
8640 if (CurMLK & RequestedMLK)
8641 continue;
8642
8643 if (const AccessSet *Accesses = AccessKind2Accesses[Idx])
8644 for (const AccessInfo &AI : *Accesses)
8645 if (!Pred(AI.I, AI.Ptr, AI.Kind, CurMLK))
8646 return false;
8647 }
8648
8649 return true;
8650 }
8651
8652 ChangeStatus indicatePessimisticFixpoint() override {
8653 // If we give up and indicate a pessimistic fixpoint this instruction will
8654 // become an access for all potential access kinds:
8655 // TODO: Add pointers for argmemonly and globals to improve the results of
8656 // checkForAllAccessesToMemoryKind.
8657 bool Changed = false;
8658 MemoryLocationsKind KnownMLK = getKnown();
8659 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
8660 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS; CurMLK *= 2)
8661 if (!(CurMLK & KnownMLK))
8662 updateStateAndAccessesMap(getState(), CurMLK, I, nullptr, Changed,
8663 getAccessKindFromInst(I));
8664 return AAMemoryLocation::indicatePessimisticFixpoint();
8665 }
8666
8667protected:
8668 /// Helper struct to tie together an instruction that has a read or write
8669 /// effect with the pointer it accesses (if any).
8670 struct AccessInfo {
8671
8672 /// The instruction that caused the access.
8673 const Instruction *I;
8674
8675 /// The base pointer that is accessed, or null if unknown.
8676 const Value *Ptr;
8677
8678 /// The kind of access (read/write/read+write).
8680
8681 bool operator==(const AccessInfo &RHS) const {
8682 return I == RHS.I && Ptr == RHS.Ptr && Kind == RHS.Kind;
8683 }
8684 bool operator()(const AccessInfo &LHS, const AccessInfo &RHS) const {
8685 if (LHS.I != RHS.I)
8686 return LHS.I < RHS.I;
8687 if (LHS.Ptr != RHS.Ptr)
8688 return LHS.Ptr < RHS.Ptr;
8689 if (LHS.Kind != RHS.Kind)
8690 return LHS.Kind < RHS.Kind;
8691 return false;
8692 }
8693 };
8694
8695 /// Mapping from *single* memory location kinds, e.g., LOCAL_MEM with the
8696 /// value of NO_LOCAL_MEM, to the accesses encountered for this memory kind.
8697 using AccessSet = SmallSet<AccessInfo, 2, AccessInfo>;
8698 std::array<AccessSet *, llvm::ConstantLog2<VALID_STATE>()>
8699 AccessKind2Accesses;
8700
8701 /// Categorize the pointer arguments of CB that might access memory in
8702 /// AccessedLoc and update the state and access map accordingly.
8703 void
8704 categorizeArgumentPointerLocations(Attributor &A, CallBase &CB,
8705 AAMemoryLocation::StateType &AccessedLocs,
8706 bool &Changed);
8707
8708 /// Return the kind(s) of location that may be accessed by \p V.
8710 categorizeAccessedLocations(Attributor &A, Instruction &I, bool &Changed);
8711
8712 /// Return the access kind as determined by \p I.
8713 AccessKind getAccessKindFromInst(const Instruction *I) {
8714 AccessKind AK = READ_WRITE;
8715 if (I) {
8716 AK = I->mayReadFromMemory() ? READ : NONE;
8717 AK = AccessKind(AK | (I->mayWriteToMemory() ? WRITE : NONE));
8718 }
8719 return AK;
8720 }
8721
8722 /// Update the state \p State and the AccessKind2Accesses given that \p I is
8723 /// an access of kind \p AK to a \p MLK memory location with the access
8724 /// pointer \p Ptr.
8725 void updateStateAndAccessesMap(AAMemoryLocation::StateType &State,
8726 MemoryLocationsKind MLK, const Instruction *I,
8727 const Value *Ptr, bool &Changed,
8728 AccessKind AK = READ_WRITE) {
8729
8730 assert(isPowerOf2_32(MLK) && "Expected a single location set!");
8731 auto *&Accesses = AccessKind2Accesses[llvm::Log2_32(MLK)];
8732 if (!Accesses)
8733 Accesses = new (Allocator) AccessSet();
8734 Changed |= Accesses->insert(AccessInfo{I, Ptr, AK}).second;
8735 if (MLK == NO_UNKOWN_MEM)
8736 MLK = NO_LOCATIONS;
8737 State.removeAssumedBits(MLK);
8738 }
8739
8740 /// Determine the underlying locations kinds for \p Ptr, e.g., globals or
8741 /// arguments, and update the state and access map accordingly.
8742 void categorizePtrValue(Attributor &A, const Instruction &I, const Value &Ptr,
8743 AAMemoryLocation::StateType &State, bool &Changed,
8744 unsigned AccessAS = 0);
8745
8746 /// Used to allocate access sets.
8748};
8749
8750void AAMemoryLocationImpl::categorizePtrValue(
8751 Attributor &A, const Instruction &I, const Value &Ptr,
8752 AAMemoryLocation::StateType &State, bool &Changed, unsigned AccessAS) {
8753 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize pointer locations for "
8754 << Ptr << " ["
8755 << getMemoryLocationsAsStr(State.getAssumed()) << "]\n");
8756
8757 auto Pred = [&](Value &Obj) {
8758 unsigned ObjectAS = Obj.getType()->getPointerAddressSpace();
8759 // TODO: recognize the TBAA used for constant accesses.
8760 MemoryLocationsKind MLK = NO_LOCATIONS;
8761
8762 // Filter accesses to constant (GPU) memory if we have an AS at the access
8763 // site or the object is known to actually have the associated AS.
8764 if (AA::isGPU(A.getModule())) {
8765 if (AA::isGPUConstantAddressSpace(A.getModule(), AccessAS) ||
8766 (AA::isGPUConstantAddressSpace(A.getModule(), ObjectAS) &&
8767 isIdentifiedObject(&Obj)))
8768 return true;
8769 }
8770
8771 if (isa<UndefValue>(&Obj))
8772 return true;
8773 if (isa<Argument>(&Obj)) {
8774 // TODO: For now we do not treat byval arguments as local copies performed
8775 // on the call edge, though, we should. To make that happen we need to
8776 // teach various passes, e.g., DSE, about the copy effect of a byval. That
8777 // would also allow us to mark functions only accessing byval arguments as
8778 // readnone again, arguably their accesses have no effect outside of the
8779 // function, like accesses to allocas.
8780 MLK = NO_ARGUMENT_MEM;
8781 } else if (auto *GV = dyn_cast<GlobalValue>(&Obj)) {
8782 // Reading constant memory is not treated as a read "effect" by the
8783 // function attr pass so we won't neither. Constants defined by TBAA are
8784 // similar. (We know we do not write it because it is constant.)
8785 if (auto *GVar = dyn_cast<GlobalVariable>(GV))
8786 if (GVar->isConstant())
8787 return true;
8788
8789 if (GV->hasLocalLinkage())
8790 MLK = NO_GLOBAL_INTERNAL_MEM;
8791 else
8792 MLK = NO_GLOBAL_EXTERNAL_MEM;
8793 } else if (isa<ConstantPointerNull>(&Obj) && ObjectAS == AccessAS &&
8794 !NullPointerIsDefined(getAssociatedFunction(), AccessAS)) {
8795 // Accessing null is undefined, but not accessing a null pointer cast to
8796 // another address space, which may be a valid address there.
8797 return true;
8798 } else if (isa<AllocaInst>(&Obj)) {
8799 MLK = NO_LOCAL_MEM;
8800 } else if (const auto *CB = dyn_cast<CallBase>(&Obj)) {
8801 bool IsKnownNoAlias;
8804 IsKnownNoAlias))
8805 MLK = NO_MALLOCED_MEM;
8806 else
8807 MLK = NO_UNKOWN_MEM;
8808 } else {
8809 MLK = NO_UNKOWN_MEM;
8810 }
8811
8812 assert(MLK != NO_LOCATIONS && "No location specified!");
8813 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Ptr value can be categorized: "
8814 << Obj << " -> " << getMemoryLocationsAsStr(MLK) << "\n");
8815 updateStateAndAccessesMap(State, MLK, &I, &Obj, Changed,
8816 getAccessKindFromInst(&I));
8817
8818 return true;
8819 };
8820
8821 const auto *AA = A.getAAFor<AAUnderlyingObjects>(
8823 if (!AA || !AA->forallUnderlyingObjects(Pred, AA::Intraprocedural)) {
8824 LLVM_DEBUG(
8825 dbgs() << "[AAMemoryLocation] Pointer locations not categorized\n");
8826 updateStateAndAccessesMap(State, NO_UNKOWN_MEM, &I, nullptr, Changed,
8827 getAccessKindFromInst(&I));
8828 return;
8829 }
8830
8831 LLVM_DEBUG(
8832 dbgs() << "[AAMemoryLocation] Accessed locations with pointer locations: "
8833 << getMemoryLocationsAsStr(State.getAssumed()) << "\n");
8834}
8835
8836void AAMemoryLocationImpl::categorizeArgumentPointerLocations(
8837 Attributor &A, CallBase &CB, AAMemoryLocation::StateType &AccessedLocs,
8838 bool &Changed) {
8839 for (unsigned ArgNo = 0, E = CB.arg_size(); ArgNo < E; ++ArgNo) {
8840
8841 // Skip non-pointer arguments.
8842 const Value *ArgOp = CB.getArgOperand(ArgNo);
8843 if (!ArgOp->getType()->isPtrOrPtrVectorTy())
8844 continue;
8845
8846 // Skip readnone arguments.
8847 const IRPosition &ArgOpIRP = IRPosition::callsite_argument(CB, ArgNo);
8848 const auto *ArgOpMemLocationAA =
8849 A.getAAFor<AAMemoryBehavior>(*this, ArgOpIRP, DepClassTy::OPTIONAL);
8850
8851 if (ArgOpMemLocationAA && ArgOpMemLocationAA->isAssumedReadNone())
8852 continue;
8853
8854 // Categorize potentially accessed pointer arguments as if there was an
8855 // access instruction with them as pointer.
8856 categorizePtrValue(A, CB, *ArgOp, AccessedLocs, Changed);
8857 }
8858}
8859
8861AAMemoryLocationImpl::categorizeAccessedLocations(Attributor &A, Instruction &I,
8862 bool &Changed) {
8863 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize accessed locations for "
8864 << I << "\n");
8865
8866 AAMemoryLocation::StateType AccessedLocs;
8867 AccessedLocs.intersectAssumedBits(NO_LOCATIONS);
8868
8869 if (auto *CB = dyn_cast<CallBase>(&I)) {
8870
8871 // First check if we assume any memory is access is visible.
8872 const auto *CBMemLocationAA = A.getAAFor<AAMemoryLocation>(
8874 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize call site: " << I
8875 << " [" << CBMemLocationAA << "]\n");
8876 if (!CBMemLocationAA) {
8877 updateStateAndAccessesMap(AccessedLocs, NO_UNKOWN_MEM, &I, nullptr,
8878 Changed, getAccessKindFromInst(&I));
8879 return NO_UNKOWN_MEM;
8880 }
8881
8882 if (CBMemLocationAA->isAssumedReadNone())
8883 return NO_LOCATIONS;
8884
8885 if (CBMemLocationAA->isAssumedInaccessibleMemOnly()) {
8886 updateStateAndAccessesMap(AccessedLocs, NO_INACCESSIBLE_MEM, &I, nullptr,
8887 Changed, getAccessKindFromInst(&I));
8888 return AccessedLocs.getAssumed();
8889 }
8890
8891 uint32_t CBAssumedNotAccessedLocs =
8892 CBMemLocationAA->getAssumedNotAccessedLocation();
8893
8894 // Set the argmemonly and global bit as we handle them separately below.
8895 uint32_t CBAssumedNotAccessedLocsNoArgMem =
8896 CBAssumedNotAccessedLocs | NO_ARGUMENT_MEM | NO_GLOBAL_MEM;
8897
8898 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS; CurMLK *= 2) {
8899 if (CBAssumedNotAccessedLocsNoArgMem & CurMLK)
8900 continue;
8901 updateStateAndAccessesMap(AccessedLocs, CurMLK, &I, nullptr, Changed,
8902 getAccessKindFromInst(&I));
8903 }
8904
8905 // Now handle global memory if it might be accessed. This is slightly tricky
8906 // as NO_GLOBAL_MEM has multiple bits set.
8907 bool HasGlobalAccesses = ((~CBAssumedNotAccessedLocs) & NO_GLOBAL_MEM);
8908 if (HasGlobalAccesses) {
8909 auto AccessPred = [&](const Instruction *, const Value *Ptr,
8910 AccessKind Kind, MemoryLocationsKind MLK) {
8911 updateStateAndAccessesMap(AccessedLocs, MLK, &I, Ptr, Changed,
8912 getAccessKindFromInst(&I));
8913 return true;
8914 };
8915 if (!CBMemLocationAA->checkForAllAccessesToMemoryKind(
8916 AccessPred, inverseLocation(NO_GLOBAL_MEM, false, false)))
8917 return AccessedLocs.getWorstState();
8918 }
8919
8920 LLVM_DEBUG(
8921 dbgs() << "[AAMemoryLocation] Accessed state before argument handling: "
8922 << getMemoryLocationsAsStr(AccessedLocs.getAssumed()) << "\n");
8923
8924 // Now handle argument memory if it might be accessed.
8925 bool HasArgAccesses = ((~CBAssumedNotAccessedLocs) & NO_ARGUMENT_MEM);
8926 if (HasArgAccesses)
8927 categorizeArgumentPointerLocations(A, *CB, AccessedLocs, Changed);
8928
8929 LLVM_DEBUG(
8930 dbgs() << "[AAMemoryLocation] Accessed state after argument handling: "
8931 << getMemoryLocationsAsStr(AccessedLocs.getAssumed()) << "\n");
8932
8933 return AccessedLocs.getAssumed();
8934 }
8935
8936 if (const Value *Ptr = getPointerOperand(&I, /* AllowVolatile */ true)) {
8937 LLVM_DEBUG(
8938 dbgs() << "[AAMemoryLocation] Categorize memory access with pointer: "
8939 << I << " [" << *Ptr << "]\n");
8940 categorizePtrValue(A, I, *Ptr, AccessedLocs, Changed,
8941 Ptr->getType()->getPointerAddressSpace());
8942 return AccessedLocs.getAssumed();
8943 }
8944
8945 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Failed to categorize instruction: "
8946 << I << "\n");
8947 updateStateAndAccessesMap(AccessedLocs, NO_UNKOWN_MEM, &I, nullptr, Changed,
8948 getAccessKindFromInst(&I));
8949 return AccessedLocs.getAssumed();
8950}
8951
8952/// An AA to represent the memory behavior function attributes.
8953struct AAMemoryLocationFunction final : public AAMemoryLocationImpl {
8954 AAMemoryLocationFunction(const IRPosition &IRP, Attributor &A)
8955 : AAMemoryLocationImpl(IRP, A) {}
8956
8957 /// See AbstractAttribute::updateImpl(Attributor &A).
8958 ChangeStatus updateImpl(Attributor &A) override {
8959
8960 const auto *MemBehaviorAA =
8961 A.getAAFor<AAMemoryBehavior>(*this, getIRPosition(), DepClassTy::NONE);
8962 if (MemBehaviorAA && MemBehaviorAA->isAssumedReadNone()) {
8963 if (MemBehaviorAA->isKnownReadNone())
8964 return indicateOptimisticFixpoint();
8966 "AAMemoryLocation was not read-none but AAMemoryBehavior was!");
8967 A.recordDependence(*MemBehaviorAA, *this, DepClassTy::OPTIONAL);
8968 return ChangeStatus::UNCHANGED;
8969 }
8970
8971 // The current assumed state used to determine a change.
8972 auto AssumedState = getAssumed();
8973 bool Changed = false;
8974
8975 auto CheckRWInst = [&](Instruction &I) {
8976 MemoryLocationsKind MLK = categorizeAccessedLocations(A, I, Changed);
8977 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Accessed locations for " << I
8978 << ": " << getMemoryLocationsAsStr(MLK) << "\n");
8979 removeAssumedBits(inverseLocation(MLK, false, false));
8980 // Stop once only the valid bit set in the *not assumed location*, thus
8981 // once we don't actually exclude any memory locations in the state.
8982 return getAssumedNotAccessedLocation() != VALID_STATE;
8983 };
8984
8985 bool UsedAssumedInformation = false;
8986 if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this,
8987 UsedAssumedInformation))
8988 return indicatePessimisticFixpoint();
8989
8990 Changed |= AssumedState != getAssumed();
8991 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
8992 }
8993
8994 /// See AbstractAttribute::trackStatistics()
8995 void trackStatistics() const override {
8996 if (isAssumedReadNone())
8997 STATS_DECLTRACK_FN_ATTR(readnone)
8998 else if (isAssumedArgMemOnly())
8999 STATS_DECLTRACK_FN_ATTR(argmemonly)
9000 else if (isAssumedInaccessibleMemOnly())
9001 STATS_DECLTRACK_FN_ATTR(inaccessiblememonly)
9002 else if (isAssumedInaccessibleOrArgMemOnly())
9003 STATS_DECLTRACK_FN_ATTR(inaccessiblememorargmemonly)
9004 }
9005};
9006
9007/// AAMemoryLocation attribute for call sites.
9008struct AAMemoryLocationCallSite final : AAMemoryLocationImpl {
9009 AAMemoryLocationCallSite(const IRPosition &IRP, Attributor &A)
9010 : AAMemoryLocationImpl(IRP, A) {}
9011
9012 /// See AbstractAttribute::updateImpl(...).
9013 ChangeStatus updateImpl(Attributor &A) override {
9014 // TODO: Once we have call site specific value information we can provide
9015 // call site specific liveness liveness information and then it makes
9016 // sense to specialize attributes for call sites arguments instead of
9017 // redirecting requests to the callee argument.
9018 Function *F = getAssociatedFunction();
9019 const IRPosition &FnPos = IRPosition::function(*F);
9020 auto *FnAA =
9021 A.getAAFor<AAMemoryLocation>(*this, FnPos, DepClassTy::REQUIRED);
9022 if (!FnAA)
9023 return indicatePessimisticFixpoint();
9024 bool Changed = false;
9025 auto AccessPred = [&](const Instruction *I, const Value *Ptr,
9026 AccessKind Kind, MemoryLocationsKind MLK) {
9027 updateStateAndAccessesMap(getState(), MLK, I, Ptr, Changed,
9028 getAccessKindFromInst(I));
9029 return true;
9030 };
9031 if (!FnAA->checkForAllAccessesToMemoryKind(AccessPred, ALL_LOCATIONS))
9032 return indicatePessimisticFixpoint();
9033 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
9034 }
9035
9036 /// See AbstractAttribute::trackStatistics()
9037 void trackStatistics() const override {
9038 if (isAssumedReadNone())
9039 STATS_DECLTRACK_CS_ATTR(readnone)
9040 }
9041};
9042} // namespace
9043
9044/// ------------------ denormal-fp-math Attribute -------------------------
9045
9046namespace {
9047struct AADenormalFPMathImpl : public AADenormalFPMath {
9048 AADenormalFPMathImpl(const IRPosition &IRP, Attributor &A)
9049 : AADenormalFPMath(IRP, A) {}
9050
9051 const std::string getAsStr(Attributor *A) const override {
9052 std::string Str("AADenormalFPMath[");
9053 raw_string_ostream OS(Str);
9054
9055 DenormalState Known = getKnown();
9056 if (Known.Mode.isValid())
9057 OS << "denormal-fp-math=" << Known.Mode;
9058 else
9059 OS << "invalid";
9060
9061 if (Known.ModeF32.isValid())
9062 OS << " denormal-fp-math-f32=" << Known.ModeF32;
9063 OS << ']';
9064 return Str;
9065 }
9066};
9067
9068struct AADenormalFPMathFunction final : AADenormalFPMathImpl {
9069 AADenormalFPMathFunction(const IRPosition &IRP, Attributor &A)
9070 : AADenormalFPMathImpl(IRP, A) {}
9071
9072 void initialize(Attributor &A) override {
9073 const Function *F = getAnchorScope();
9074 DenormalFPEnv DenormEnv = F->getDenormalFPEnv();
9075
9076 Known = DenormalState{DenormEnv.DefaultMode, DenormEnv.F32Mode};
9077 if (isModeFixed())
9078 indicateFixpoint();
9079 }
9080
9081 ChangeStatus updateImpl(Attributor &A) override {
9082 ChangeStatus Change = ChangeStatus::UNCHANGED;
9083
9084 auto CheckCallSite = [=, &Change, &A](AbstractCallSite CS) {
9085 Function *Caller = CS.getInstruction()->getFunction();
9086 LLVM_DEBUG(dbgs() << "[AADenormalFPMath] Call " << Caller->getName()
9087 << "->" << getAssociatedFunction()->getName() << '\n');
9088
9089 const auto *CallerInfo = A.getAAFor<AADenormalFPMath>(
9090 *this, IRPosition::function(*Caller), DepClassTy::REQUIRED);
9091 if (!CallerInfo)
9092 return false;
9093
9094 Change = Change | clampStateAndIndicateChange(this->getState(),
9095 CallerInfo->getState());
9096 return true;
9097 };
9098
9099 bool AllCallSitesKnown = true;
9100 if (!A.checkForAllCallSites(CheckCallSite, *this, true, AllCallSitesKnown))
9101 return indicatePessimisticFixpoint();
9102
9103 if (Change == ChangeStatus::CHANGED && isModeFixed())
9104 indicateFixpoint();
9105 return Change;
9106 }
9107
9108 ChangeStatus manifest(Attributor &A) override {
9109 LLVMContext &Ctx = getAssociatedFunction()->getContext();
9110
9111 SmallVector<Attribute, 2> AttrToAdd;
9113
9114 // TODO: Change to use DenormalFPEnv everywhere.
9115 DenormalFPEnv KnownEnv(Known.Mode, Known.ModeF32);
9116
9117 if (KnownEnv == DenormalFPEnv::getDefault()) {
9118 AttrToRemove.push_back(Attribute::DenormalFPEnv);
9119 } else {
9120 AttrToAdd.push_back(Attribute::get(
9121 Ctx, Attribute::DenormalFPEnv,
9122 DenormalFPEnv(Known.Mode, Known.ModeF32).toIntValue()));
9123 }
9124
9125 auto &IRP = getIRPosition();
9126
9127 // TODO: There should be a combined add and remove API.
9128 return A.removeAttrs(IRP, AttrToRemove) |
9129 A.manifestAttrs(IRP, AttrToAdd, /*ForceReplace=*/true);
9130 }
9131
9132 void trackStatistics() const override {
9133 STATS_DECLTRACK_FN_ATTR(denormal_fpenv)
9134 }
9135};
9136} // namespace
9137
9138/// ------------------ Value Constant Range Attribute -------------------------
9139
9140namespace {
9141struct AAValueConstantRangeImpl : AAValueConstantRange {
9142 using StateType = IntegerRangeState;
9143 AAValueConstantRangeImpl(const IRPosition &IRP, Attributor &A)
9144 : AAValueConstantRange(IRP, A) {}
9145
9146 /// See AbstractAttribute::initialize(..).
9147 void initialize(Attributor &A) override {
9148 if (A.hasSimplificationCallback(getIRPosition())) {
9149 indicatePessimisticFixpoint();
9150 return;
9151 }
9152
9153 // Intersect a range given by SCEV.
9154 intersectKnown(getConstantRangeFromSCEV(A, getCtxI()));
9155
9156 // Intersect a range given by LVI.
9157 intersectKnown(getConstantRangeFromLVI(A, getCtxI()));
9158 }
9159
9160 /// See AbstractAttribute::getAsStr().
9161 const std::string getAsStr(Attributor *A) const override {
9162 std::string Str;
9163 llvm::raw_string_ostream OS(Str);
9164 OS << "range(" << getBitWidth() << ")<";
9165 getKnown().print(OS);
9166 OS << " / ";
9167 getAssumed().print(OS);
9168 OS << ">";
9169 return Str;
9170 }
9171
9172 /// Helper function to get a SCEV expr for the associated value at program
9173 /// point \p I.
9174 const SCEV *getSCEV(Attributor &A, const Instruction *I = nullptr) const {
9175 if (!getAnchorScope())
9176 return nullptr;
9177
9178 ScalarEvolution *SE =
9179 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(
9180 *getAnchorScope());
9181
9182 LoopInfo *LI = A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(
9183 *getAnchorScope());
9184
9185 if (!SE || !LI)
9186 return nullptr;
9187
9188 const SCEV *S = SE->getSCEV(&getAssociatedValue());
9189 if (!I)
9190 return S;
9191
9192 return SE->getSCEVAtScope(S, LI->getLoopFor(I->getParent()));
9193 }
9194
9195 /// Helper function to get a range from SCEV for the associated value at
9196 /// program point \p I.
9197 ConstantRange getConstantRangeFromSCEV(Attributor &A,
9198 const Instruction *I = nullptr) const {
9199 if (!getAnchorScope())
9200 return getWorstState(getBitWidth());
9201
9202 ScalarEvolution *SE =
9203 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(
9204 *getAnchorScope());
9205
9206 const SCEV *S = getSCEV(A, I);
9207 if (!SE || !S)
9208 return getWorstState(getBitWidth());
9209
9210 return SE->getUnsignedRange(S);
9211 }
9212
9213 /// Helper function to get a range from LVI for the associated value at
9214 /// program point \p I.
9215 ConstantRange
9216 getConstantRangeFromLVI(Attributor &A,
9217 const Instruction *CtxI = nullptr) const {
9218 if (!getAnchorScope())
9219 return getWorstState(getBitWidth());
9220
9221 LazyValueInfo *LVI =
9222 A.getInfoCache().getAnalysisResultForFunction<LazyValueAnalysis>(
9223 *getAnchorScope());
9224
9225 if (!LVI || !CtxI)
9226 return getWorstState(getBitWidth());
9227 return LVI->getConstantRange(&getAssociatedValue(),
9228 const_cast<Instruction *>(CtxI),
9229 /*UndefAllowed*/ false);
9230 }
9231
9232 /// Return true if \p CtxI is valid for querying outside analyses.
9233 /// This basically makes sure we do not ask intra-procedural analysis
9234 /// about a context in the wrong function or a context that violates
9235 /// dominance assumptions they might have. The \p AllowAACtxI flag indicates
9236 /// if the original context of this AA is OK or should be considered invalid.
9237 bool isValidCtxInstructionForOutsideAnalysis(Attributor &A,
9238 const Instruction *CtxI,
9239 bool AllowAACtxI) const {
9240 if (!CtxI || (!AllowAACtxI && CtxI == getCtxI()))
9241 return false;
9242
9243 // Our context might be in a different function, neither intra-procedural
9244 // analysis (ScalarEvolution nor LazyValueInfo) can handle that.
9245 if (!AA::isValidInScope(getAssociatedValue(), CtxI->getFunction()))
9246 return false;
9247
9248 // If the context is not dominated by the value there are paths to the
9249 // context that do not define the value. This cannot be handled by
9250 // LazyValueInfo so we need to bail.
9251 if (auto *I = dyn_cast<Instruction>(&getAssociatedValue())) {
9252 InformationCache &InfoCache = A.getInfoCache();
9253 const DominatorTree *DT =
9254 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(
9255 *I->getFunction());
9256 return DT && DT->dominates(I, CtxI);
9257 }
9258
9259 return true;
9260 }
9261
9262 /// See AAValueConstantRange::getAssumedConstantRange(..).
9263 ConstantRange
9264 getAssumedConstantRange(Attributor &A,
9265 const Instruction *CtxI = nullptr) const override {
9266 // TODO: Make SCEV use Attributor assumption.
9267 // We may be able to bound a variable range via assumptions in
9268 // Attributor. ex.) If x is assumed to be in [1, 3] and y is known to
9269 // evolve to x^2 + x, then we can say that y is in [2, 12].
9270 if (!isValidCtxInstructionForOutsideAnalysis(A, CtxI,
9271 /* AllowAACtxI */ false))
9272 return getAssumed();
9273
9274 ConstantRange LVIR = getConstantRangeFromLVI(A, CtxI);
9275 ConstantRange SCEVR = getConstantRangeFromSCEV(A, CtxI);
9276 return getAssumed().intersectWith(SCEVR).intersectWith(LVIR);
9277 }
9278
9279 /// Helper function to create MDNode for range metadata.
9280 static MDNode *
9281 getMDNodeForConstantRange(Type *Ty, LLVMContext &Ctx,
9282 const ConstantRange &AssumedConstantRange) {
9283 Metadata *LowAndHigh[] = {ConstantAsMetadata::get(ConstantInt::get(
9284 Ty, AssumedConstantRange.getLower())),
9285 ConstantAsMetadata::get(ConstantInt::get(
9286 Ty, AssumedConstantRange.getUpper()))};
9287 return MDNode::get(Ctx, LowAndHigh);
9288 }
9289
9290 /// Return true if \p Assumed is included in ranges from instruction \p I.
9291 static bool isBetterRange(const ConstantRange &Assumed,
9292 const Instruction &I) {
9293 if (Assumed.isFullSet())
9294 return false;
9295
9296 std::optional<ConstantRange> Known;
9297
9298 if (const auto *CB = dyn_cast<CallBase>(&I)) {
9299 Known = CB->getRange();
9300 } else if (MDNode *KnownRanges = I.getMetadata(LLVMContext::MD_range)) {
9301 // If multiple ranges are annotated in IR, we give up to annotate assumed
9302 // range for now.
9303
9304 // TODO: If there exists a known range which containts assumed range, we
9305 // can say assumed range is better.
9306 if (KnownRanges->getNumOperands() > 2)
9307 return false;
9308
9309 ConstantInt *Lower =
9310 mdconst::extract<ConstantInt>(KnownRanges->getOperand(0));
9311 ConstantInt *Upper =
9312 mdconst::extract<ConstantInt>(KnownRanges->getOperand(1));
9313
9314 Known.emplace(Lower->getValue(), Upper->getValue());
9315 }
9316 return !Known || (*Known != Assumed && Known->contains(Assumed));
9317 }
9318
9319 /// Helper function to set range metadata.
9320 static bool
9321 setRangeMetadataIfisBetterRange(Instruction *I,
9322 const ConstantRange &AssumedConstantRange) {
9323 if (isBetterRange(AssumedConstantRange, *I)) {
9324 I->setMetadata(LLVMContext::MD_range,
9325 getMDNodeForConstantRange(I->getType(), I->getContext(),
9326 AssumedConstantRange));
9327 return true;
9328 }
9329 return false;
9330 }
9331 /// Helper function to set range return attribute.
9332 static bool
9333 setRangeRetAttrIfisBetterRange(Attributor &A, const IRPosition &IRP,
9334 Instruction *I,
9335 const ConstantRange &AssumedConstantRange) {
9336 if (isBetterRange(AssumedConstantRange, *I)) {
9337 A.manifestAttrs(IRP,
9338 Attribute::get(I->getContext(), Attribute::Range,
9339 AssumedConstantRange),
9340 /*ForceReplace*/ true);
9341 return true;
9342 }
9343 return false;
9344 }
9345
9346 /// See AbstractAttribute::manifest()
9347 ChangeStatus manifest(Attributor &A) override {
9348 ChangeStatus Changed = ChangeStatus::UNCHANGED;
9349 ConstantRange AssumedConstantRange = getAssumedConstantRange(A);
9350 assert(!AssumedConstantRange.isFullSet() && "Invalid state");
9351
9352 auto &V = getAssociatedValue();
9353 if (!AssumedConstantRange.isEmptySet() &&
9354 !AssumedConstantRange.isSingleElement()) {
9355 if (Instruction *I = dyn_cast<Instruction>(&V)) {
9356 assert(I == getCtxI() && "Should not annotate an instruction which is "
9357 "not the context instruction");
9358 if (isa<LoadInst>(I))
9359 if (setRangeMetadataIfisBetterRange(I, AssumedConstantRange))
9360 Changed = ChangeStatus::CHANGED;
9361 if (isa<CallInst>(I))
9362 if (setRangeRetAttrIfisBetterRange(A, getIRPosition(), I,
9363 AssumedConstantRange))
9364 Changed = ChangeStatus::CHANGED;
9365 }
9366 }
9367
9368 return Changed;
9369 }
9370};
9371
9372struct AAValueConstantRangeArgument final
9373 : AAArgumentFromCallSiteArguments<
9374 AAValueConstantRange, AAValueConstantRangeImpl, IntegerRangeState,
9375 true /* BridgeCallBaseContext */> {
9376 using Base = AAArgumentFromCallSiteArguments<
9377 AAValueConstantRange, AAValueConstantRangeImpl, IntegerRangeState,
9378 true /* BridgeCallBaseContext */>;
9379 AAValueConstantRangeArgument(const IRPosition &IRP, Attributor &A)
9380 : Base(IRP, A) {}
9381
9382 /// See AbstractAttribute::trackStatistics()
9383 void trackStatistics() const override {
9384 STATS_DECLTRACK_ARG_ATTR(value_range)
9385 }
9386};
9387
9388struct AAValueConstantRangeReturned
9389 : AAReturnedFromReturnedValues<AAValueConstantRange,
9390 AAValueConstantRangeImpl,
9391 AAValueConstantRangeImpl::StateType,
9392 /* PropagateCallBaseContext */ true> {
9393 using Base =
9394 AAReturnedFromReturnedValues<AAValueConstantRange,
9395 AAValueConstantRangeImpl,
9396 AAValueConstantRangeImpl::StateType,
9397 /* PropagateCallBaseContext */ true>;
9398 AAValueConstantRangeReturned(const IRPosition &IRP, Attributor &A)
9399 : Base(IRP, A) {}
9400
9401 /// See AbstractAttribute::initialize(...).
9402 void initialize(Attributor &A) override {
9403 if (!A.isFunctionIPOAmendable(*getAssociatedFunction()))
9404 indicatePessimisticFixpoint();
9405 }
9406
9407 /// See AbstractAttribute::trackStatistics()
9408 void trackStatistics() const override {
9409 STATS_DECLTRACK_FNRET_ATTR(value_range)
9410 }
9411};
9412
9413struct AAValueConstantRangeFloating : AAValueConstantRangeImpl {
9414 AAValueConstantRangeFloating(const IRPosition &IRP, Attributor &A)
9415 : AAValueConstantRangeImpl(IRP, A) {}
9416
9417 /// See AbstractAttribute::initialize(...).
9418 void initialize(Attributor &A) override {
9419 AAValueConstantRangeImpl::initialize(A);
9420 if (isAtFixpoint())
9421 return;
9422
9423 Value &V = getAssociatedValue();
9424
9425 if (auto *C = dyn_cast<ConstantInt>(&V)) {
9426 unionAssumed(ConstantRange(C->getValue()));
9427 indicateOptimisticFixpoint();
9428 return;
9429 }
9430
9431 if (isa<UndefValue>(&V)) {
9432 // Collapse the undef state to 0.
9433 unionAssumed(ConstantRange(APInt(getBitWidth(), 0)));
9434 indicateOptimisticFixpoint();
9435 return;
9436 }
9437
9438 if (isa<CallBase>(&V))
9439 return;
9440
9441 if (isa<BinaryOperator>(&V) || isa<CmpInst>(&V) || isa<CastInst>(&V))
9442 return;
9443
9444 // If it is a load instruction with range metadata, use it.
9445 if (LoadInst *LI = dyn_cast<LoadInst>(&V))
9446 if (auto *RangeMD = LI->getMetadata(LLVMContext::MD_range)) {
9447 intersectKnown(getConstantRangeFromMetadata(*RangeMD));
9448 return;
9449 }
9450
9451 // We can work with PHI and select instruction as we traverse their operands
9452 // during update.
9453 if (isa<SelectInst>(V) || isa<PHINode>(V))
9454 return;
9455
9456 // Otherwise we give up.
9457 indicatePessimisticFixpoint();
9458
9459 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] We give up: "
9460 << getAssociatedValue() << "\n");
9461 }
9462
9463 bool calculateBinaryOperator(
9464 Attributor &A, BinaryOperator *BinOp, IntegerRangeState &T,
9465 const Instruction *CtxI,
9466 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) {
9467 Value *LHS = BinOp->getOperand(0);
9468 Value *RHS = BinOp->getOperand(1);
9469
9470 // Simplify the operands first.
9471 bool UsedAssumedInformation = false;
9472 const auto &SimplifiedLHS = A.getAssumedSimplified(
9473 IRPosition::value(*LHS, getCallBaseContext()), *this,
9474 UsedAssumedInformation, AA::Interprocedural);
9475 if (!SimplifiedLHS.has_value())
9476 return true;
9477 if (!*SimplifiedLHS)
9478 return false;
9479 LHS = *SimplifiedLHS;
9480
9481 const auto &SimplifiedRHS = A.getAssumedSimplified(
9482 IRPosition::value(*RHS, getCallBaseContext()), *this,
9483 UsedAssumedInformation, AA::Interprocedural);
9484 if (!SimplifiedRHS.has_value())
9485 return true;
9486 if (!*SimplifiedRHS)
9487 return false;
9488 RHS = *SimplifiedRHS;
9489
9490 // TODO: Allow non integers as well.
9491 if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy())
9492 return false;
9493
9494 auto *LHSAA = A.getAAFor<AAValueConstantRange>(
9495 *this, IRPosition::value(*LHS, getCallBaseContext()),
9496 DepClassTy::REQUIRED);
9497 if (!LHSAA)
9498 return false;
9499 QuerriedAAs.push_back(LHSAA);
9500 auto LHSAARange = LHSAA->getAssumedConstantRange(A, CtxI);
9501
9502 auto *RHSAA = A.getAAFor<AAValueConstantRange>(
9503 *this, IRPosition::value(*RHS, getCallBaseContext()),
9504 DepClassTy::REQUIRED);
9505 if (!RHSAA)
9506 return false;
9507 QuerriedAAs.push_back(RHSAA);
9508 auto RHSAARange = RHSAA->getAssumedConstantRange(A, CtxI);
9509
9510 auto AssumedRange = LHSAARange.binaryOp(BinOp->getOpcode(), RHSAARange);
9511
9512 T.unionAssumed(AssumedRange);
9513
9514 // TODO: Track a known state too.
9515
9516 return T.isValidState();
9517 }
9518
9519 bool calculateCastInst(
9520 Attributor &A, CastInst *CastI, IntegerRangeState &T,
9521 const Instruction *CtxI,
9522 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) {
9523 assert(CastI->getNumOperands() == 1 && "Expected cast to be unary!");
9524 // TODO: Allow non integers as well.
9525 Value *OpV = CastI->getOperand(0);
9526
9527 // Simplify the operand first.
9528 bool UsedAssumedInformation = false;
9529 const auto &SimplifiedOpV = A.getAssumedSimplified(
9530 IRPosition::value(*OpV, getCallBaseContext()), *this,
9531 UsedAssumedInformation, AA::Interprocedural);
9532 if (!SimplifiedOpV.has_value())
9533 return true;
9534 if (!*SimplifiedOpV)
9535 return false;
9536 OpV = *SimplifiedOpV;
9537
9538 if (!OpV->getType()->isIntegerTy())
9539 return false;
9540
9541 auto *OpAA = A.getAAFor<AAValueConstantRange>(
9542 *this, IRPosition::value(*OpV, getCallBaseContext()),
9543 DepClassTy::REQUIRED);
9544 if (!OpAA)
9545 return false;
9546 QuerriedAAs.push_back(OpAA);
9547 T.unionAssumed(OpAA->getAssumed().castOp(CastI->getOpcode(),
9548 getState().getBitWidth()));
9549 return T.isValidState();
9550 }
9551
9552 bool
9553 calculateCmpInst(Attributor &A, CmpInst *CmpI, IntegerRangeState &T,
9554 const Instruction *CtxI,
9555 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) {
9556 Value *LHS = CmpI->getOperand(0);
9557 Value *RHS = CmpI->getOperand(1);
9558
9559 // Simplify the operands first.
9560 bool UsedAssumedInformation = false;
9561 const auto &SimplifiedLHS = A.getAssumedSimplified(
9562 IRPosition::value(*LHS, getCallBaseContext()), *this,
9563 UsedAssumedInformation, AA::Interprocedural);
9564 if (!SimplifiedLHS.has_value())
9565 return true;
9566 if (!*SimplifiedLHS)
9567 return false;
9568 LHS = *SimplifiedLHS;
9569
9570 const auto &SimplifiedRHS = A.getAssumedSimplified(
9571 IRPosition::value(*RHS, getCallBaseContext()), *this,
9572 UsedAssumedInformation, AA::Interprocedural);
9573 if (!SimplifiedRHS.has_value())
9574 return true;
9575 if (!*SimplifiedRHS)
9576 return false;
9577 RHS = *SimplifiedRHS;
9578
9579 // TODO: Allow non integers as well.
9580 if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy())
9581 return false;
9582
9583 auto *LHSAA = A.getAAFor<AAValueConstantRange>(
9584 *this, IRPosition::value(*LHS, getCallBaseContext()),
9585 DepClassTy::REQUIRED);
9586 if (!LHSAA)
9587 return false;
9588 QuerriedAAs.push_back(LHSAA);
9589 auto *RHSAA = A.getAAFor<AAValueConstantRange>(
9590 *this, IRPosition::value(*RHS, getCallBaseContext()),
9591 DepClassTy::REQUIRED);
9592 if (!RHSAA)
9593 return false;
9594 QuerriedAAs.push_back(RHSAA);
9595 auto LHSAARange = LHSAA->getAssumedConstantRange(A, CtxI);
9596 auto RHSAARange = RHSAA->getAssumedConstantRange(A, CtxI);
9597
9598 // If one of them is empty set, we can't decide.
9599 if (LHSAARange.isEmptySet() || RHSAARange.isEmptySet())
9600 return true;
9601
9602 bool MustTrue = false, MustFalse = false;
9603
9604 auto AllowedRegion =
9606
9607 if (AllowedRegion.intersectWith(LHSAARange).isEmptySet())
9608 MustFalse = true;
9609
9610 if (LHSAARange.icmp(CmpI->getPredicate(), RHSAARange))
9611 MustTrue = true;
9612
9613 assert((!MustTrue || !MustFalse) &&
9614 "Either MustTrue or MustFalse should be false!");
9615
9616 if (MustTrue)
9617 T.unionAssumed(ConstantRange(APInt(/* numBits */ 1, /* val */ 1)));
9618 else if (MustFalse)
9619 T.unionAssumed(ConstantRange(APInt(/* numBits */ 1, /* val */ 0)));
9620 else
9621 T.unionAssumed(ConstantRange(/* BitWidth */ 1, /* isFullSet */ true));
9622
9623 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] " << *CmpI << " after "
9624 << (MustTrue ? "true" : (MustFalse ? "false" : "unknown"))
9625 << ": " << T << "\n\t" << *LHSAA << "\t<op>\n\t"
9626 << *RHSAA);
9627
9628 // TODO: Track a known state too.
9629 return T.isValidState();
9630 }
9631
9632 /// See AbstractAttribute::updateImpl(...).
9633 ChangeStatus updateImpl(Attributor &A) override {
9634
9635 IntegerRangeState T(getBitWidth());
9636 auto VisitValueCB = [&](Value &V, const Instruction *CtxI) -> bool {
9638 if (!I || isa<CallBase>(I)) {
9639
9640 // Simplify the operand first.
9641 bool UsedAssumedInformation = false;
9642 const auto &SimplifiedOpV = A.getAssumedSimplified(
9643 IRPosition::value(V, getCallBaseContext()), *this,
9644 UsedAssumedInformation, AA::Interprocedural);
9645 if (!SimplifiedOpV.has_value())
9646 return true;
9647 if (!*SimplifiedOpV)
9648 return false;
9649 Value *VPtr = *SimplifiedOpV;
9650
9651 // If the value is not instruction, we query AA to Attributor.
9652 const auto *AA = A.getAAFor<AAValueConstantRange>(
9653 *this, IRPosition::value(*VPtr, getCallBaseContext()),
9654 DepClassTy::REQUIRED);
9655
9656 // Clamp operator is not used to utilize a program point CtxI.
9657 if (AA)
9658 T.unionAssumed(AA->getAssumedConstantRange(A, CtxI));
9659 else
9660 return false;
9661
9662 return T.isValidState();
9663 }
9664
9666 if (auto *BinOp = dyn_cast<BinaryOperator>(I)) {
9667 if (!calculateBinaryOperator(A, BinOp, T, CtxI, QuerriedAAs))
9668 return false;
9669 } else if (auto *CmpI = dyn_cast<CmpInst>(I)) {
9670 if (!calculateCmpInst(A, CmpI, T, CtxI, QuerriedAAs))
9671 return false;
9672 } else if (auto *CastI = dyn_cast<CastInst>(I)) {
9673 if (!calculateCastInst(A, CastI, T, CtxI, QuerriedAAs))
9674 return false;
9675 } else {
9676 // Give up with other instructions.
9677 // TODO: Add other instructions
9678
9679 T.indicatePessimisticFixpoint();
9680 return false;
9681 }
9682
9683 // Catch circular reasoning in a pessimistic way for now.
9684 // TODO: Check how the range evolves and if we stripped anything, see also
9685 // AADereferenceable or AAAlign for similar situations.
9686 for (const AAValueConstantRange *QueriedAA : QuerriedAAs) {
9687 if (QueriedAA != this)
9688 continue;
9689 // If we are in a stady state we do not need to worry.
9690 if (T.getAssumed() == getState().getAssumed())
9691 continue;
9692 T.indicatePessimisticFixpoint();
9693 }
9694
9695 return T.isValidState();
9696 };
9697
9698 if (!VisitValueCB(getAssociatedValue(), getCtxI()))
9699 return indicatePessimisticFixpoint();
9700
9701 // Ensure that long def-use chains can't cause circular reasoning either by
9702 // introducing a cutoff below.
9703 if (clampStateAndIndicateChange(getState(), T) == ChangeStatus::UNCHANGED)
9704 return ChangeStatus::UNCHANGED;
9705 if (++NumChanges > MaxNumChanges) {
9706 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] performed " << NumChanges
9707 << " but only " << MaxNumChanges
9708 << " are allowed to avoid cyclic reasoning.");
9709 return indicatePessimisticFixpoint();
9710 }
9711 return ChangeStatus::CHANGED;
9712 }
9713
9714 /// See AbstractAttribute::trackStatistics()
9715 void trackStatistics() const override {
9717 }
9718
9719 /// Tracker to bail after too many widening steps of the constant range.
9720 int NumChanges = 0;
9721
9722 /// Upper bound for the number of allowed changes (=widening steps) for the
9723 /// constant range before we give up.
9724 static constexpr int MaxNumChanges = 5;
9725};
9726
9727struct AAValueConstantRangeFunction : AAValueConstantRangeImpl {
9728 AAValueConstantRangeFunction(const IRPosition &IRP, Attributor &A)
9729 : AAValueConstantRangeImpl(IRP, A) {}
9730
9731 /// See AbstractAttribute::initialize(...).
9732 ChangeStatus updateImpl(Attributor &A) override {
9733 llvm_unreachable("AAValueConstantRange(Function|CallSite)::updateImpl will "
9734 "not be called");
9735 }
9736
9737 /// See AbstractAttribute::trackStatistics()
9738 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(value_range) }
9739};
9740
9741struct AAValueConstantRangeCallSite : AAValueConstantRangeFunction {
9742 AAValueConstantRangeCallSite(const IRPosition &IRP, Attributor &A)
9743 : AAValueConstantRangeFunction(IRP, A) {}
9744
9745 /// See AbstractAttribute::trackStatistics()
9746 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(value_range) }
9747};
9748
9749struct AAValueConstantRangeCallSiteReturned
9750 : AACalleeToCallSite<AAValueConstantRange, AAValueConstantRangeImpl,
9751 AAValueConstantRangeImpl::StateType,
9752 /* IntroduceCallBaseContext */ true> {
9753 AAValueConstantRangeCallSiteReturned(const IRPosition &IRP, Attributor &A)
9754 : AACalleeToCallSite<AAValueConstantRange, AAValueConstantRangeImpl,
9755 AAValueConstantRangeImpl::StateType,
9756 /* IntroduceCallBaseContext */ true>(IRP, A) {}
9757
9758 /// See AbstractAttribute::initialize(...).
9759 void initialize(Attributor &A) override {
9760 // If it is a call instruction with range attribute, use the range.
9761 if (CallInst *CI = dyn_cast<CallInst>(&getAssociatedValue())) {
9762 if (std::optional<ConstantRange> Range = CI->getRange())
9763 intersectKnown(*Range);
9764 }
9765
9766 AAValueConstantRangeImpl::initialize(A);
9767 }
9768
9769 /// See AbstractAttribute::trackStatistics()
9770 void trackStatistics() const override {
9771 STATS_DECLTRACK_CSRET_ATTR(value_range)
9772 }
9773};
9774struct AAValueConstantRangeCallSiteArgument : AAValueConstantRangeFloating {
9775 AAValueConstantRangeCallSiteArgument(const IRPosition &IRP, Attributor &A)
9776 : AAValueConstantRangeFloating(IRP, A) {}
9777
9778 /// See AbstractAttribute::manifest()
9779 ChangeStatus manifest(Attributor &A) override {
9780 return ChangeStatus::UNCHANGED;
9781 }
9782
9783 /// See AbstractAttribute::trackStatistics()
9784 void trackStatistics() const override {
9785 STATS_DECLTRACK_CSARG_ATTR(value_range)
9786 }
9787};
9788} // namespace
9789
9790/// ------------------ Potential Values Attribute -------------------------
9791
9792namespace {
9793struct AAPotentialConstantValuesImpl : AAPotentialConstantValues {
9794 using StateType = PotentialConstantIntValuesState;
9795
9796 AAPotentialConstantValuesImpl(const IRPosition &IRP, Attributor &A)
9797 : AAPotentialConstantValues(IRP, A) {}
9798
9799 /// See AbstractAttribute::initialize(..).
9800 void initialize(Attributor &A) override {
9801 if (A.hasSimplificationCallback(getIRPosition()))
9802 indicatePessimisticFixpoint();
9803 else
9804 AAPotentialConstantValues::initialize(A);
9805 }
9806
9807 bool fillSetWithConstantValues(Attributor &A, const IRPosition &IRP, SetTy &S,
9808 bool &ContainsUndef, bool ForSelf) {
9810 bool UsedAssumedInformation = false;
9811 if (!A.getAssumedSimplifiedValues(IRP, *this, Values, AA::Interprocedural,
9812 UsedAssumedInformation)) {
9813 // Avoid recursion when the caller is computing constant values for this
9814 // IRP itself.
9815 if (ForSelf)
9816 return false;
9817 if (!IRP.getAssociatedType()->isIntegerTy())
9818 return false;
9819 auto *PotentialValuesAA = A.getAAFor<AAPotentialConstantValues>(
9820 *this, IRP, DepClassTy::REQUIRED);
9821 if (!PotentialValuesAA || !PotentialValuesAA->getState().isValidState())
9822 return false;
9823 ContainsUndef = PotentialValuesAA->getState().undefIsContained();
9824 S = PotentialValuesAA->getState().getAssumedSet();
9825 return true;
9826 }
9827
9828 // Copy all the constant values, except UndefValue. ContainsUndef is true
9829 // iff Values contains only UndefValue instances. If there are other known
9830 // constants, then UndefValue is dropped.
9831 ContainsUndef = false;
9832 for (auto &It : Values) {
9833 if (isa<UndefValue>(It.getValue())) {
9834 ContainsUndef = true;
9835 continue;
9836 }
9837 auto *CI = dyn_cast<ConstantInt>(It.getValue());
9838 if (!CI)
9839 return false;
9840 S.insert(CI->getValue());
9841 }
9842 ContainsUndef &= S.empty();
9843
9844 return true;
9845 }
9846
9847 /// See AbstractAttribute::getAsStr().
9848 const std::string getAsStr(Attributor *A) const override {
9849 std::string Str;
9850 llvm::raw_string_ostream OS(Str);
9851 OS << getState();
9852 return Str;
9853 }
9854
9855 /// See AbstractAttribute::updateImpl(...).
9856 ChangeStatus updateImpl(Attributor &A) override {
9857 return indicatePessimisticFixpoint();
9858 }
9859};
9860
9861struct AAPotentialConstantValuesArgument final
9862 : AAArgumentFromCallSiteArguments<AAPotentialConstantValues,
9863 AAPotentialConstantValuesImpl,
9864 PotentialConstantIntValuesState> {
9865 using Base = AAArgumentFromCallSiteArguments<AAPotentialConstantValues,
9866 AAPotentialConstantValuesImpl,
9868 AAPotentialConstantValuesArgument(const IRPosition &IRP, Attributor &A)
9869 : Base(IRP, A) {}
9870
9871 /// See AbstractAttribute::trackStatistics()
9872 void trackStatistics() const override {
9873 STATS_DECLTRACK_ARG_ATTR(potential_values)
9874 }
9875};
9876
9877struct AAPotentialConstantValuesReturned
9878 : AAReturnedFromReturnedValues<AAPotentialConstantValues,
9879 AAPotentialConstantValuesImpl> {
9880 using Base = AAReturnedFromReturnedValues<AAPotentialConstantValues,
9881 AAPotentialConstantValuesImpl>;
9882 AAPotentialConstantValuesReturned(const IRPosition &IRP, Attributor &A)
9883 : Base(IRP, A) {}
9884
9885 void initialize(Attributor &A) override {
9886 if (!A.isFunctionIPOAmendable(*getAssociatedFunction()))
9887 indicatePessimisticFixpoint();
9888 Base::initialize(A);
9889 }
9890
9891 /// See AbstractAttribute::trackStatistics()
9892 void trackStatistics() const override {
9893 STATS_DECLTRACK_FNRET_ATTR(potential_values)
9894 }
9895};
9896
9897struct AAPotentialConstantValuesFloating : AAPotentialConstantValuesImpl {
9898 AAPotentialConstantValuesFloating(const IRPosition &IRP, Attributor &A)
9899 : AAPotentialConstantValuesImpl(IRP, A) {}
9900
9901 /// See AbstractAttribute::initialize(..).
9902 void initialize(Attributor &A) override {
9903 AAPotentialConstantValuesImpl::initialize(A);
9904 if (isAtFixpoint())
9905 return;
9906
9907 Value &V = getAssociatedValue();
9908
9909 if (auto *C = dyn_cast<ConstantInt>(&V)) {
9910 unionAssumed(C->getValue());
9911 indicateOptimisticFixpoint();
9912 return;
9913 }
9914
9915 if (isa<UndefValue>(&V)) {
9916 unionAssumedWithUndef();
9917 indicateOptimisticFixpoint();
9918 return;
9919 }
9920
9921 if (isa<BinaryOperator>(&V) || isa<ICmpInst>(&V) || isa<CastInst>(&V))
9922 return;
9923
9924 if (isa<SelectInst>(V) || isa<PHINode>(V) || isa<LoadInst>(V))
9925 return;
9926
9927 indicatePessimisticFixpoint();
9928
9929 LLVM_DEBUG(dbgs() << "[AAPotentialConstantValues] We give up: "
9930 << getAssociatedValue() << "\n");
9931 }
9932
9933 static bool calculateICmpInst(const ICmpInst *ICI, const APInt &LHS,
9934 const APInt &RHS) {
9935 return ICmpInst::compare(LHS, RHS, ICI->getPredicate());
9936 }
9937
9938 static APInt calculateCastInst(const CastInst *CI, const APInt &Src,
9939 uint32_t ResultBitWidth) {
9940 Instruction::CastOps CastOp = CI->getOpcode();
9941 switch (CastOp) {
9942 default:
9943 llvm_unreachable("unsupported or not integer cast");
9944 case Instruction::Trunc:
9945 return Src.trunc(ResultBitWidth);
9946 case Instruction::SExt:
9947 return Src.sext(ResultBitWidth);
9948 case Instruction::ZExt:
9949 return Src.zext(ResultBitWidth);
9950 case Instruction::BitCast:
9951 return Src;
9952 }
9953 }
9954
9955 static APInt calculateBinaryOperator(const BinaryOperator *BinOp,
9956 const APInt &LHS, const APInt &RHS,
9957 bool &SkipOperation, bool &Unsupported) {
9958 Instruction::BinaryOps BinOpcode = BinOp->getOpcode();
9959 // Unsupported is set to true when the binary operator is not supported.
9960 // SkipOperation is set to true when UB occur with the given operand pair
9961 // (LHS, RHS).
9962 // TODO: we should look at nsw and nuw keywords to handle operations
9963 // that create poison or undef value.
9964 switch (BinOpcode) {
9965 default:
9966 Unsupported = true;
9967 return LHS;
9968 case Instruction::Add:
9969 return LHS + RHS;
9970 case Instruction::Sub:
9971 return LHS - RHS;
9972 case Instruction::Mul:
9973 return LHS * RHS;
9974 case Instruction::UDiv:
9975 if (RHS.isZero()) {
9976 SkipOperation = true;
9977 return LHS;
9978 }
9979 return LHS.udiv(RHS);
9980 case Instruction::SDiv:
9981 if (RHS.isZero()) {
9982 SkipOperation = true;
9983 return LHS;
9984 }
9985 return LHS.sdiv(RHS);
9986 case Instruction::URem:
9987 if (RHS.isZero()) {
9988 SkipOperation = true;
9989 return LHS;
9990 }
9991 return LHS.urem(RHS);
9992 case Instruction::SRem:
9993 if (RHS.isZero()) {
9994 SkipOperation = true;
9995 return LHS;
9996 }
9997 return LHS.srem(RHS);
9998 case Instruction::Shl:
9999 return LHS.shl(RHS);
10000 case Instruction::LShr:
10001 return LHS.lshr(RHS);
10002 case Instruction::AShr:
10003 return LHS.ashr(RHS);
10004 case Instruction::And:
10005 return LHS & RHS;
10006 case Instruction::Or:
10007 return LHS | RHS;
10008 case Instruction::Xor:
10009 return LHS ^ RHS;
10010 }
10011 }
10012
10013 bool calculateBinaryOperatorAndTakeUnion(const BinaryOperator *BinOp,
10014 const APInt &LHS, const APInt &RHS) {
10015 bool SkipOperation = false;
10016 bool Unsupported = false;
10017 APInt Result =
10018 calculateBinaryOperator(BinOp, LHS, RHS, SkipOperation, Unsupported);
10019 if (Unsupported)
10020 return false;
10021 // If SkipOperation is true, we can ignore this operand pair (L, R).
10022 if (!SkipOperation)
10023 unionAssumed(Result);
10024 return isValidState();
10025 }
10026
10027 ChangeStatus updateWithICmpInst(Attributor &A, ICmpInst *ICI) {
10028 auto AssumedBefore = getAssumed();
10029 Value *LHS = ICI->getOperand(0);
10030 Value *RHS = ICI->getOperand(1);
10031
10032 bool LHSContainsUndef = false, RHSContainsUndef = false;
10033 SetTy LHSAAPVS, RHSAAPVS;
10034 if (!fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS,
10035 LHSContainsUndef, /* ForSelf */ false) ||
10036 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS,
10037 RHSContainsUndef, /* ForSelf */ false))
10038 return indicatePessimisticFixpoint();
10039
10040 // TODO: make use of undef flag to limit potential values aggressively.
10041 bool MaybeTrue = false, MaybeFalse = false;
10042 const APInt Zero(RHS->getType()->getIntegerBitWidth(), 0);
10043 if (LHSContainsUndef && RHSContainsUndef) {
10044 // The result of any comparison between undefs can be soundly replaced
10045 // with undef.
10046 unionAssumedWithUndef();
10047 } else if (LHSContainsUndef) {
10048 for (const APInt &R : RHSAAPVS) {
10049 bool CmpResult = calculateICmpInst(ICI, Zero, R);
10050 MaybeTrue |= CmpResult;
10051 MaybeFalse |= !CmpResult;
10052 if (MaybeTrue & MaybeFalse)
10053 return indicatePessimisticFixpoint();
10054 }
10055 } else if (RHSContainsUndef) {
10056 for (const APInt &L : LHSAAPVS) {
10057 bool CmpResult = calculateICmpInst(ICI, L, Zero);
10058 MaybeTrue |= CmpResult;
10059 MaybeFalse |= !CmpResult;
10060 if (MaybeTrue & MaybeFalse)
10061 return indicatePessimisticFixpoint();
10062 }
10063 } else {
10064 for (const APInt &L : LHSAAPVS) {
10065 for (const APInt &R : RHSAAPVS) {
10066 bool CmpResult = calculateICmpInst(ICI, L, R);
10067 MaybeTrue |= CmpResult;
10068 MaybeFalse |= !CmpResult;
10069 if (MaybeTrue & MaybeFalse)
10070 return indicatePessimisticFixpoint();
10071 }
10072 }
10073 }
10074 if (MaybeTrue)
10075 unionAssumed(APInt(/* numBits */ 1, /* val */ 1));
10076 if (MaybeFalse)
10077 unionAssumed(APInt(/* numBits */ 1, /* val */ 0));
10078 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10079 : ChangeStatus::CHANGED;
10080 }
10081
10082 ChangeStatus updateWithSelectInst(Attributor &A, SelectInst *SI) {
10083 auto AssumedBefore = getAssumed();
10084 Value *LHS = SI->getTrueValue();
10085 Value *RHS = SI->getFalseValue();
10086
10087 bool UsedAssumedInformation = false;
10088 std::optional<Constant *> C = A.getAssumedConstant(
10089 *SI->getCondition(), *this, UsedAssumedInformation);
10090
10091 // Check if we only need one operand.
10092 bool OnlyLeft = false, OnlyRight = false;
10093 if (C && *C && (*C)->isOneValue())
10094 OnlyLeft = true;
10095 else if (C && *C && (*C)->isNullValue())
10096 OnlyRight = true;
10097
10098 bool LHSContainsUndef = false, RHSContainsUndef = false;
10099 SetTy LHSAAPVS, RHSAAPVS;
10100 if (!OnlyRight &&
10101 !fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS,
10102 LHSContainsUndef, /* ForSelf */ false))
10103 return indicatePessimisticFixpoint();
10104
10105 if (!OnlyLeft &&
10106 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS,
10107 RHSContainsUndef, /* ForSelf */ false))
10108 return indicatePessimisticFixpoint();
10109
10110 if (OnlyLeft || OnlyRight) {
10111 // select (true/false), lhs, rhs
10112 auto *OpAA = OnlyLeft ? &LHSAAPVS : &RHSAAPVS;
10113 auto Undef = OnlyLeft ? LHSContainsUndef : RHSContainsUndef;
10114
10115 if (Undef)
10116 unionAssumedWithUndef();
10117 else {
10118 for (const auto &It : *OpAA)
10119 unionAssumed(It);
10120 }
10121
10122 } else if (LHSContainsUndef && RHSContainsUndef) {
10123 // select i1 *, undef , undef => undef
10124 unionAssumedWithUndef();
10125 } else {
10126 for (const auto &It : LHSAAPVS)
10127 unionAssumed(It);
10128 for (const auto &It : RHSAAPVS)
10129 unionAssumed(It);
10130 }
10131 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10132 : ChangeStatus::CHANGED;
10133 }
10134
10135 ChangeStatus updateWithCastInst(Attributor &A, CastInst *CI) {
10136 auto AssumedBefore = getAssumed();
10137 if (!CI->isIntegerCast())
10138 return indicatePessimisticFixpoint();
10139 assert(CI->getNumOperands() == 1 && "Expected cast to be unary!");
10140 uint32_t ResultBitWidth = CI->getDestTy()->getIntegerBitWidth();
10141 Value *Src = CI->getOperand(0);
10142
10143 bool SrcContainsUndef = false;
10144 SetTy SrcPVS;
10145 if (!fillSetWithConstantValues(A, IRPosition::value(*Src), SrcPVS,
10146 SrcContainsUndef, /* ForSelf */ false))
10147 return indicatePessimisticFixpoint();
10148
10149 if (SrcContainsUndef)
10150 unionAssumedWithUndef();
10151 else {
10152 for (const APInt &S : SrcPVS) {
10153 APInt T = calculateCastInst(CI, S, ResultBitWidth);
10154 unionAssumed(T);
10155 }
10156 }
10157 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10158 : ChangeStatus::CHANGED;
10159 }
10160
10161 ChangeStatus updateWithBinaryOperator(Attributor &A, BinaryOperator *BinOp) {
10162 auto AssumedBefore = getAssumed();
10163 Value *LHS = BinOp->getOperand(0);
10164 Value *RHS = BinOp->getOperand(1);
10165
10166 bool LHSContainsUndef = false, RHSContainsUndef = false;
10167 SetTy LHSAAPVS, RHSAAPVS;
10168 if (!fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS,
10169 LHSContainsUndef, /* ForSelf */ false) ||
10170 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS,
10171 RHSContainsUndef, /* ForSelf */ false))
10172 return indicatePessimisticFixpoint();
10173
10174 const APInt Zero = APInt(LHS->getType()->getIntegerBitWidth(), 0);
10175
10176 // TODO: make use of undef flag to limit potential values aggressively.
10177 if (LHSContainsUndef && RHSContainsUndef) {
10178 if (!calculateBinaryOperatorAndTakeUnion(BinOp, Zero, Zero))
10179 return indicatePessimisticFixpoint();
10180 } else if (LHSContainsUndef) {
10181 for (const APInt &R : RHSAAPVS) {
10182 if (!calculateBinaryOperatorAndTakeUnion(BinOp, Zero, R))
10183 return indicatePessimisticFixpoint();
10184 }
10185 } else if (RHSContainsUndef) {
10186 for (const APInt &L : LHSAAPVS) {
10187 if (!calculateBinaryOperatorAndTakeUnion(BinOp, L, Zero))
10188 return indicatePessimisticFixpoint();
10189 }
10190 } else {
10191 for (const APInt &L : LHSAAPVS) {
10192 for (const APInt &R : RHSAAPVS) {
10193 if (!calculateBinaryOperatorAndTakeUnion(BinOp, L, R))
10194 return indicatePessimisticFixpoint();
10195 }
10196 }
10197 }
10198 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10199 : ChangeStatus::CHANGED;
10200 }
10201
10202 ChangeStatus updateWithInstruction(Attributor &A, Instruction *Inst) {
10203 auto AssumedBefore = getAssumed();
10204 SetTy Incoming;
10205 bool ContainsUndef;
10206 if (!fillSetWithConstantValues(A, IRPosition::value(*Inst), Incoming,
10207 ContainsUndef, /* ForSelf */ true))
10208 return indicatePessimisticFixpoint();
10209 if (ContainsUndef) {
10210 unionAssumedWithUndef();
10211 } else {
10212 for (const auto &It : Incoming)
10213 unionAssumed(It);
10214 }
10215 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10216 : ChangeStatus::CHANGED;
10217 }
10218
10219 /// See AbstractAttribute::updateImpl(...).
10220 ChangeStatus updateImpl(Attributor &A) override {
10221 Value &V = getAssociatedValue();
10223
10224 if (auto *ICI = dyn_cast<ICmpInst>(I))
10225 return updateWithICmpInst(A, ICI);
10226
10227 if (auto *SI = dyn_cast<SelectInst>(I))
10228 return updateWithSelectInst(A, SI);
10229
10230 if (auto *CI = dyn_cast<CastInst>(I))
10231 return updateWithCastInst(A, CI);
10232
10233 if (auto *BinOp = dyn_cast<BinaryOperator>(I))
10234 return updateWithBinaryOperator(A, BinOp);
10235
10236 if (isa<PHINode>(I) || isa<LoadInst>(I))
10237 return updateWithInstruction(A, I);
10238
10239 return indicatePessimisticFixpoint();
10240 }
10241
10242 /// See AbstractAttribute::trackStatistics()
10243 void trackStatistics() const override {
10244 STATS_DECLTRACK_FLOATING_ATTR(potential_values)
10245 }
10246};
10247
10248struct AAPotentialConstantValuesFunction : AAPotentialConstantValuesImpl {
10249 AAPotentialConstantValuesFunction(const IRPosition &IRP, Attributor &A)
10250 : AAPotentialConstantValuesImpl(IRP, A) {}
10251
10252 /// See AbstractAttribute::initialize(...).
10253 ChangeStatus updateImpl(Attributor &A) override {
10255 "AAPotentialConstantValues(Function|CallSite)::updateImpl will "
10256 "not be called");
10257 }
10258
10259 /// See AbstractAttribute::trackStatistics()
10260 void trackStatistics() const override {
10261 STATS_DECLTRACK_FN_ATTR(potential_values)
10262 }
10263};
10264
10265struct AAPotentialConstantValuesCallSite : AAPotentialConstantValuesFunction {
10266 AAPotentialConstantValuesCallSite(const IRPosition &IRP, Attributor &A)
10267 : AAPotentialConstantValuesFunction(IRP, A) {}
10268
10269 /// See AbstractAttribute::trackStatistics()
10270 void trackStatistics() const override {
10271 STATS_DECLTRACK_CS_ATTR(potential_values)
10272 }
10273};
10274
10275struct AAPotentialConstantValuesCallSiteReturned
10276 : AACalleeToCallSite<AAPotentialConstantValues,
10277 AAPotentialConstantValuesImpl> {
10278 AAPotentialConstantValuesCallSiteReturned(const IRPosition &IRP,
10279 Attributor &A)
10280 : AACalleeToCallSite<AAPotentialConstantValues,
10281 AAPotentialConstantValuesImpl>(IRP, A) {}
10282
10283 /// See AbstractAttribute::trackStatistics()
10284 void trackStatistics() const override {
10285 STATS_DECLTRACK_CSRET_ATTR(potential_values)
10286 }
10287};
10288
10289struct AAPotentialConstantValuesCallSiteArgument
10290 : AAPotentialConstantValuesFloating {
10291 AAPotentialConstantValuesCallSiteArgument(const IRPosition &IRP,
10292 Attributor &A)
10293 : AAPotentialConstantValuesFloating(IRP, A) {}
10294
10295 /// See AbstractAttribute::initialize(..).
10296 void initialize(Attributor &A) override {
10297 AAPotentialConstantValuesImpl::initialize(A);
10298 if (isAtFixpoint())
10299 return;
10300
10301 Value &V = getAssociatedValue();
10302
10303 if (auto *C = dyn_cast<ConstantInt>(&V)) {
10304 unionAssumed(C->getValue());
10305 indicateOptimisticFixpoint();
10306 return;
10307 }
10308
10309 if (isa<UndefValue>(&V)) {
10310 unionAssumedWithUndef();
10311 indicateOptimisticFixpoint();
10312 return;
10313 }
10314 }
10315
10316 /// See AbstractAttribute::updateImpl(...).
10317 ChangeStatus updateImpl(Attributor &A) override {
10318 Value &V = getAssociatedValue();
10319 auto AssumedBefore = getAssumed();
10320 auto *AA = A.getAAFor<AAPotentialConstantValues>(
10321 *this, IRPosition::value(V), DepClassTy::REQUIRED);
10322 if (!AA)
10323 return indicatePessimisticFixpoint();
10324 const auto &S = AA->getAssumed();
10325 unionAssumed(S);
10326 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10327 : ChangeStatus::CHANGED;
10328 }
10329
10330 /// See AbstractAttribute::trackStatistics()
10331 void trackStatistics() const override {
10332 STATS_DECLTRACK_CSARG_ATTR(potential_values)
10333 }
10334};
10335} // namespace
10336
10337/// ------------------------ NoUndef Attribute ---------------------------------
10339 Attribute::AttrKind ImpliedAttributeKind,
10340 bool IgnoreSubsumingPositions) {
10341 assert(ImpliedAttributeKind == Attribute::NoUndef &&
10342 "Unexpected attribute kind");
10343 if (A.hasAttr(IRP, {Attribute::NoUndef}, IgnoreSubsumingPositions,
10344 Attribute::NoUndef))
10345 return true;
10346
10347 Value &Val = IRP.getAssociatedValue();
10350 LLVMContext &Ctx = Val.getContext();
10351 A.manifestAttrs(IRP, Attribute::get(Ctx, Attribute::NoUndef));
10352 return true;
10353 }
10354
10355 return false;
10356}
10357
10358namespace {
10359struct AANoUndefImpl : AANoUndef {
10360 AANoUndefImpl(const IRPosition &IRP, Attributor &A) : AANoUndef(IRP, A) {}
10361
10362 /// See AbstractAttribute::initialize(...).
10363 void initialize(Attributor &A) override {
10364 Value &V = getAssociatedValue();
10365 if (isa<UndefValue>(V))
10366 indicatePessimisticFixpoint();
10367 assert(!isImpliedByIR(A, getIRPosition(), Attribute::NoUndef));
10368 }
10369
10370 /// See followUsesInMBEC
10371 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
10372 AANoUndef::StateType &State) {
10373 const Value *UseV = U->get();
10374 const DominatorTree *DT = nullptr;
10375 AssumptionCache *AC = nullptr;
10376 InformationCache &InfoCache = A.getInfoCache();
10377 if (Function *F = getAnchorScope()) {
10378 DT = InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F);
10379 AC = InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F);
10380 }
10381 State.setKnown(isGuaranteedNotToBeUndefOrPoison(UseV, AC, I, DT));
10382 bool TrackUse = false;
10383 // Track use for instructions which must produce undef or poison bits when
10384 // at least one operand contains such bits.
10386 TrackUse = true;
10387 return TrackUse;
10388 }
10389
10390 /// See AbstractAttribute::getAsStr().
10391 const std::string getAsStr(Attributor *A) const override {
10392 return getAssumed() ? "noundef" : "may-undef-or-poison";
10393 }
10394
10395 ChangeStatus manifest(Attributor &A) override {
10396 // We don't manifest noundef attribute for dead positions because the
10397 // associated values with dead positions would be replaced with undef
10398 // values.
10399 bool UsedAssumedInformation = false;
10400 if (A.isAssumedDead(getIRPosition(), nullptr, nullptr,
10401 UsedAssumedInformation))
10402 return ChangeStatus::UNCHANGED;
10403 // A position whose simplified value does not have any value is
10404 // considered to be dead. We don't manifest noundef in such positions for
10405 // the same reason above.
10406 if (!A.getAssumedSimplified(getIRPosition(), *this, UsedAssumedInformation,
10408 .has_value())
10409 return ChangeStatus::UNCHANGED;
10410 return AANoUndef::manifest(A);
10411 }
10412};
10413
10414struct AANoUndefFloating : public AANoUndefImpl {
10415 AANoUndefFloating(const IRPosition &IRP, Attributor &A)
10416 : AANoUndefImpl(IRP, A) {}
10417
10418 /// See AbstractAttribute::initialize(...).
10419 void initialize(Attributor &A) override {
10420 AANoUndefImpl::initialize(A);
10421 if (!getState().isAtFixpoint() && getAnchorScope() &&
10422 !getAnchorScope()->isDeclaration())
10423 if (Instruction *CtxI = getCtxI())
10424 followUsesInMBEC(*this, A, getState(), *CtxI);
10425 }
10426
10427 /// See AbstractAttribute::updateImpl(...).
10428 ChangeStatus updateImpl(Attributor &A) override {
10429 auto VisitValueCB = [&](const IRPosition &IRP) -> bool {
10430 bool IsKnownNoUndef;
10432 A, this, IRP, DepClassTy::REQUIRED, IsKnownNoUndef);
10433 };
10434
10435 bool Stripped;
10436 bool UsedAssumedInformation = false;
10437 Value *AssociatedValue = &getAssociatedValue();
10439 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
10440 AA::AnyScope, UsedAssumedInformation))
10441 Stripped = false;
10442 else
10443 Stripped =
10444 Values.size() != 1 || Values.front().getValue() != AssociatedValue;
10445
10446 if (!Stripped) {
10447 // If we haven't stripped anything we might still be able to use a
10448 // different AA, but only if the IRP changes. Effectively when we
10449 // interpret this not as a call site value but as a floating/argument
10450 // value.
10451 const IRPosition AVIRP = IRPosition::value(*AssociatedValue);
10452 if (AVIRP == getIRPosition() || !VisitValueCB(AVIRP))
10453 return indicatePessimisticFixpoint();
10454 return ChangeStatus::UNCHANGED;
10455 }
10456
10457 for (const auto &VAC : Values)
10458 if (!VisitValueCB(IRPosition::value(*VAC.getValue())))
10459 return indicatePessimisticFixpoint();
10460
10461 return ChangeStatus::UNCHANGED;
10462 }
10463
10464 /// See AbstractAttribute::trackStatistics()
10465 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noundef) }
10466};
10467
10468struct AANoUndefReturned final
10469 : AAReturnedFromReturnedValues<AANoUndef, AANoUndefImpl> {
10470 AANoUndefReturned(const IRPosition &IRP, Attributor &A)
10471 : AAReturnedFromReturnedValues<AANoUndef, AANoUndefImpl>(IRP, A) {}
10472
10473 /// See AbstractAttribute::trackStatistics()
10474 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noundef) }
10475};
10476
10477struct AANoUndefArgument final
10478 : AAArgumentFromCallSiteArguments<AANoUndef, AANoUndefImpl> {
10479 AANoUndefArgument(const IRPosition &IRP, Attributor &A)
10480 : AAArgumentFromCallSiteArguments<AANoUndef, AANoUndefImpl>(IRP, A) {}
10481
10482 /// See AbstractAttribute::trackStatistics()
10483 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noundef) }
10484};
10485
10486struct AANoUndefCallSiteArgument final : AANoUndefFloating {
10487 AANoUndefCallSiteArgument(const IRPosition &IRP, Attributor &A)
10488 : AANoUndefFloating(IRP, A) {}
10489
10490 /// See AbstractAttribute::trackStatistics()
10491 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(noundef) }
10492};
10493
10494struct AANoUndefCallSiteReturned final
10495 : AACalleeToCallSite<AANoUndef, AANoUndefImpl> {
10496 AANoUndefCallSiteReturned(const IRPosition &IRP, Attributor &A)
10497 : AACalleeToCallSite<AANoUndef, AANoUndefImpl>(IRP, A) {}
10498
10499 /// See AbstractAttribute::trackStatistics()
10500 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(noundef) }
10501};
10502
10503/// ------------------------ NoFPClass Attribute -------------------------------
10504
10505struct AANoFPClassImpl : AANoFPClass {
10506 AANoFPClassImpl(const IRPosition &IRP, Attributor &A) : AANoFPClass(IRP, A) {}
10507
10508 void initialize(Attributor &A) override {
10509 const IRPosition &IRP = getIRPosition();
10510
10511 Value &V = IRP.getAssociatedValue();
10512 if (isa<UndefValue>(V)) {
10513 indicateOptimisticFixpoint();
10514 return;
10515 }
10516
10518 A.getAttrs(getIRPosition(), {Attribute::NoFPClass}, Attrs, false);
10519 for (const auto &Attr : Attrs) {
10520 addKnownBits(Attr.getNoFPClass());
10521 }
10522
10523 Instruction *CtxI = getCtxI();
10524
10525 if (getPositionKind() != IRPosition::IRP_RETURNED) {
10526 const DataLayout &DL = A.getDataLayout();
10527 InformationCache &InfoCache = A.getInfoCache();
10528
10529 const DominatorTree *DT = nullptr;
10530 AssumptionCache *AC = nullptr;
10531 const TargetLibraryInfo *TLI = nullptr;
10532 Function *F = getAnchorScope();
10533 if (F) {
10534 TLI = InfoCache.getTargetLibraryInfoForFunction(*F);
10535 if (!F->isDeclaration()) {
10536 DT =
10537 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F);
10538 AC = InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F);
10539 }
10540 }
10541
10542 SimplifyQuery Q(DL, TLI, DT, AC, CtxI);
10543
10544 KnownFPClass KnownFPClass = computeKnownFPClass(&V, fcAllFlags, Q);
10545 addKnownBits(~KnownFPClass.getKnownFPClasses());
10546 }
10547
10548 if (CtxI)
10549 followUsesInMBEC(*this, A, getState(), *CtxI);
10550 }
10551
10552 /// See followUsesInMBEC
10553 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
10554 AANoFPClass::StateType &State) {
10555 // TODO: Determine what instructions can be looked through.
10556 auto *CB = dyn_cast<CallBase>(I);
10557 if (!CB)
10558 return false;
10559
10560 if (!CB->isArgOperand(U))
10561 return false;
10562
10563 unsigned ArgNo = CB->getArgOperandNo(U);
10564 IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo);
10565 if (auto *NoFPAA = A.getAAFor<AANoFPClass>(*this, IRP, DepClassTy::NONE))
10566 State.addKnownBits(NoFPAA->getState().getKnown());
10567 return false;
10568 }
10569
10570 const std::string getAsStr(Attributor *A) const override {
10571 std::string Result = "nofpclass";
10572 raw_string_ostream OS(Result);
10573 OS << getKnownNoFPClass() << '/' << getAssumedNoFPClass();
10574 return Result;
10575 }
10576
10577 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
10578 SmallVectorImpl<Attribute> &Attrs) const override {
10579 Attrs.emplace_back(Attribute::getWithNoFPClass(Ctx, getAssumedNoFPClass()));
10580 }
10581};
10582
10583struct AANoFPClassFloating : public AANoFPClassImpl {
10584 AANoFPClassFloating(const IRPosition &IRP, Attributor &A)
10585 : AANoFPClassImpl(IRP, A) {}
10586
10587 /// See AbstractAttribute::updateImpl(...).
10588 ChangeStatus updateImpl(Attributor &A) override {
10590 bool UsedAssumedInformation = false;
10591 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
10592 AA::AnyScope, UsedAssumedInformation)) {
10593 Values.push_back({getAssociatedValue(), getCtxI()});
10594 }
10595
10596 StateType T;
10597 auto VisitValueCB = [&](Value &V, const Instruction *CtxI) -> bool {
10598 const auto *AA = A.getAAFor<AANoFPClass>(*this, IRPosition::value(V),
10599 DepClassTy::REQUIRED);
10600 if (!AA || this == AA) {
10601 T.indicatePessimisticFixpoint();
10602 } else {
10603 const AANoFPClass::StateType &S =
10604 static_cast<const AANoFPClass::StateType &>(AA->getState());
10605 T ^= S;
10606 }
10607 return T.isValidState();
10608 };
10609
10610 for (const auto &VAC : Values)
10611 if (!VisitValueCB(*VAC.getValue(), VAC.getCtxI()))
10612 return indicatePessimisticFixpoint();
10613
10614 return clampStateAndIndicateChange(getState(), T);
10615 }
10616
10617 /// See AbstractAttribute::trackStatistics()
10618 void trackStatistics() const override {
10620 }
10621};
10622
10623struct AANoFPClassReturned final
10624 : AAReturnedFromReturnedValues<AANoFPClass, AANoFPClassImpl,
10625 AANoFPClassImpl::StateType, false,
10626 Attribute::None, false> {
10627 AANoFPClassReturned(const IRPosition &IRP, Attributor &A)
10628 : AAReturnedFromReturnedValues<AANoFPClass, AANoFPClassImpl,
10629 AANoFPClassImpl::StateType, false,
10630 Attribute::None, false>(IRP, A) {}
10631
10632 /// See AbstractAttribute::trackStatistics()
10633 void trackStatistics() const override {
10635 }
10636};
10637
10638struct AANoFPClassArgument final
10639 : AAArgumentFromCallSiteArguments<AANoFPClass, AANoFPClassImpl> {
10640 AANoFPClassArgument(const IRPosition &IRP, Attributor &A)
10641 : AAArgumentFromCallSiteArguments<AANoFPClass, AANoFPClassImpl>(IRP, A) {}
10642
10643 /// See AbstractAttribute::trackStatistics()
10644 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nofpclass) }
10645};
10646
10647struct AANoFPClassCallSiteArgument final : AANoFPClassFloating {
10648 AANoFPClassCallSiteArgument(const IRPosition &IRP, Attributor &A)
10649 : AANoFPClassFloating(IRP, A) {}
10650
10651 /// See AbstractAttribute::trackStatistics()
10652 void trackStatistics() const override {
10654 }
10655};
10656
10657struct AANoFPClassCallSiteReturned final
10658 : AACalleeToCallSite<AANoFPClass, AANoFPClassImpl> {
10659 AANoFPClassCallSiteReturned(const IRPosition &IRP, Attributor &A)
10660 : AACalleeToCallSite<AANoFPClass, AANoFPClassImpl>(IRP, A) {}
10661
10662 /// See AbstractAttribute::trackStatistics()
10663 void trackStatistics() const override {
10665 }
10666};
10667
10668struct AACallEdgesImpl : public AACallEdges {
10669 AACallEdgesImpl(const IRPosition &IRP, Attributor &A) : AACallEdges(IRP, A) {}
10670
10671 const SetVector<Function *> &getOptimisticEdges() const override {
10672 return CalledFunctions;
10673 }
10674
10675 bool hasUnknownCallee() const override { return HasUnknownCallee; }
10676
10677 bool hasNonAsmUnknownCallee() const override {
10678 return HasUnknownCalleeNonAsm;
10679 }
10680
10681 const std::string getAsStr(Attributor *A) const override {
10682 return "CallEdges[" + std::to_string(HasUnknownCallee) + "," +
10683 std::to_string(CalledFunctions.size()) + "]";
10684 }
10685
10686 void trackStatistics() const override {}
10687
10688protected:
10689 void addCalledFunction(Function *Fn, ChangeStatus &Change) {
10690 if (CalledFunctions.insert(Fn)) {
10691 Change = ChangeStatus::CHANGED;
10692 LLVM_DEBUG(dbgs() << "[AACallEdges] New call edge: " << Fn->getName()
10693 << "\n");
10694 }
10695 }
10696
10697 void setHasUnknownCallee(bool NonAsm, ChangeStatus &Change) {
10698 if (!HasUnknownCallee)
10699 Change = ChangeStatus::CHANGED;
10700 if (NonAsm && !HasUnknownCalleeNonAsm)
10701 Change = ChangeStatus::CHANGED;
10702 HasUnknownCalleeNonAsm |= NonAsm;
10703 HasUnknownCallee = true;
10704 }
10705
10706private:
10707 /// Optimistic set of functions that might be called by this position.
10708 SetVector<Function *> CalledFunctions;
10709
10710 /// Is there any call with a unknown callee.
10711 bool HasUnknownCallee = false;
10712
10713 /// Is there any call with a unknown callee, excluding any inline asm.
10714 bool HasUnknownCalleeNonAsm = false;
10715};
10716
10717struct AACallEdgesCallSite : public AACallEdgesImpl {
10718 AACallEdgesCallSite(const IRPosition &IRP, Attributor &A)
10719 : AACallEdgesImpl(IRP, A) {}
10720 /// See AbstractAttribute::updateImpl(...).
10721 ChangeStatus updateImpl(Attributor &A) override {
10722 ChangeStatus Change = ChangeStatus::UNCHANGED;
10723
10724 auto VisitValue = [&](Value &V, const Instruction *CtxI) -> bool {
10725 if (Function *Fn = dyn_cast<Function>(&V)) {
10726 addCalledFunction(Fn, Change);
10727 } else {
10728 LLVM_DEBUG(dbgs() << "[AACallEdges] Unrecognized value: " << V << "\n");
10729 setHasUnknownCallee(true, Change);
10730 }
10731
10732 // Explore all values.
10733 return true;
10734 };
10735
10737 // Process any value that we might call.
10738 auto ProcessCalledOperand = [&](Value *V, Instruction *CtxI) {
10739 if (isa<Constant>(V)) {
10740 VisitValue(*V, CtxI);
10741 return;
10742 }
10743
10744 bool UsedAssumedInformation = false;
10745 Values.clear();
10746 if (!A.getAssumedSimplifiedValues(IRPosition::value(*V), *this, Values,
10747 AA::AnyScope, UsedAssumedInformation)) {
10748 Values.push_back({*V, CtxI});
10749 }
10750 for (auto &VAC : Values)
10751 VisitValue(*VAC.getValue(), VAC.getCtxI());
10752 };
10753
10754 CallBase *CB = cast<CallBase>(getCtxI());
10755
10756 if (auto *IA = dyn_cast<InlineAsm>(CB->getCalledOperand())) {
10757 if (IA->hasSideEffects() &&
10758 !hasAssumption(*CB->getCaller(), "ompx_no_call_asm") &&
10759 !hasAssumption(*CB, "ompx_no_call_asm")) {
10760 setHasUnknownCallee(false, Change);
10761 }
10762 return Change;
10763 }
10764
10765 if (CB->isIndirectCall())
10766 if (auto *IndirectCallAA = A.getAAFor<AAIndirectCallInfo>(
10767 *this, getIRPosition(), DepClassTy::OPTIONAL))
10768 if (IndirectCallAA->foreachCallee(
10769 [&](Function *Fn) { return VisitValue(*Fn, CB); }))
10770 return Change;
10771
10772 // The most simple case.
10773 ProcessCalledOperand(CB->getCalledOperand(), CB);
10774
10775 // Process callback functions.
10776 SmallVector<const Use *, 4u> CallbackUses;
10777 AbstractCallSite::getCallbackUses(*CB, CallbackUses);
10778 for (const Use *U : CallbackUses)
10779 ProcessCalledOperand(U->get(), CB);
10780
10781 return Change;
10782 }
10783};
10784
10785struct AACallEdgesFunction : public AACallEdgesImpl {
10786 AACallEdgesFunction(const IRPosition &IRP, Attributor &A)
10787 : AACallEdgesImpl(IRP, A) {}
10788
10789 /// See AbstractAttribute::updateImpl(...).
10790 ChangeStatus updateImpl(Attributor &A) override {
10791 ChangeStatus Change = ChangeStatus::UNCHANGED;
10792
10793 auto ProcessCallInst = [&](Instruction &Inst) {
10794 CallBase &CB = cast<CallBase>(Inst);
10795
10796 auto *CBEdges = A.getAAFor<AACallEdges>(
10797 *this, IRPosition::callsite_function(CB), DepClassTy::REQUIRED);
10798 if (!CBEdges)
10799 return false;
10800 if (CBEdges->hasNonAsmUnknownCallee())
10801 setHasUnknownCallee(true, Change);
10802 if (CBEdges->hasUnknownCallee())
10803 setHasUnknownCallee(false, Change);
10804
10805 for (Function *F : CBEdges->getOptimisticEdges())
10806 addCalledFunction(F, Change);
10807
10808 return true;
10809 };
10810
10811 // Visit all callable instructions.
10812 bool UsedAssumedInformation = false;
10813 if (!A.checkForAllCallLikeInstructions(ProcessCallInst, *this,
10814 UsedAssumedInformation,
10815 /* CheckBBLivenessOnly */ true)) {
10816 // If we haven't looked at all call like instructions, assume that there
10817 // are unknown callees.
10818 setHasUnknownCallee(true, Change);
10819 }
10820
10821 return Change;
10822 }
10823};
10824
10825/// -------------------AAInterFnReachability Attribute--------------------------
10826
10827struct AAInterFnReachabilityFunction
10828 : public CachedReachabilityAA<AAInterFnReachability, Function> {
10829 using Base = CachedReachabilityAA<AAInterFnReachability, Function>;
10830 AAInterFnReachabilityFunction(const IRPosition &IRP, Attributor &A)
10831 : Base(IRP, A) {}
10832
10833 bool instructionCanReach(
10834 Attributor &A, const Instruction &From, const Function &To,
10835 const AA::InstExclusionSetTy *ExclusionSet) const override {
10836 assert(From.getFunction() == getAnchorScope() && "Queried the wrong AA!");
10837 auto *NonConstThis = const_cast<AAInterFnReachabilityFunction *>(this);
10838
10839 RQITy StackRQI(A, From, To, ExclusionSet, false);
10840 RQITy::Reachable Result;
10841 if (!NonConstThis->checkQueryCache(A, StackRQI, Result))
10842 return NonConstThis->isReachableImpl(A, StackRQI,
10843 /*IsTemporaryRQI=*/true);
10844 return Result == RQITy::Reachable::Yes;
10845 }
10846
10847 bool isReachableImpl(Attributor &A, RQITy &RQI,
10848 bool IsTemporaryRQI) override {
10849 const Instruction *EntryI =
10850 &RQI.From->getFunction()->getEntryBlock().front();
10851 if (EntryI != RQI.From &&
10852 !instructionCanReach(A, *EntryI, *RQI.To, nullptr))
10853 return rememberResult(A, RQITy::Reachable::No, RQI, false,
10854 IsTemporaryRQI);
10855
10856 auto CheckReachableCallBase = [&](CallBase *CB) {
10857 auto *CBEdges = A.getAAFor<AACallEdges>(
10858 *this, IRPosition::callsite_function(*CB), DepClassTy::OPTIONAL);
10859 if (!CBEdges || !CBEdges->getState().isValidState())
10860 return false;
10861 // TODO Check To backwards in this case.
10862 if (CBEdges->hasUnknownCallee())
10863 return false;
10864
10865 for (Function *Fn : CBEdges->getOptimisticEdges()) {
10866 if (Fn == RQI.To)
10867 return false;
10868
10869 if (Fn->isDeclaration()) {
10870 if (Fn->hasFnAttribute(Attribute::NoCallback))
10871 continue;
10872 // TODO Check To backwards in this case.
10873 return false;
10874 }
10875
10876 if (Fn == getAnchorScope()) {
10877 if (EntryI == RQI.From)
10878 continue;
10879 return false;
10880 }
10881
10882 const AAInterFnReachability *InterFnReachability =
10883 A.getAAFor<AAInterFnReachability>(*this, IRPosition::function(*Fn),
10884 DepClassTy::OPTIONAL);
10885
10886 const Instruction &FnFirstInst = Fn->getEntryBlock().front();
10887 if (!InterFnReachability ||
10888 InterFnReachability->instructionCanReach(A, FnFirstInst, *RQI.To,
10889 RQI.ExclusionSet))
10890 return false;
10891 }
10892 return true;
10893 };
10894
10895 const auto *IntraFnReachability = A.getAAFor<AAIntraFnReachability>(
10896 *this, IRPosition::function(*RQI.From->getFunction()),
10897 DepClassTy::OPTIONAL);
10898
10899 // Determine call like instructions that we can reach from the inst.
10900 auto CheckCallBase = [&](Instruction &CBInst) {
10901 // There are usually less nodes in the call graph, check inter function
10902 // reachability first.
10903 if (CheckReachableCallBase(cast<CallBase>(&CBInst)))
10904 return true;
10905 return IntraFnReachability && !IntraFnReachability->isAssumedReachable(
10906 A, *RQI.From, CBInst, RQI.ExclusionSet);
10907 };
10908
10909 bool UsedExclusionSet = /* conservative */ true;
10910 bool UsedAssumedInformation = false;
10911 if (!A.checkForAllCallLikeInstructions(CheckCallBase, *this,
10912 UsedAssumedInformation,
10913 /* CheckBBLivenessOnly */ true))
10914 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
10915 IsTemporaryRQI);
10916
10917 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
10918 IsTemporaryRQI);
10919 }
10920
10921 void trackStatistics() const override {}
10922};
10923} // namespace
10924
10925template <typename AAType>
10926static std::optional<Constant *>
10928 const IRPosition &IRP, Type &Ty) {
10929 if (!Ty.isIntegerTy())
10930 return nullptr;
10931
10932 // This will also pass the call base context.
10933 const auto *AA = A.getAAFor<AAType>(QueryingAA, IRP, DepClassTy::NONE);
10934 if (!AA)
10935 return nullptr;
10936
10937 std::optional<Constant *> COpt = AA->getAssumedConstant(A);
10938
10939 if (!COpt.has_value()) {
10940 A.recordDependence(*AA, QueryingAA, DepClassTy::OPTIONAL);
10941 return std::nullopt;
10942 }
10943 if (auto *C = *COpt) {
10944 A.recordDependence(*AA, QueryingAA, DepClassTy::OPTIONAL);
10945 return C;
10946 }
10947 return nullptr;
10948}
10949
10951 Attributor &A, const AbstractAttribute &AA, const IRPosition &IRP,
10953 Type &Ty = *IRP.getAssociatedType();
10954 std::optional<Value *> V;
10955 for (auto &It : Values) {
10956 V = AA::combineOptionalValuesInAAValueLatice(V, It.getValue(), &Ty);
10957 if (V.has_value() && !*V)
10958 break;
10959 }
10960 if (!V.has_value())
10961 return UndefValue::get(&Ty);
10962 return *V;
10963}
10964
10965namespace {
10966struct AAPotentialValuesImpl : AAPotentialValues {
10967 using StateType = PotentialLLVMValuesState;
10968
10969 AAPotentialValuesImpl(const IRPosition &IRP, Attributor &A)
10970 : AAPotentialValues(IRP, A) {}
10971
10972 /// See AbstractAttribute::initialize(..).
10973 void initialize(Attributor &A) override {
10974 if (A.hasSimplificationCallback(getIRPosition())) {
10975 indicatePessimisticFixpoint();
10976 return;
10977 }
10978 Value *Stripped = getAssociatedValue().stripPointerCasts();
10979 if (isa<Constant>(Stripped) && !isa<ConstantExpr>(Stripped)) {
10980 addValue(A, getState(), *Stripped, getCtxI(), AA::AnyScope,
10981 getAnchorScope());
10982 indicateOptimisticFixpoint();
10983 return;
10984 }
10985 AAPotentialValues::initialize(A);
10986 }
10987
10988 /// See AbstractAttribute::getAsStr().
10989 const std::string getAsStr(Attributor *A) const override {
10990 std::string Str;
10991 llvm::raw_string_ostream OS(Str);
10992 OS << getState();
10993 return Str;
10994 }
10995
10996 template <typename AAType>
10997 static std::optional<Value *> askOtherAA(Attributor &A,
10998 const AbstractAttribute &AA,
10999 const IRPosition &IRP, Type &Ty) {
11001 return &IRP.getAssociatedValue();
11002 std::optional<Constant *> C = askForAssumedConstant<AAType>(A, AA, IRP, Ty);
11003 if (!C)
11004 return std::nullopt;
11005 if (*C)
11006 if (auto *CC = AA::getWithType(**C, Ty))
11007 return CC;
11008 return nullptr;
11009 }
11010
11011 virtual void addValue(Attributor &A, StateType &State, Value &V,
11012 const Instruction *CtxI, AA::ValueScope S,
11013 Function *AnchorScope) const {
11014
11015 IRPosition ValIRP = IRPosition::value(V);
11016 if (auto *CB = dyn_cast_or_null<CallBase>(CtxI)) {
11017 for (const auto &U : CB->args()) {
11018 if (U.get() != &V)
11019 continue;
11020 ValIRP = IRPosition::callsite_argument(*CB, CB->getArgOperandNo(&U));
11021 break;
11022 }
11023 }
11024
11025 Value *VPtr = &V;
11026 if (ValIRP.getAssociatedType()->isIntegerTy()) {
11027 Type &Ty = *getAssociatedType();
11028 std::optional<Value *> SimpleV =
11029 askOtherAA<AAValueConstantRange>(A, *this, ValIRP, Ty);
11030 if (SimpleV.has_value() && !*SimpleV) {
11031 auto *PotentialConstantsAA = A.getAAFor<AAPotentialConstantValues>(
11032 *this, ValIRP, DepClassTy::OPTIONAL);
11033 if (PotentialConstantsAA && PotentialConstantsAA->isValidState()) {
11034 for (const auto &It : PotentialConstantsAA->getAssumedSet())
11035 State.unionAssumed({{*ConstantInt::get(&Ty, It), nullptr}, S});
11036 if (PotentialConstantsAA->undefIsContained())
11037 State.unionAssumed({{*UndefValue::get(&Ty), nullptr}, S});
11038 return;
11039 }
11040 }
11041 if (!SimpleV.has_value())
11042 return;
11043
11044 if (*SimpleV)
11045 VPtr = *SimpleV;
11046 }
11047
11048 if (isa<ConstantInt>(VPtr))
11049 CtxI = nullptr;
11050 if (!AA::isValidInScope(*VPtr, AnchorScope))
11052
11053 State.unionAssumed({{*VPtr, CtxI}, S});
11054 }
11055
11056 /// Helper struct to tie a value+context pair together with the scope for
11057 /// which this is the simplified version.
11058 struct ItemInfo {
11059 AA::ValueAndContext I;
11061
11062 bool operator==(const ItemInfo &II) const {
11063 return II.I == I && II.S == S;
11064 };
11065 bool operator<(const ItemInfo &II) const {
11066 return std::tie(I, S) < std::tie(II.I, II.S);
11067 };
11068 };
11069
11070 bool recurseForValue(Attributor &A, const IRPosition &IRP, AA::ValueScope S) {
11071 SmallMapVector<AA::ValueAndContext, int, 8> ValueScopeMap;
11072 for (auto CS : {AA::Intraprocedural, AA::Interprocedural}) {
11073 if (!(CS & S))
11074 continue;
11075
11076 bool UsedAssumedInformation = false;
11078 if (!A.getAssumedSimplifiedValues(IRP, this, Values, CS,
11079 UsedAssumedInformation))
11080 return false;
11081
11082 for (auto &It : Values)
11083 ValueScopeMap[It] += CS;
11084 }
11085 for (auto &It : ValueScopeMap)
11086 addValue(A, getState(), *It.first.getValue(), It.first.getCtxI(),
11087 AA::ValueScope(It.second), getAnchorScope());
11088
11089 return true;
11090 }
11091
11092 void giveUpOnIntraprocedural(Attributor &A) {
11093 auto NewS = StateType::getBestState(getState());
11094 for (const auto &It : getAssumedSet()) {
11095 if (It.second == AA::Intraprocedural)
11096 continue;
11097 addValue(A, NewS, *It.first.getValue(), It.first.getCtxI(),
11098 AA::Interprocedural, getAnchorScope());
11099 }
11100 assert(!undefIsContained() && "Undef should be an explicit value!");
11101 addValue(A, NewS, getAssociatedValue(), getCtxI(), AA::Intraprocedural,
11102 getAnchorScope());
11103 getState() = NewS;
11104 }
11105
11106 /// See AbstractState::indicatePessimisticFixpoint(...).
11107 ChangeStatus indicatePessimisticFixpoint() override {
11108 getState() = StateType::getBestState(getState());
11109 getState().unionAssumed({{getAssociatedValue(), getCtxI()}, AA::AnyScope});
11110 AAPotentialValues::indicateOptimisticFixpoint();
11111 return ChangeStatus::CHANGED;
11112 }
11113
11114 /// See AbstractAttribute::updateImpl(...).
11115 ChangeStatus updateImpl(Attributor &A) override {
11116 return indicatePessimisticFixpoint();
11117 }
11118
11119 /// See AbstractAttribute::manifest(...).
11120 ChangeStatus manifest(Attributor &A) override {
11123 Values.clear();
11124 if (!getAssumedSimplifiedValues(A, Values, S))
11125 continue;
11126 Value &OldV = getAssociatedValue();
11127 if (isa<UndefValue>(OldV))
11128 continue;
11129 Value *NewV = getSingleValue(A, *this, getIRPosition(), Values);
11130 if (!NewV || NewV == &OldV)
11131 continue;
11132 if (getCtxI() &&
11133 !AA::isValidAtPosition({*NewV, *getCtxI()}, A.getInfoCache()))
11134 continue;
11135 if (A.changeAfterManifest(getIRPosition(), *NewV))
11136 return ChangeStatus::CHANGED;
11137 }
11138 return ChangeStatus::UNCHANGED;
11139 }
11140
11141 bool getAssumedSimplifiedValues(
11142 Attributor &A, SmallVectorImpl<AA::ValueAndContext> &Values,
11143 AA::ValueScope S, bool RecurseForSelectAndPHI = false) const override {
11144 if (!isValidState())
11145 return false;
11146 bool UsedAssumedInformation = false;
11147 for (const auto &It : getAssumedSet())
11148 if (It.second & S) {
11149 if (RecurseForSelectAndPHI && (isa<PHINode>(It.first.getValue()) ||
11150 isa<SelectInst>(It.first.getValue()))) {
11151 if (A.getAssumedSimplifiedValues(
11152 IRPosition::inst(*cast<Instruction>(It.first.getValue())),
11153 this, Values, S, UsedAssumedInformation))
11154 continue;
11155 }
11156 Values.push_back(It.first);
11157 }
11158 assert(!undefIsContained() && "Undef should be an explicit value!");
11159 return true;
11160 }
11161};
11162
11163struct AAPotentialValuesFloating : AAPotentialValuesImpl {
11164 AAPotentialValuesFloating(const IRPosition &IRP, Attributor &A)
11165 : AAPotentialValuesImpl(IRP, A) {}
11166
11167 /// See AbstractAttribute::updateImpl(...).
11168 ChangeStatus updateImpl(Attributor &A) override {
11169 auto AssumedBefore = getAssumed();
11170
11171 genericValueTraversal(A, &getAssociatedValue());
11172
11173 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
11174 : ChangeStatus::CHANGED;
11175 }
11176
11177 /// Helper struct to remember which AAIsDead instances we actually used.
11178 struct LivenessInfo {
11179 const AAIsDead *LivenessAA = nullptr;
11180 bool AnyDead = false;
11181 };
11182
11183 /// Check if \p Cmp is a comparison we can simplify.
11184 ///
11185 /// We handle multiple cases, one in which at least one operand is an
11186 /// (assumed) nullptr. If so, try to simplify it using AANonNull on the other
11187 /// operand. Return true if successful, in that case Worklist will be updated.
11188 bool handleCmp(Attributor &A, Value &Cmp, Value *LHS, Value *RHS,
11189 CmpInst::Predicate Pred, ItemInfo II,
11190 SmallVectorImpl<ItemInfo> &Worklist) {
11191
11192 // Simplify the operands first.
11193 bool UsedAssumedInformation = false;
11194 SmallVector<AA::ValueAndContext> LHSValues, RHSValues;
11195 auto GetSimplifiedValues = [&](Value &V,
11197 if (!A.getAssumedSimplifiedValues(
11198 IRPosition::value(V, getCallBaseContext()), this, Values,
11199 AA::Intraprocedural, UsedAssumedInformation)) {
11200 Values.clear();
11201 Values.push_back(AA::ValueAndContext{V, II.I.getCtxI()});
11202 }
11203 return Values.empty();
11204 };
11205 if (GetSimplifiedValues(*LHS, LHSValues))
11206 return true;
11207 if (GetSimplifiedValues(*RHS, RHSValues))
11208 return true;
11209
11210 LLVMContext &Ctx = LHS->getContext();
11211
11212 InformationCache &InfoCache = A.getInfoCache();
11213 Instruction *CmpI = dyn_cast<Instruction>(&Cmp);
11214 Function *F = CmpI ? CmpI->getFunction() : nullptr;
11215 const auto *DT =
11216 F ? InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F)
11217 : nullptr;
11218 const auto *TLI =
11219 F ? A.getInfoCache().getTargetLibraryInfoForFunction(*F) : nullptr;
11220 auto *AC =
11221 F ? InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F)
11222 : nullptr;
11223
11224 const DataLayout &DL = A.getDataLayout();
11225 SimplifyQuery Q(DL, TLI, DT, AC, CmpI);
11226
11227 auto CheckPair = [&](Value &LHSV, Value &RHSV) {
11228 if (isa<UndefValue>(LHSV) || isa<UndefValue>(RHSV)) {
11229 addValue(A, getState(), *UndefValue::get(Cmp.getType()),
11230 /* CtxI */ nullptr, II.S, getAnchorScope());
11231 return true;
11232 }
11233
11234 // Handle the trivial case first in which we don't even need to think
11235 // about null or non-null.
11236 if (&LHSV == &RHSV &&
11238 Constant *NewV = ConstantInt::get(Type::getInt1Ty(Ctx),
11240 addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S,
11241 getAnchorScope());
11242 return true;
11243 }
11244
11245 auto *TypedLHS = AA::getWithType(LHSV, *LHS->getType());
11246 auto *TypedRHS = AA::getWithType(RHSV, *RHS->getType());
11247 if (TypedLHS && TypedRHS) {
11248 Value *NewV = simplifyCmpInst(Pred, TypedLHS, TypedRHS, Q);
11249 if (NewV && NewV != &Cmp) {
11250 addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S,
11251 getAnchorScope());
11252 return true;
11253 }
11254 }
11255
11256 // From now on we only handle equalities (==, !=).
11257 if (!CmpInst::isEquality(Pred))
11258 return false;
11259
11260 bool LHSIsNull = isa<ConstantPointerNull>(LHSV);
11261 bool RHSIsNull = isa<ConstantPointerNull>(RHSV);
11262 if (!LHSIsNull && !RHSIsNull)
11263 return false;
11264
11265 // Left is the nullptr ==/!= non-nullptr case. We'll use AANonNull on the
11266 // non-nullptr operand and if we assume it's non-null we can conclude the
11267 // result of the comparison.
11268 assert((LHSIsNull || RHSIsNull) &&
11269 "Expected nullptr versus non-nullptr comparison at this point");
11270
11271 // The index is the operand that we assume is not null.
11272 unsigned PtrIdx = LHSIsNull;
11273 bool IsKnownNonNull;
11274 bool IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>(
11275 A, this, IRPosition::value(*(PtrIdx ? &RHSV : &LHSV)),
11276 DepClassTy::REQUIRED, IsKnownNonNull);
11277 if (!IsAssumedNonNull)
11278 return false;
11279
11280 // The new value depends on the predicate, true for != and false for ==.
11281 Constant *NewV =
11282 ConstantInt::get(Type::getInt1Ty(Ctx), Pred == CmpInst::ICMP_NE);
11283 addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S,
11284 getAnchorScope());
11285 return true;
11286 };
11287
11288 for (auto &LHSValue : LHSValues)
11289 for (auto &RHSValue : RHSValues)
11290 if (!CheckPair(*LHSValue.getValue(), *RHSValue.getValue()))
11291 return false;
11292 return true;
11293 }
11294
11295 bool handleSelectInst(Attributor &A, SelectInst &SI, ItemInfo II,
11296 SmallVectorImpl<ItemInfo> &Worklist) {
11297 const Instruction *CtxI = II.I.getCtxI();
11298 bool UsedAssumedInformation = false;
11299
11300 std::optional<Constant *> C =
11301 A.getAssumedConstant(*SI.getCondition(), *this, UsedAssumedInformation);
11302 bool NoValueYet = !C.has_value();
11303 if (NoValueYet || isa_and_nonnull<UndefValue>(*C))
11304 return true;
11305 if (auto *CI = dyn_cast_or_null<ConstantInt>(*C)) {
11306 if (CI->isZero())
11307 Worklist.push_back({{*SI.getFalseValue(), CtxI}, II.S});
11308 else
11309 Worklist.push_back({{*SI.getTrueValue(), CtxI}, II.S});
11310 } else if (&SI == &getAssociatedValue()) {
11311 // We could not simplify the condition, assume both values.
11312 Worklist.push_back({{*SI.getTrueValue(), CtxI}, II.S});
11313 Worklist.push_back({{*SI.getFalseValue(), CtxI}, II.S});
11314 } else {
11315 std::optional<Value *> SimpleV = A.getAssumedSimplified(
11316 IRPosition::inst(SI), *this, UsedAssumedInformation, II.S);
11317 if (!SimpleV.has_value())
11318 return true;
11319 if (*SimpleV) {
11320 addValue(A, getState(), **SimpleV, CtxI, II.S, getAnchorScope());
11321 return true;
11322 }
11323 return false;
11324 }
11325 return true;
11326 }
11327
11328 bool handleLoadInst(Attributor &A, LoadInst &LI, ItemInfo II,
11329 SmallVectorImpl<ItemInfo> &Worklist) {
11330 SmallSetVector<Value *, 4> PotentialCopies;
11331 SmallSetVector<Instruction *, 4> PotentialValueOrigins;
11332 bool UsedAssumedInformation = false;
11333 if (!AA::getPotentiallyLoadedValues(A, LI, PotentialCopies,
11334 PotentialValueOrigins, *this,
11335 UsedAssumedInformation,
11336 /* OnlyExact */ true)) {
11337 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Failed to get potentially "
11338 "loaded values for load instruction "
11339 << LI << "\n");
11340 return false;
11341 }
11342
11343 // Do not simplify loads that are only used in llvm.assume if we cannot also
11344 // remove all stores that may feed into the load. The reason is that the
11345 // assume is probably worth something as long as the stores are around.
11346 InformationCache &InfoCache = A.getInfoCache();
11347 if (InfoCache.isOnlyUsedByAssume(LI)) {
11348 if (!llvm::all_of(PotentialValueOrigins, [&](Instruction *I) {
11349 if (!I || isa<AssumeInst>(I))
11350 return true;
11351 if (auto *SI = dyn_cast<StoreInst>(I))
11352 return A.isAssumedDead(SI->getOperandUse(0), this,
11353 /* LivenessAA */ nullptr,
11354 UsedAssumedInformation,
11355 /* CheckBBLivenessOnly */ false);
11356 return A.isAssumedDead(*I, this, /* LivenessAA */ nullptr,
11357 UsedAssumedInformation,
11358 /* CheckBBLivenessOnly */ false);
11359 })) {
11360 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Load is onl used by assumes "
11361 "and we cannot delete all the stores: "
11362 << LI << "\n");
11363 return false;
11364 }
11365 }
11366
11367 // Values have to be dynamically unique or we loose the fact that a
11368 // single llvm::Value might represent two runtime values (e.g.,
11369 // stack locations in different recursive calls).
11370 const Instruction *CtxI = II.I.getCtxI();
11371 bool ScopeIsLocal = (II.S & AA::Intraprocedural);
11372 bool AllLocal = ScopeIsLocal;
11373 bool DynamicallyUnique = llvm::all_of(PotentialCopies, [&](Value *PC) {
11374 AllLocal &= AA::isValidInScope(*PC, getAnchorScope());
11375 return AA::isDynamicallyUnique(A, *this, *PC);
11376 });
11377 if (!DynamicallyUnique) {
11378 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Not all potentially loaded "
11379 "values are dynamically unique: "
11380 << LI << "\n");
11381 return false;
11382 }
11383
11384 for (auto *PotentialCopy : PotentialCopies) {
11385 if (AllLocal) {
11386 Worklist.push_back({{*PotentialCopy, CtxI}, II.S});
11387 } else {
11388 Worklist.push_back({{*PotentialCopy, CtxI}, AA::Interprocedural});
11389 }
11390 }
11391 if (!AllLocal && ScopeIsLocal)
11392 addValue(A, getState(), LI, CtxI, AA::Intraprocedural, getAnchorScope());
11393 return true;
11394 }
11395
11396 bool handlePHINode(
11397 Attributor &A, PHINode &PHI, ItemInfo II,
11398 SmallVectorImpl<ItemInfo> &Worklist,
11399 SmallMapVector<const Function *, LivenessInfo, 4> &LivenessAAs) {
11400 auto GetLivenessInfo = [&](const Function &F) -> LivenessInfo & {
11401 LivenessInfo &LI = LivenessAAs[&F];
11402 if (!LI.LivenessAA)
11403 LI.LivenessAA = A.getAAFor<AAIsDead>(*this, IRPosition::function(F),
11404 DepClassTy::NONE);
11405 return LI;
11406 };
11407
11408 if (&PHI == &getAssociatedValue()) {
11409 LivenessInfo &LI = GetLivenessInfo(*PHI.getFunction());
11410 const auto *CI =
11411 A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>(
11412 *PHI.getFunction());
11413
11414 CycleRef C;
11415 bool CyclePHI = mayBeInCycle(CI, &PHI, /* HeaderOnly */ true, &C);
11416 for (unsigned u = 0, e = PHI.getNumIncomingValues(); u < e; u++) {
11417 BasicBlock *IncomingBB = PHI.getIncomingBlock(u);
11418 if (LI.LivenessAA &&
11419 LI.LivenessAA->isEdgeDead(IncomingBB, PHI.getParent())) {
11420 LI.AnyDead = true;
11421 continue;
11422 }
11423 Value *V = PHI.getIncomingValue(u);
11424 if (V == &PHI)
11425 continue;
11426
11427 // If the incoming value is not the PHI but an instruction in the same
11428 // cycle we might have multiple versions of it flying around.
11429 if (CyclePHI && isa<Instruction>(V) &&
11430 (!C || CI->contains(C, cast<Instruction>(V)->getParent())))
11431 return false;
11432
11433 Worklist.push_back({{*V, IncomingBB->getTerminator()}, II.S});
11434 }
11435 return true;
11436 }
11437
11438 bool UsedAssumedInformation = false;
11439 std::optional<Value *> SimpleV = A.getAssumedSimplified(
11440 IRPosition::inst(PHI), *this, UsedAssumedInformation, II.S);
11441 if (!SimpleV.has_value())
11442 return true;
11443 if (!(*SimpleV))
11444 return false;
11445 addValue(A, getState(), **SimpleV, &PHI, II.S, getAnchorScope());
11446 return true;
11447 }
11448
11449 /// Use the generic, non-optimistic InstSimplfy functionality if we managed to
11450 /// simplify any operand of the instruction \p I. Return true if successful,
11451 /// in that case Worklist will be updated.
11452 bool handleGenericInst(Attributor &A, Instruction &I, ItemInfo II,
11453 SmallVectorImpl<ItemInfo> &Worklist) {
11454 bool SomeSimplified = false;
11455 bool UsedAssumedInformation = false;
11456
11457 SmallVector<Value *, 8> NewOps(I.getNumOperands());
11458 int Idx = 0;
11459 for (Value *Op : I.operands()) {
11460 const auto &SimplifiedOp = A.getAssumedSimplified(
11461 IRPosition::value(*Op, getCallBaseContext()), *this,
11462 UsedAssumedInformation, AA::Intraprocedural);
11463 // If we are not sure about any operand we are not sure about the entire
11464 // instruction, we'll wait.
11465 if (!SimplifiedOp.has_value())
11466 return true;
11467
11468 if (*SimplifiedOp)
11469 NewOps[Idx] = *SimplifiedOp;
11470 else
11471 NewOps[Idx] = Op;
11472
11473 SomeSimplified |= (NewOps[Idx] != Op);
11474 ++Idx;
11475 }
11476
11477 // We won't bother with the InstSimplify interface if we didn't simplify any
11478 // operand ourselves.
11479 if (!SomeSimplified)
11480 return false;
11481
11482 InformationCache &InfoCache = A.getInfoCache();
11483 Function *F = I.getFunction();
11484 const auto *DT =
11485 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F);
11486 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
11487 auto *AC = InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F);
11488
11489 const DataLayout &DL = I.getDataLayout();
11490 SimplifyQuery Q(DL, TLI, DT, AC, &I);
11491 Value *NewV = simplifyInstructionWithOperands(&I, NewOps, Q);
11492 if (!NewV || NewV == &I)
11493 return false;
11494
11495 LLVM_DEBUG(dbgs() << "Generic inst " << I << " assumed simplified to "
11496 << *NewV << "\n");
11497 Worklist.push_back({{*NewV, II.I.getCtxI()}, II.S});
11498 return true;
11499 }
11500
11502 Attributor &A, Instruction &I, ItemInfo II,
11503 SmallVectorImpl<ItemInfo> &Worklist,
11504 SmallMapVector<const Function *, LivenessInfo, 4> &LivenessAAs) {
11505 if (auto *CI = dyn_cast<CmpInst>(&I))
11506 return handleCmp(A, *CI, CI->getOperand(0), CI->getOperand(1),
11507 CI->getPredicate(), II, Worklist);
11508
11509 switch (I.getOpcode()) {
11510 case Instruction::Select:
11511 return handleSelectInst(A, cast<SelectInst>(I), II, Worklist);
11512 case Instruction::PHI:
11513 return handlePHINode(A, cast<PHINode>(I), II, Worklist, LivenessAAs);
11514 case Instruction::Load:
11515 return handleLoadInst(A, cast<LoadInst>(I), II, Worklist);
11516 default:
11517 return handleGenericInst(A, I, II, Worklist);
11518 };
11519 return false;
11520 }
11521
11522 void genericValueTraversal(Attributor &A, Value *InitialV) {
11523 SmallMapVector<const Function *, LivenessInfo, 4> LivenessAAs;
11524
11525 SmallSet<ItemInfo, 16> Visited;
11527 Worklist.push_back({{*InitialV, getCtxI()}, AA::AnyScope});
11528
11529 int Iteration = 0;
11530 do {
11531 ItemInfo II = Worklist.pop_back_val();
11532 Value *V = II.I.getValue();
11533 assert(V);
11534 const Instruction *CtxI = II.I.getCtxI();
11535 AA::ValueScope S = II.S;
11536
11537 // Check if we should process the current value. To prevent endless
11538 // recursion keep a record of the values we followed!
11539 if (!Visited.insert(II).second)
11540 continue;
11541
11542 // Make sure we limit the compile time for complex expressions.
11543 if (Iteration++ >= MaxPotentialValuesIterations) {
11544 LLVM_DEBUG(dbgs() << "Generic value traversal reached iteration limit: "
11545 << Iteration << "!\n");
11546 addValue(A, getState(), *V, CtxI, S, getAnchorScope());
11547 continue;
11548 }
11549
11550 // Explicitly look through calls with a "returned" attribute if we do
11551 // not have a pointer as stripPointerCasts only works on them.
11552 Value *NewV = nullptr;
11553 if (V->getType()->isPointerTy()) {
11554 NewV = AA::getWithType(*V->stripPointerCasts(), *V->getType());
11555 } else {
11556 if (auto *CB = dyn_cast<CallBase>(V))
11557 if (auto *Callee =
11559 for (Argument &Arg : Callee->args())
11560 if (Arg.hasReturnedAttr()) {
11561 NewV = CB->getArgOperand(Arg.getArgNo());
11562 break;
11563 }
11564 }
11565 }
11566 if (NewV && NewV != V) {
11567 Worklist.push_back({{*NewV, CtxI}, S});
11568 continue;
11569 }
11570
11571 if (auto *I = dyn_cast<Instruction>(V)) {
11572 if (simplifyInstruction(A, *I, II, Worklist, LivenessAAs))
11573 continue;
11574 }
11575
11576 if (V != InitialV || isa<Argument>(V))
11577 if (recurseForValue(A, IRPosition::value(*V), II.S))
11578 continue;
11579
11580 // If we haven't stripped anything we give up.
11581 if (V == InitialV && CtxI == getCtxI()) {
11582 indicatePessimisticFixpoint();
11583 return;
11584 }
11585
11586 addValue(A, getState(), *V, CtxI, S, getAnchorScope());
11587 } while (!Worklist.empty());
11588
11589 // If we actually used liveness information so we have to record a
11590 // dependence.
11591 for (auto &It : LivenessAAs)
11592 if (It.second.AnyDead)
11593 A.recordDependence(*It.second.LivenessAA, *this, DepClassTy::OPTIONAL);
11594 }
11595
11596 /// See AbstractAttribute::trackStatistics()
11597 void trackStatistics() const override {
11598 STATS_DECLTRACK_FLOATING_ATTR(potential_values)
11599 }
11600};
11601
11602struct AAPotentialValuesArgument final : AAPotentialValuesImpl {
11603 using Base = AAPotentialValuesImpl;
11604 AAPotentialValuesArgument(const IRPosition &IRP, Attributor &A)
11605 : Base(IRP, A) {}
11606
11607 /// See AbstractAttribute::initialize(..).
11608 void initialize(Attributor &A) override {
11609 auto &Arg = cast<Argument>(getAssociatedValue());
11611 indicatePessimisticFixpoint();
11612 }
11613
11614 /// See AbstractAttribute::updateImpl(...).
11615 ChangeStatus updateImpl(Attributor &A) override {
11616 auto AssumedBefore = getAssumed();
11617
11618 unsigned ArgNo = getCalleeArgNo();
11619
11620 bool UsedAssumedInformation = false;
11622 auto CallSitePred = [&](AbstractCallSite ACS) {
11623 const auto CSArgIRP = IRPosition::callsite_argument(ACS, ArgNo);
11624 if (CSArgIRP.getPositionKind() == IRP_INVALID)
11625 return false;
11626
11627 if (!A.getAssumedSimplifiedValues(CSArgIRP, this, Values,
11629 UsedAssumedInformation))
11630 return false;
11631
11632 return isValidState();
11633 };
11634
11635 if (!A.checkForAllCallSites(CallSitePred, *this,
11636 /* RequireAllCallSites */ true,
11637 UsedAssumedInformation))
11638 return indicatePessimisticFixpoint();
11639
11640 Function *Fn = getAssociatedFunction();
11641 bool AnyNonLocal = false;
11642 for (auto &It : Values) {
11643 if (isa<Constant>(It.getValue())) {
11644 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::AnyScope,
11645 getAnchorScope());
11646 continue;
11647 }
11648 if (!AA::isDynamicallyUnique(A, *this, *It.getValue()))
11649 return indicatePessimisticFixpoint();
11650
11651 if (auto *Arg = dyn_cast<Argument>(It.getValue()))
11652 if (Arg->getParent() == Fn) {
11653 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::AnyScope,
11654 getAnchorScope());
11655 continue;
11656 }
11657 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::Interprocedural,
11658 getAnchorScope());
11659 AnyNonLocal = true;
11660 }
11661 assert(!undefIsContained() && "Undef should be an explicit value!");
11662 if (AnyNonLocal)
11663 giveUpOnIntraprocedural(A);
11664
11665 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
11666 : ChangeStatus::CHANGED;
11667 }
11668
11669 /// See AbstractAttribute::trackStatistics()
11670 void trackStatistics() const override {
11671 STATS_DECLTRACK_ARG_ATTR(potential_values)
11672 }
11673};
11674
11675struct AAPotentialValuesReturned : public AAPotentialValuesFloating {
11676 using Base = AAPotentialValuesFloating;
11677 AAPotentialValuesReturned(const IRPosition &IRP, Attributor &A)
11678 : Base(IRP, A) {}
11679
11680 /// See AbstractAttribute::initialize(..).
11681 void initialize(Attributor &A) override {
11682 Function *F = getAssociatedFunction();
11683 if (!F || F->isDeclaration() || F->getReturnType()->isVoidTy()) {
11684 indicatePessimisticFixpoint();
11685 return;
11686 }
11687
11688 for (Argument &Arg : F->args())
11689 if (Arg.hasReturnedAttr()) {
11690 addValue(A, getState(), Arg, nullptr, AA::AnyScope, F);
11691 ReturnedArg = &Arg;
11692 break;
11693 }
11694 if (!A.isFunctionIPOAmendable(*F) ||
11695 A.hasSimplificationCallback(getIRPosition())) {
11696 if (!ReturnedArg)
11697 indicatePessimisticFixpoint();
11698 else
11699 indicateOptimisticFixpoint();
11700 }
11701 }
11702
11703 /// See AbstractAttribute::updateImpl(...).
11704 ChangeStatus updateImpl(Attributor &A) override {
11705 auto AssumedBefore = getAssumed();
11706 bool UsedAssumedInformation = false;
11707
11709 Function *AnchorScope = getAnchorScope();
11710 auto HandleReturnedValue = [&](Value &V, Instruction *CtxI,
11711 bool AddValues) {
11713 Values.clear();
11714 if (!A.getAssumedSimplifiedValues(IRPosition::value(V), this, Values, S,
11715 UsedAssumedInformation,
11716 /* RecurseForSelectAndPHI */ true))
11717 return false;
11718 if (!AddValues)
11719 continue;
11720
11721 bool AllInterAreIntra = false;
11722 if (S == AA::Interprocedural)
11723 AllInterAreIntra =
11724 llvm::all_of(Values, [&](const AA::ValueAndContext &VAC) {
11725 return AA::isValidInScope(*VAC.getValue(), AnchorScope);
11726 });
11727
11728 for (const AA::ValueAndContext &VAC : Values) {
11729 addValue(A, getState(), *VAC.getValue(),
11730 VAC.getCtxI() ? VAC.getCtxI() : CtxI,
11731 AllInterAreIntra ? AA::AnyScope : S, AnchorScope);
11732 }
11733 if (AllInterAreIntra)
11734 break;
11735 }
11736 return true;
11737 };
11738
11739 if (ReturnedArg) {
11740 HandleReturnedValue(*ReturnedArg, nullptr, true);
11741 } else {
11742 auto RetInstPred = [&](Instruction &RetI) {
11743 bool AddValues = true;
11744 if (isa<PHINode>(RetI.getOperand(0)) ||
11745 isa<SelectInst>(RetI.getOperand(0))) {
11746 addValue(A, getState(), *RetI.getOperand(0), &RetI, AA::AnyScope,
11747 AnchorScope);
11748 AddValues = false;
11749 }
11750 return HandleReturnedValue(*RetI.getOperand(0), &RetI, AddValues);
11751 };
11752
11753 if (!A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret},
11754 UsedAssumedInformation,
11755 /* CheckBBLivenessOnly */ true))
11756 return indicatePessimisticFixpoint();
11757 }
11758
11759 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
11760 : ChangeStatus::CHANGED;
11761 }
11762
11763 ChangeStatus manifest(Attributor &A) override {
11764 if (ReturnedArg)
11765 return ChangeStatus::UNCHANGED;
11767 if (!getAssumedSimplifiedValues(A, Values, AA::ValueScope::Intraprocedural,
11768 /* RecurseForSelectAndPHI */ true))
11769 return ChangeStatus::UNCHANGED;
11770 Value *NewVal = getSingleValue(A, *this, getIRPosition(), Values);
11771 if (!NewVal)
11772 return ChangeStatus::UNCHANGED;
11773
11774 ChangeStatus Changed = ChangeStatus::UNCHANGED;
11775 if (auto *Arg = dyn_cast<Argument>(NewVal)) {
11776 STATS_DECLTRACK(UniqueReturnValue, FunctionReturn,
11777 "Number of function with unique return");
11778 Changed |= A.manifestAttrs(
11780 {Attribute::get(Arg->getContext(), Attribute::Returned)});
11781 STATS_DECLTRACK_ARG_ATTR(returned);
11782 }
11783
11784 auto RetInstPred = [&](Instruction &RetI) {
11785 Value *RetOp = RetI.getOperand(0);
11786 if (isa<UndefValue>(RetOp) || RetOp == NewVal)
11787 return true;
11788 if (AA::isValidAtPosition({*NewVal, RetI}, A.getInfoCache()))
11789 if (A.changeUseAfterManifest(RetI.getOperandUse(0), *NewVal))
11790 Changed = ChangeStatus::CHANGED;
11791 return true;
11792 };
11793 bool UsedAssumedInformation = false;
11794 (void)A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret},
11795 UsedAssumedInformation,
11796 /* CheckBBLivenessOnly */ true);
11797 return Changed;
11798 }
11799
11800 ChangeStatus indicatePessimisticFixpoint() override {
11801 return AAPotentialValues::indicatePessimisticFixpoint();
11802 }
11803
11804 /// See AbstractAttribute::trackStatistics()
11805 void trackStatistics() const override{
11806 STATS_DECLTRACK_FNRET_ATTR(potential_values)}
11807
11808 /// The argumented with an existing `returned` attribute.
11809 Argument *ReturnedArg = nullptr;
11810};
11811
11812struct AAPotentialValuesFunction : AAPotentialValuesImpl {
11813 AAPotentialValuesFunction(const IRPosition &IRP, Attributor &A)
11814 : AAPotentialValuesImpl(IRP, A) {}
11815
11816 /// See AbstractAttribute::updateImpl(...).
11817 ChangeStatus updateImpl(Attributor &A) override {
11818 llvm_unreachable("AAPotentialValues(Function|CallSite)::updateImpl will "
11819 "not be called");
11820 }
11821
11822 /// See AbstractAttribute::trackStatistics()
11823 void trackStatistics() const override {
11824 STATS_DECLTRACK_FN_ATTR(potential_values)
11825 }
11826};
11827
11828struct AAPotentialValuesCallSite : AAPotentialValuesFunction {
11829 AAPotentialValuesCallSite(const IRPosition &IRP, Attributor &A)
11830 : AAPotentialValuesFunction(IRP, A) {}
11831
11832 /// See AbstractAttribute::trackStatistics()
11833 void trackStatistics() const override {
11834 STATS_DECLTRACK_CS_ATTR(potential_values)
11835 }
11836};
11837
11838struct AAPotentialValuesCallSiteReturned : AAPotentialValuesImpl {
11839 AAPotentialValuesCallSiteReturned(const IRPosition &IRP, Attributor &A)
11840 : AAPotentialValuesImpl(IRP, A) {}
11841
11842 /// See AbstractAttribute::updateImpl(...).
11843 ChangeStatus updateImpl(Attributor &A) override {
11844 auto AssumedBefore = getAssumed();
11845
11846 Function *Callee = getAssociatedFunction();
11847 if (!Callee)
11848 return indicatePessimisticFixpoint();
11849
11850 bool UsedAssumedInformation = false;
11851 auto *CB = cast<CallBase>(getCtxI());
11852 if (CB->isMustTailCall() &&
11853 !A.isAssumedDead(IRPosition::inst(*CB), this, nullptr,
11854 UsedAssumedInformation))
11855 return indicatePessimisticFixpoint();
11856
11857 Function *Caller = CB->getCaller();
11858
11859 auto AddScope = [&](AA::ValueScope S) {
11861 if (!A.getAssumedSimplifiedValues(IRPosition::returned(*Callee), this,
11862 Values, S, UsedAssumedInformation))
11863 return false;
11864
11865 for (auto &It : Values) {
11866 Value *V = It.getValue();
11867 std::optional<Value *> CallerV = A.translateArgumentToCallSiteContent(
11868 V, *CB, *this, UsedAssumedInformation);
11869 if (!CallerV.has_value()) {
11870 // Nothing to do as long as no value was determined.
11871 continue;
11872 }
11873 V = *CallerV ? *CallerV : V;
11874 if (*CallerV && AA::isDynamicallyUnique(A, *this, *V)) {
11875 if (recurseForValue(A, IRPosition::value(*V), S))
11876 continue;
11877 }
11878 if (S == AA::Intraprocedural && !AA::isValidInScope(*V, Caller)) {
11879 giveUpOnIntraprocedural(A);
11880 return true;
11881 }
11882 addValue(A, getState(), *V, CB, S, getAnchorScope());
11883 }
11884 return true;
11885 };
11886 if (!AddScope(AA::Intraprocedural))
11887 return indicatePessimisticFixpoint();
11888 if (!AddScope(AA::Interprocedural))
11889 return indicatePessimisticFixpoint();
11890 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
11891 : ChangeStatus::CHANGED;
11892 }
11893
11894 ChangeStatus indicatePessimisticFixpoint() override {
11895 return AAPotentialValues::indicatePessimisticFixpoint();
11896 }
11897
11898 /// See AbstractAttribute::trackStatistics()
11899 void trackStatistics() const override {
11900 STATS_DECLTRACK_CSRET_ATTR(potential_values)
11901 }
11902};
11903
11904struct AAPotentialValuesCallSiteArgument : AAPotentialValuesFloating {
11905 AAPotentialValuesCallSiteArgument(const IRPosition &IRP, Attributor &A)
11906 : AAPotentialValuesFloating(IRP, A) {}
11907
11908 /// See AbstractAttribute::trackStatistics()
11909 void trackStatistics() const override {
11910 STATS_DECLTRACK_CSARG_ATTR(potential_values)
11911 }
11912};
11913} // namespace
11914
11915/// ---------------------- Assumption Propagation ------------------------------
11916namespace {
11917struct AAAssumptionInfoImpl : public AAAssumptionInfo {
11918 AAAssumptionInfoImpl(const IRPosition &IRP, Attributor &A,
11919 const DenseSet<StringRef> &Known)
11920 : AAAssumptionInfo(IRP, A, Known) {}
11921
11922 /// See AbstractAttribute::manifest(...).
11923 ChangeStatus manifest(Attributor &A) override {
11924 // Don't manifest a universal set if it somehow made it here.
11925 if (getKnown().isUniversal())
11926 return ChangeStatus::UNCHANGED;
11927
11928 const IRPosition &IRP = getIRPosition();
11929 SmallVector<StringRef, 0> Set(getAssumed().getSet().begin(),
11930 getAssumed().getSet().end());
11931 llvm::sort(Set);
11932 return A.manifestAttrs(IRP,
11933 Attribute::get(IRP.getAnchorValue().getContext(),
11935 llvm::join(Set, ",")),
11936 /*ForceReplace=*/true);
11937 }
11938
11939 bool hasAssumption(const StringRef Assumption) const override {
11940 return isValidState() && setContains(Assumption);
11941 }
11942
11943 /// See AbstractAttribute::getAsStr()
11944 const std::string getAsStr(Attributor *A) const override {
11945 const SetContents &Known = getKnown();
11946 const SetContents &Assumed = getAssumed();
11947
11948 SmallVector<StringRef, 0> Set(Known.getSet().begin(), Known.getSet().end());
11949 llvm::sort(Set);
11950 const std::string KnownStr = llvm::join(Set, ",");
11951
11952 std::string AssumedStr = "Universal";
11953 if (!Assumed.isUniversal()) {
11954 Set.assign(Assumed.getSet().begin(), Assumed.getSet().end());
11955 AssumedStr = llvm::join(Set, ",");
11956 }
11957 return "Known [" + KnownStr + "]," + " Assumed [" + AssumedStr + "]";
11958 }
11959};
11960
11961/// Propagates assumption information from parent functions to all of their
11962/// successors. An assumption can be propagated if the containing function
11963/// dominates the called function.
11964///
11965/// We start with a "known" set of assumptions already valid for the associated
11966/// function and an "assumed" set that initially contains all possible
11967/// assumptions. The assumed set is inter-procedurally updated by narrowing its
11968/// contents as concrete values are known. The concrete values are seeded by the
11969/// first nodes that are either entries into the call graph, or contains no
11970/// assumptions. Each node is updated as the intersection of the assumed state
11971/// with all of its predecessors.
11972struct AAAssumptionInfoFunction final : AAAssumptionInfoImpl {
11973 AAAssumptionInfoFunction(const IRPosition &IRP, Attributor &A)
11974 : AAAssumptionInfoImpl(IRP, A,
11975 getAssumptions(*IRP.getAssociatedFunction())) {}
11976
11977 /// See AbstractAttribute::updateImpl(...).
11978 ChangeStatus updateImpl(Attributor &A) override {
11979 bool Changed = false;
11980
11981 auto CallSitePred = [&](AbstractCallSite ACS) {
11982 const auto *AssumptionAA = A.getAAFor<AAAssumptionInfo>(
11983 *this, IRPosition::callsite_function(*ACS.getInstruction()),
11984 DepClassTy::REQUIRED);
11985 if (!AssumptionAA)
11986 return false;
11987 // Get the set of assumptions shared by all of this function's callers.
11988 Changed |= getIntersection(AssumptionAA->getAssumed());
11989 return !getAssumed().empty() || !getKnown().empty();
11990 };
11991
11992 bool UsedAssumedInformation = false;
11993 // Get the intersection of all assumptions held by this node's predecessors.
11994 // If we don't know all the call sites then this is either an entry into the
11995 // call graph or an empty node. This node is known to only contain its own
11996 // assumptions and can be propagated to its successors.
11997 if (!A.checkForAllCallSites(CallSitePred, *this, true,
11998 UsedAssumedInformation))
11999 return indicatePessimisticFixpoint();
12000
12001 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
12002 }
12003
12004 void trackStatistics() const override {}
12005};
12006
12007/// Assumption Info defined for call sites.
12008struct AAAssumptionInfoCallSite final : AAAssumptionInfoImpl {
12009
12010 AAAssumptionInfoCallSite(const IRPosition &IRP, Attributor &A)
12011 : AAAssumptionInfoImpl(IRP, A, getInitialAssumptions(IRP)) {}
12012
12013 /// See AbstractAttribute::initialize(...).
12014 void initialize(Attributor &A) override {
12015 const IRPosition &FnPos = IRPosition::function(*getAnchorScope());
12016 A.getAAFor<AAAssumptionInfo>(*this, FnPos, DepClassTy::REQUIRED);
12017 }
12018
12019 /// See AbstractAttribute::updateImpl(...).
12020 ChangeStatus updateImpl(Attributor &A) override {
12021 const IRPosition &FnPos = IRPosition::function(*getAnchorScope());
12022 auto *AssumptionAA =
12023 A.getAAFor<AAAssumptionInfo>(*this, FnPos, DepClassTy::REQUIRED);
12024 if (!AssumptionAA)
12025 return indicatePessimisticFixpoint();
12026 bool Changed = getIntersection(AssumptionAA->getAssumed());
12027 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
12028 }
12029
12030 /// See AbstractAttribute::trackStatistics()
12031 void trackStatistics() const override {}
12032
12033private:
12034 /// Helper to initialized the known set as all the assumptions this call and
12035 /// the callee contain.
12036 DenseSet<StringRef> getInitialAssumptions(const IRPosition &IRP) {
12037 const CallBase &CB = cast<CallBase>(IRP.getAssociatedValue());
12038 auto Assumptions = getAssumptions(CB);
12039 if (const Function *F = CB.getCaller())
12040 set_union(Assumptions, getAssumptions(*F));
12041 if (Function *F = IRP.getAssociatedFunction())
12042 set_union(Assumptions, getAssumptions(*F));
12043 return Assumptions;
12044 }
12045};
12046} // namespace
12047
12049 return static_cast<AACallGraphNode *>(const_cast<AACallEdges *>(
12050 A.getOrCreateAAFor<AACallEdges>(IRPosition::function(**I))));
12051}
12052
12054
12055/// ------------------------ UnderlyingObjects ---------------------------------
12056
12057namespace {
12058struct AAUnderlyingObjectsImpl
12059 : StateWrapper<BooleanState, AAUnderlyingObjects> {
12061 AAUnderlyingObjectsImpl(const IRPosition &IRP, Attributor &A) : BaseTy(IRP) {}
12062
12063 /// See AbstractAttribute::getAsStr().
12064 const std::string getAsStr(Attributor *A) const override {
12065 if (!isValidState())
12066 return "<invalid>";
12067 std::string Str;
12069 OS << "underlying objects: inter " << InterAssumedUnderlyingObjects.size()
12070 << " objects, intra " << IntraAssumedUnderlyingObjects.size()
12071 << " objects.\n";
12072 if (!InterAssumedUnderlyingObjects.empty()) {
12073 OS << "inter objects:\n";
12074 for (auto *Obj : InterAssumedUnderlyingObjects)
12075 OS << *Obj << '\n';
12076 }
12077 if (!IntraAssumedUnderlyingObjects.empty()) {
12078 OS << "intra objects:\n";
12079 for (auto *Obj : IntraAssumedUnderlyingObjects)
12080 OS << *Obj << '\n';
12081 }
12082 return Str;
12083 }
12084
12085 /// See AbstractAttribute::trackStatistics()
12086 void trackStatistics() const override {}
12087
12088 /// See AbstractAttribute::updateImpl(...).
12089 ChangeStatus updateImpl(Attributor &A) override {
12090 auto &Ptr = getAssociatedValue();
12091
12092 bool UsedAssumedInformation = false;
12093 auto DoUpdate = [&](SmallSetVector<Value *, 8> &UnderlyingObjects,
12095 SmallPtrSet<Value *, 8> SeenObjects;
12097
12098 if (!A.getAssumedSimplifiedValues(IRPosition::value(Ptr), *this, Values,
12099 Scope, UsedAssumedInformation))
12100 return UnderlyingObjects.insert(&Ptr);
12101
12102 bool Changed = false;
12103
12104 for (unsigned I = 0; I < Values.size(); ++I) {
12105 auto &VAC = Values[I];
12106 auto *Obj = VAC.getValue();
12107 Value *UO = getUnderlyingObject(Obj);
12108 if (!SeenObjects.insert(UO ? UO : Obj).second)
12109 continue;
12110 if (UO && UO != Obj) {
12111 if (isa<AllocaInst>(UO) || isa<GlobalValue>(UO)) {
12112 Changed |= UnderlyingObjects.insert(UO);
12113 continue;
12114 }
12115
12116 const auto *OtherAA = A.getAAFor<AAUnderlyingObjects>(
12117 *this, IRPosition::value(*UO), DepClassTy::OPTIONAL);
12118 auto Pred = [&](Value &V) {
12119 if (&V == UO)
12120 Changed |= UnderlyingObjects.insert(UO);
12121 else
12122 Values.emplace_back(V, nullptr);
12123 return true;
12124 };
12125
12126 if (!OtherAA || !OtherAA->forallUnderlyingObjects(Pred, Scope))
12128 "The forall call should not return false at this position");
12129 UsedAssumedInformation |= !OtherAA->getState().isAtFixpoint();
12130 continue;
12131 }
12132
12133 if (isa<SelectInst>(Obj)) {
12134 Changed |= handleIndirect(A, *Obj, UnderlyingObjects, Scope,
12135 UsedAssumedInformation);
12136 continue;
12137 }
12138 if (auto *PHI = dyn_cast<PHINode>(Obj)) {
12139 // Explicitly look through PHIs as we do not care about dynamically
12140 // uniqueness.
12141 for (unsigned u = 0, e = PHI->getNumIncomingValues(); u < e; u++) {
12142 Changed |=
12143 handleIndirect(A, *PHI->getIncomingValue(u), UnderlyingObjects,
12144 Scope, UsedAssumedInformation);
12145 }
12146 continue;
12147 }
12148
12149 Changed |= UnderlyingObjects.insert(Obj);
12150 }
12151
12152 return Changed;
12153 };
12154
12155 bool Changed = false;
12156 Changed |= DoUpdate(IntraAssumedUnderlyingObjects, AA::Intraprocedural);
12157 Changed |= DoUpdate(InterAssumedUnderlyingObjects, AA::Interprocedural);
12158 if (!UsedAssumedInformation)
12159 indicateOptimisticFixpoint();
12160 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
12161 }
12162
12163 bool forallUnderlyingObjects(
12164 function_ref<bool(Value &)> Pred,
12165 AA::ValueScope Scope = AA::Interprocedural) const override {
12166 if (!isValidState())
12167 return Pred(getAssociatedValue());
12168
12169 auto &AssumedUnderlyingObjects = Scope == AA::Intraprocedural
12170 ? IntraAssumedUnderlyingObjects
12171 : InterAssumedUnderlyingObjects;
12172 for (Value *Obj : AssumedUnderlyingObjects)
12173 if (!Pred(*Obj))
12174 return false;
12175
12176 return true;
12177 }
12178
12179private:
12180 /// Handle the case where the value is not the actual underlying value, such
12181 /// as a phi node or a select instruction.
12182 bool handleIndirect(Attributor &A, Value &V,
12183 SmallSetVector<Value *, 8> &UnderlyingObjects,
12184 AA::ValueScope Scope, bool &UsedAssumedInformation) {
12185 bool Changed = false;
12186 const auto *AA = A.getAAFor<AAUnderlyingObjects>(
12187 *this, IRPosition::value(V), DepClassTy::OPTIONAL);
12188 auto Pred = [&](Value &V) {
12189 Changed |= UnderlyingObjects.insert(&V);
12190 return true;
12191 };
12192 if (!AA || !AA->forallUnderlyingObjects(Pred, Scope))
12194 "The forall call should not return false at this position");
12195 UsedAssumedInformation |= !AA->getState().isAtFixpoint();
12196 return Changed;
12197 }
12198
12199 /// All the underlying objects collected so far via intra procedural scope.
12200 SmallSetVector<Value *, 8> IntraAssumedUnderlyingObjects;
12201 /// All the underlying objects collected so far via inter procedural scope.
12202 SmallSetVector<Value *, 8> InterAssumedUnderlyingObjects;
12203};
12204
12205struct AAUnderlyingObjectsFloating final : AAUnderlyingObjectsImpl {
12206 AAUnderlyingObjectsFloating(const IRPosition &IRP, Attributor &A)
12207 : AAUnderlyingObjectsImpl(IRP, A) {}
12208};
12209
12210struct AAUnderlyingObjectsArgument final : AAUnderlyingObjectsImpl {
12211 AAUnderlyingObjectsArgument(const IRPosition &IRP, Attributor &A)
12212 : AAUnderlyingObjectsImpl(IRP, A) {}
12213};
12214
12215struct AAUnderlyingObjectsCallSite final : AAUnderlyingObjectsImpl {
12216 AAUnderlyingObjectsCallSite(const IRPosition &IRP, Attributor &A)
12217 : AAUnderlyingObjectsImpl(IRP, A) {}
12218};
12219
12220struct AAUnderlyingObjectsCallSiteArgument final : AAUnderlyingObjectsImpl {
12221 AAUnderlyingObjectsCallSiteArgument(const IRPosition &IRP, Attributor &A)
12222 : AAUnderlyingObjectsImpl(IRP, A) {}
12223};
12224
12225struct AAUnderlyingObjectsReturned final : AAUnderlyingObjectsImpl {
12226 AAUnderlyingObjectsReturned(const IRPosition &IRP, Attributor &A)
12227 : AAUnderlyingObjectsImpl(IRP, A) {}
12228};
12229
12230struct AAUnderlyingObjectsCallSiteReturned final : AAUnderlyingObjectsImpl {
12231 AAUnderlyingObjectsCallSiteReturned(const IRPosition &IRP, Attributor &A)
12232 : AAUnderlyingObjectsImpl(IRP, A) {}
12233};
12234
12235struct AAUnderlyingObjectsFunction final : AAUnderlyingObjectsImpl {
12236 AAUnderlyingObjectsFunction(const IRPosition &IRP, Attributor &A)
12237 : AAUnderlyingObjectsImpl(IRP, A) {}
12238};
12239} // namespace
12240
12241/// ------------------------ Global Value Info -------------------------------
12242namespace {
12243struct AAGlobalValueInfoFloating : public AAGlobalValueInfo {
12244 AAGlobalValueInfoFloating(const IRPosition &IRP, Attributor &A)
12245 : AAGlobalValueInfo(IRP, A) {}
12246
12247 /// See AbstractAttribute::initialize(...).
12248 void initialize(Attributor &A) override {}
12249
12250 bool checkUse(Attributor &A, const Use &U, bool &Follow,
12251 SmallVectorImpl<const Value *> &Worklist) {
12252 Instruction *UInst = dyn_cast<Instruction>(U.getUser());
12253 if (!UInst) {
12254 // Outside a closed world, code outside the module can read an
12255 // externally visible global, so the value escapes through it.
12256 if (auto *GV = dyn_cast<GlobalValue>(U.getUser()))
12257 if (!GV->hasLocalLinkage() && !A.isClosedWorldModule())
12258 return false;
12259 Follow = true;
12260 return true;
12261 }
12262
12263 LLVM_DEBUG(dbgs() << "[AAGlobalValueInfo] Check use: " << *U.get() << " in "
12264 << *UInst << "\n");
12265
12266 if (auto *Cmp = dyn_cast<ICmpInst>(U.getUser())) {
12267 int Idx = &Cmp->getOperandUse(0) == &U;
12268 if (isa<Constant>(Cmp->getOperand(Idx)))
12269 return true;
12270 return U == &getAnchorValue();
12271 }
12272
12273 // Explicitly catch return instructions.
12274 if (isa<ReturnInst>(UInst)) {
12275 auto CallSitePred = [&](AbstractCallSite ACS) {
12276 Worklist.push_back(ACS.getInstruction());
12277 return true;
12278 };
12279 bool UsedAssumedInformation = false;
12280 // TODO: We should traverse the uses or add a "non-call-site" CB.
12281 if (!A.checkForAllCallSites(CallSitePred, *UInst->getFunction(),
12282 /*RequireAllCallSites=*/true, this,
12283 UsedAssumedInformation))
12284 return false;
12285 return true;
12286 }
12287
12288 // For now we only use special logic for call sites. However, the tracker
12289 // itself knows about a lot of other non-capturing cases already.
12290 auto *CB = dyn_cast<CallBase>(UInst);
12291 if (!CB)
12292 return false;
12293 // Direct calls are OK uses.
12294 if (CB->isCallee(&U))
12295 return true;
12296 // Non-argument uses are scary.
12297 if (!CB->isArgOperand(&U))
12298 return false;
12299 // TODO: Iterate callees.
12300 auto *Fn = dyn_cast<Function>(CB->getCalledOperand());
12301 if (!Fn || !A.isFunctionIPOAmendable(*Fn))
12302 return false;
12303
12304 unsigned ArgNo = CB->getArgOperandNo(&U);
12305 Worklist.push_back(Fn->getArg(ArgNo));
12306 return true;
12307 }
12308
12309 ChangeStatus updateImpl(Attributor &A) override {
12310 unsigned NumUsesBefore = Uses.size();
12311
12312 SmallPtrSet<const Value *, 8> Visited;
12314 Worklist.push_back(&getAnchorValue());
12315
12316 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
12317 Uses.insert(&U);
12318 // TODO(captures): Make this more precise.
12319 UseCaptureInfo CI = DetermineUseCaptureKind(U, /*Base=*/nullptr);
12320 if (CI.isPassthrough()) {
12321 Follow = true;
12322 return true;
12323 }
12324 return checkUse(A, U, Follow, Worklist);
12325 };
12326 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) {
12327 Uses.insert(&OldU);
12328 return true;
12329 };
12330
12331 while (!Worklist.empty()) {
12332 const Value *V = Worklist.pop_back_val();
12333 if (!Visited.insert(V).second)
12334 continue;
12335 if (!A.checkForAllUses(UsePred, *this, *V,
12336 /* CheckBBLivenessOnly */ true,
12337 DepClassTy::OPTIONAL,
12338 /* IgnoreDroppableUses */ true, EquivalentUseCB)) {
12339 return indicatePessimisticFixpoint();
12340 }
12341 }
12342
12343 return Uses.size() == NumUsesBefore ? ChangeStatus::UNCHANGED
12344 : ChangeStatus::CHANGED;
12345 }
12346
12347 bool isPotentialUse(const Use &U) const override {
12348 return !isValidState() || Uses.contains(&U);
12349 }
12350
12351 /// See AbstractAttribute::manifest(...).
12352 ChangeStatus manifest(Attributor &A) override {
12353 return ChangeStatus::UNCHANGED;
12354 }
12355
12356 /// See AbstractAttribute::getAsStr().
12357 const std::string getAsStr(Attributor *A) const override {
12358 return "[" + std::to_string(Uses.size()) + " uses]";
12359 }
12360
12361 void trackStatistics() const override {
12362 STATS_DECLTRACK_FLOATING_ATTR(GlobalValuesTracked);
12363 }
12364
12365private:
12366 /// Set of (transitive) uses of this GlobalValue.
12367 SmallPtrSet<const Use *, 8> Uses;
12368};
12369} // namespace
12370
12371/// ------------------------ Indirect Call Info -------------------------------
12372namespace {
12373struct AAIndirectCallInfoCallSite : public AAIndirectCallInfo {
12374 AAIndirectCallInfoCallSite(const IRPosition &IRP, Attributor &A)
12375 : AAIndirectCallInfo(IRP, A) {}
12376
12377 /// See AbstractAttribute::initialize(...).
12378 void initialize(Attributor &A) override {
12379 auto *MD = getCtxI()->getMetadata(LLVMContext::MD_callees);
12380 if (!MD && !A.isClosedWorldModule())
12381 return;
12382
12383 if (MD) {
12384 for (const auto &Op : MD->operands())
12386 PotentialCallees.insert(Callee);
12387 } else if (A.isClosedWorldModule()) {
12388 ArrayRef<Function *> IndirectlyCallableFunctions =
12389 A.getInfoCache().getIndirectlyCallableFunctions(A);
12390 PotentialCallees.insert_range(IndirectlyCallableFunctions);
12391 }
12392
12393 if (PotentialCallees.empty())
12394 indicateOptimisticFixpoint();
12395 }
12396
12397 ChangeStatus updateImpl(Attributor &A) override {
12398 CallBase *CB = cast<CallBase>(getCtxI());
12399 const Use &CalleeUse = CB->getCalledOperandUse();
12400 Value *FP = CB->getCalledOperand();
12401
12402 SmallSetVector<Function *, 4> AssumedCalleesNow;
12403 bool AllCalleesKnownNow = AllCalleesKnown;
12404
12405 auto CheckPotentialCalleeUse = [&](Function &PotentialCallee,
12406 bool &UsedAssumedInformation) {
12407 const auto *GIAA = A.getAAFor<AAGlobalValueInfo>(
12408 *this, IRPosition::value(PotentialCallee), DepClassTy::OPTIONAL);
12409 if (!GIAA || GIAA->isPotentialUse(CalleeUse))
12410 return true;
12411 UsedAssumedInformation = !GIAA->isAtFixpoint();
12412 return false;
12413 };
12414
12415 auto AddPotentialCallees = [&]() {
12416 for (auto *PotentialCallee : PotentialCallees) {
12417 bool UsedAssumedInformation = false;
12418 if (CheckPotentialCalleeUse(*PotentialCallee, UsedAssumedInformation))
12419 AssumedCalleesNow.insert(PotentialCallee);
12420 }
12421 };
12422
12423 // Use simplification to find potential callees, if !callees was present,
12424 // fallback to that set if necessary.
12425 bool UsedAssumedInformation = false;
12427 if (!A.getAssumedSimplifiedValues(IRPosition::value(*FP), this, Values,
12428 AA::ValueScope::AnyScope,
12429 UsedAssumedInformation)) {
12430 if (PotentialCallees.empty())
12431 return indicatePessimisticFixpoint();
12432 AddPotentialCallees();
12433 }
12434
12435 // Try to find a reason for \p Fn not to be a potential callee. If none was
12436 // found, add it to the assumed callees set.
12437 auto CheckPotentialCallee = [&](Function &Fn) {
12438 if (!PotentialCallees.empty() && !PotentialCallees.count(&Fn))
12439 return false;
12440
12441 auto &CachedResult = FilterResults[&Fn];
12442 if (CachedResult.has_value())
12443 return CachedResult.value();
12444
12445 bool UsedAssumedInformation = false;
12446 if (!CheckPotentialCalleeUse(Fn, UsedAssumedInformation)) {
12447 if (!UsedAssumedInformation)
12448 CachedResult = false;
12449 return false;
12450 }
12451
12452 int NumFnArgs = Fn.arg_size();
12453 int NumCBArgs = CB->arg_size();
12454
12455 // Check if any excess argument (which we fill up with poison) is known to
12456 // be UB on undef.
12457 for (int I = NumCBArgs; I < NumFnArgs; ++I) {
12458 bool IsKnown = false;
12460 A, this, IRPosition::argument(*Fn.getArg(I)),
12461 DepClassTy::OPTIONAL, IsKnown)) {
12462 if (IsKnown)
12463 CachedResult = false;
12464 return false;
12465 }
12466 }
12467
12468 CachedResult = true;
12469 return true;
12470 };
12471
12472 // Check simplification result, prune known UB callees, also restrict it to
12473 // the !callees set, if present.
12474 for (auto &VAC : Values) {
12475 if (isa<UndefValue>(VAC.getValue()))
12476 continue;
12478 VAC.getValue()->getType()->getPointerAddressSpace() == 0)
12479 continue;
12480 // TODO: Check for known UB, e.g., poison + noundef.
12481 if (auto *VACFn = dyn_cast<Function>(VAC.getValue())) {
12482 if (CheckPotentialCallee(*VACFn))
12483 AssumedCalleesNow.insert(VACFn);
12484 continue;
12485 }
12486 if (!PotentialCallees.empty()) {
12487 AddPotentialCallees();
12488 break;
12489 }
12490 AllCalleesKnownNow = false;
12491 }
12492
12493 if (AssumedCalleesNow == AssumedCallees &&
12494 AllCalleesKnown == AllCalleesKnownNow)
12495 return ChangeStatus::UNCHANGED;
12496
12497 std::swap(AssumedCallees, AssumedCalleesNow);
12498 AllCalleesKnown = AllCalleesKnownNow;
12499 return ChangeStatus::CHANGED;
12500 }
12501
12502 /// See AbstractAttribute::manifest(...).
12503 ChangeStatus manifest(Attributor &A) override {
12504 // If we can't specialize at all, give up now.
12505 if (!AllCalleesKnown && AssumedCallees.empty())
12506 return ChangeStatus::UNCHANGED;
12507
12508 CallBase *CB = cast<CallBase>(getCtxI());
12509 bool UsedAssumedInformation = false;
12510 if (A.isAssumedDead(*CB, this, /*LivenessAA=*/nullptr,
12511 UsedAssumedInformation))
12512 return ChangeStatus::UNCHANGED;
12513
12514 ChangeStatus Changed = ChangeStatus::UNCHANGED;
12515 unsigned ProgramAS = CB->getDataLayout().getProgramAddressSpace();
12516 Value *FP = CB->getCalledOperand();
12517 if (FP->getType()->getPointerAddressSpace() != ProgramAS)
12518 FP = new AddrSpaceCastInst(
12519 FP, PointerType::get(FP->getContext(), ProgramAS),
12520 FP->getName() + ".as" + Twine(ProgramAS), CB->getIterator());
12521
12522 bool CBIsVoid = CB->getType()->isVoidTy();
12524 FunctionType *CSFT = CB->getFunctionType();
12525 SmallVector<Value *> CSArgs(CB->args());
12526
12527 // If we know all callees and there are none, the call site is (effectively)
12528 // dead (or UB).
12529 if (AssumedCallees.empty()) {
12530 assert(AllCalleesKnown &&
12531 "Expected all callees to be known if there are none.");
12532 A.changeToUnreachableAfterManifest(CB);
12533 return ChangeStatus::CHANGED;
12534 }
12535
12536 // Special handling for the single callee case.
12537 if (AllCalleesKnown && AssumedCallees.size() == 1) {
12538 auto *NewCallee = AssumedCallees.front();
12539 if (isLegalToPromote(*CB, NewCallee)) {
12540 promoteCall(*CB, NewCallee, nullptr);
12541 NumIndirectCallsPromoted++;
12542 return ChangeStatus::CHANGED;
12543 }
12544 Instruction *NewCall =
12545 CallInst::Create(FunctionCallee(CSFT, NewCallee), CSArgs,
12546 CB->getName(), CB->getIterator());
12547 if (!CBIsVoid)
12548 A.changeAfterManifest(IRPosition::callsite_returned(*CB), *NewCall);
12549 A.deleteAfterManifest(*CB);
12550 return ChangeStatus::CHANGED;
12551 }
12552
12553 // For each potential value we create a conditional
12554 //
12555 // ```
12556 // if (ptr == value) value(args);
12557 // else ...
12558 // ```
12559 //
12560 bool SpecializedForAnyCallees = false;
12561 bool SpecializedForAllCallees = AllCalleesKnown;
12562 ICmpInst *LastCmp = nullptr;
12563 SmallVector<Function *, 8> SkippedAssumedCallees;
12565 for (Function *NewCallee : AssumedCallees) {
12566 if (!A.shouldSpecializeCallSiteForCallee(*this, *CB, *NewCallee,
12567 AssumedCallees.size())) {
12568 SkippedAssumedCallees.push_back(NewCallee);
12569 SpecializedForAllCallees = false;
12570 continue;
12571 }
12572 SpecializedForAnyCallees = true;
12573
12574 LastCmp = new ICmpInst(IP, llvm::CmpInst::ICMP_EQ, FP, NewCallee);
12575 Instruction *ThenTI =
12576 SplitBlockAndInsertIfThen(LastCmp, IP, /* Unreachable */ false);
12577 BasicBlock *CBBB = CB->getParent();
12578 A.registerManifestAddedBasicBlock(*ThenTI->getParent());
12579 A.registerManifestAddedBasicBlock(*IP->getParent());
12580 auto *SplitTI = cast<CondBrInst>(LastCmp->getNextNode());
12581 BasicBlock *ElseBB;
12582 if (&*IP == CB) {
12583 ElseBB = BasicBlock::Create(ThenTI->getContext(), "",
12584 ThenTI->getFunction(), CBBB);
12585 A.registerManifestAddedBasicBlock(*ElseBB);
12586 IP = UncondBrInst::Create(CBBB, ElseBB)->getIterator();
12587 SplitTI->replaceUsesOfWith(CBBB, ElseBB);
12588 } else {
12589 ElseBB = IP->getParent();
12590 ThenTI->replaceUsesOfWith(ElseBB, CBBB);
12591 }
12592 CastInst *RetBC = nullptr;
12593 CallInst *NewCall = nullptr;
12594 if (isLegalToPromote(*CB, NewCallee)) {
12595 auto *CBClone = cast<CallBase>(CB->clone());
12596 CBClone->insertBefore(ThenTI->getIterator());
12597 NewCall = &cast<CallInst>(promoteCall(*CBClone, NewCallee, &RetBC));
12598 NumIndirectCallsPromoted++;
12599 } else {
12600 NewCall = CallInst::Create(FunctionCallee(CSFT, NewCallee), CSArgs,
12601 CB->getName(), ThenTI->getIterator());
12602 }
12603 NewCalls.push_back({NewCall, RetBC});
12604 }
12605
12606 auto AttachCalleeMetadata = [&](CallBase &IndirectCB) {
12607 if (!AllCalleesKnown)
12608 return ChangeStatus::UNCHANGED;
12609 MDBuilder MDB(IndirectCB.getContext());
12610 MDNode *Callees = MDB.createCallees(SkippedAssumedCallees);
12611 IndirectCB.setMetadata(LLVMContext::MD_callees, Callees);
12612 return ChangeStatus::CHANGED;
12613 };
12614
12615 if (!SpecializedForAnyCallees)
12616 return AttachCalleeMetadata(*CB);
12617
12618 // Check if we need the fallback indirect call still.
12619 if (SpecializedForAllCallees) {
12621 LastCmp->eraseFromParent();
12622 new UnreachableInst(IP->getContext(), IP);
12623 IP->eraseFromParent();
12624 } else {
12625 auto *CBClone = cast<CallInst>(CB->clone());
12626 CBClone->setName(CB->getName());
12627 CBClone->insertBefore(*IP->getParent(), IP);
12628 NewCalls.push_back({CBClone, nullptr});
12629 AttachCalleeMetadata(*CBClone);
12630 }
12631
12632 // Check if we need a PHI to merge the results.
12633 if (!CBIsVoid) {
12634 auto *PHI = PHINode::Create(CB->getType(), NewCalls.size(),
12635 CB->getName() + ".phi",
12636 CB->getParent()->getFirstInsertionPt());
12637 for (auto &It : NewCalls) {
12638 CallBase *NewCall = It.first;
12639 Instruction *CallRet = It.second ? It.second : It.first;
12640 if (CallRet->getType() == CB->getType())
12641 PHI->addIncoming(CallRet, CallRet->getParent());
12642 else if (NewCall->getType()->isVoidTy())
12643 PHI->addIncoming(PoisonValue::get(CB->getType()),
12644 NewCall->getParent());
12645 else
12646 llvm_unreachable("Call return should match or be void!");
12647 }
12648 A.changeAfterManifest(IRPosition::callsite_returned(*CB), *PHI);
12649 }
12650
12651 A.deleteAfterManifest(*CB);
12652 Changed = ChangeStatus::CHANGED;
12653
12654 return Changed;
12655 }
12656
12657 /// See AbstractAttribute::getAsStr().
12658 const std::string getAsStr(Attributor *A) const override {
12659 return std::string(AllCalleesKnown ? "eliminate" : "specialize") +
12660 " indirect call site with " + std::to_string(AssumedCallees.size()) +
12661 " functions";
12662 }
12663
12664 void trackStatistics() const override {
12665 if (AllCalleesKnown) {
12667 Eliminated, CallSites,
12668 "Number of indirect call sites eliminated via specialization")
12669 } else {
12670 STATS_DECLTRACK(Specialized, CallSites,
12671 "Number of indirect call sites specialized")
12672 }
12673 }
12674
12675 bool foreachCallee(function_ref<bool(Function *)> CB) const override {
12676 return isValidState() && AllCalleesKnown && all_of(AssumedCallees, CB);
12677 }
12678
12679private:
12680 /// Map to remember filter results.
12681 DenseMap<Function *, std::optional<bool>> FilterResults;
12682
12683 /// If the !callee metadata was present, this set will contain all potential
12684 /// callees (superset).
12685 SmallSetVector<Function *, 4> PotentialCallees;
12686
12687 /// This set contains all currently assumed calllees, which might grow over
12688 /// time.
12689 SmallSetVector<Function *, 4> AssumedCallees;
12690
12691 /// Flag to indicate if all possible callees are in the AssumedCallees set or
12692 /// if there could be others.
12693 bool AllCalleesKnown = true;
12694};
12695} // namespace
12696
12697/// --------------------- Invariant Load Pointer -------------------------------
12698namespace {
12699
12700struct AAInvariantLoadPointerImpl
12701 : public StateWrapper<BitIntegerState<uint8_t, 15>,
12702 AAInvariantLoadPointer> {
12703
12704 enum {
12705 // pointer does not alias within the bounds of the function
12706 IS_NOALIAS = 1 << 0,
12707 // pointer is not involved in any effectful instructions within the bounds
12708 // of the function
12709 IS_NOEFFECT = 1 << 1,
12710 // loads are invariant within the bounds of the function
12711 IS_LOCALLY_INVARIANT = 1 << 2,
12712 // memory lifetime is constrained within the bounds of the function
12713 IS_LOCALLY_CONSTRAINED = 1 << 3,
12714
12715 IS_BEST_STATE = IS_NOALIAS | IS_NOEFFECT | IS_LOCALLY_INVARIANT |
12716 IS_LOCALLY_CONSTRAINED,
12717 };
12718 static_assert(getBestState() == IS_BEST_STATE, "Unexpected best state");
12719
12720 using Base =
12721 StateWrapper<BitIntegerState<uint8_t, 15>, AAInvariantLoadPointer>;
12722
12723 // the BitIntegerState is optimistic about IS_NOALIAS and IS_NOEFFECT, but
12724 // pessimistic about IS_KNOWN_INVARIANT
12725 AAInvariantLoadPointerImpl(const IRPosition &IRP, Attributor &A)
12726 : Base(IRP) {}
12727
12728 bool isKnownInvariant() const final {
12729 return isKnownLocallyInvariant() && isKnown(IS_LOCALLY_CONSTRAINED);
12730 }
12731
12732 bool isKnownLocallyInvariant() const final {
12733 if (isKnown(IS_LOCALLY_INVARIANT))
12734 return true;
12735 return isKnown(IS_NOALIAS | IS_NOEFFECT);
12736 }
12737
12738 bool isAssumedInvariant() const final {
12739 return isAssumedLocallyInvariant() && isAssumed(IS_LOCALLY_CONSTRAINED);
12740 }
12741
12742 bool isAssumedLocallyInvariant() const final {
12743 if (isAssumed(IS_LOCALLY_INVARIANT))
12744 return true;
12745 return isAssumed(IS_NOALIAS | IS_NOEFFECT);
12746 }
12747
12748 ChangeStatus updateImpl(Attributor &A) override {
12749 ChangeStatus Changed = ChangeStatus::UNCHANGED;
12750
12751 Changed |= updateNoAlias(A);
12752 if (requiresNoAlias() && !isAssumed(IS_NOALIAS))
12753 return indicatePessimisticFixpoint();
12754
12755 Changed |= updateNoEffect(A);
12756
12757 Changed |= updateLocalInvariance(A);
12758
12759 return Changed;
12760 }
12761
12762 ChangeStatus manifest(Attributor &A) override {
12763 if (!isKnownInvariant())
12764 return ChangeStatus::UNCHANGED;
12765
12766 ChangeStatus Changed = ChangeStatus::UNCHANGED;
12767 const Value *Ptr = &getAssociatedValue();
12768 const auto TagInvariantLoads = [&](const Use &U, bool &) {
12769 if (U.get() != Ptr)
12770 return true;
12771 auto *I = dyn_cast<Instruction>(U.getUser());
12772 if (!I)
12773 return true;
12774
12775 // Ensure that we are only changing uses from the corresponding callgraph
12776 // SSC in the case that the AA isn't run on the entire module
12777 if (!A.isRunOn(I->getFunction()))
12778 return true;
12779
12780 if (I->hasMetadata(LLVMContext::MD_invariant_load))
12781 return true;
12782
12783 if (auto *LI = dyn_cast<LoadInst>(I)) {
12784 LI->setMetadata(LLVMContext::MD_invariant_load,
12785 MDNode::get(LI->getContext(), {}));
12786 Changed = ChangeStatus::CHANGED;
12787 }
12788 return true;
12789 };
12790
12791 (void)A.checkForAllUses(TagInvariantLoads, *this, *Ptr);
12792 return Changed;
12793 }
12794
12795 /// See AbstractAttribute::getAsStr().
12796 const std::string getAsStr(Attributor *) const override {
12797 if (isKnownInvariant())
12798 return "load-invariant pointer";
12799 return "non-invariant pointer";
12800 }
12801
12802 /// See AbstractAttribute::trackStatistics().
12803 void trackStatistics() const override {}
12804
12805private:
12806 /// Indicate that noalias is required for the pointer to be invariant.
12807 bool requiresNoAlias() const {
12808 switch (getPositionKind()) {
12809 default:
12810 // Conservatively default to require noalias.
12811 return true;
12812 case IRP_FLOAT:
12813 case IRP_RETURNED:
12814 case IRP_CALL_SITE:
12815 return false;
12816 case IRP_CALL_SITE_RETURNED: {
12817 const auto &CB = cast<CallBase>(getAnchorValue());
12819 &CB, /*MustPreserveOffset=*/false);
12820 }
12821 case IRP_ARGUMENT: {
12822 const Function *F = getAssociatedFunction();
12823 assert(F && "no associated function for argument");
12824 return !isCallableCC(F->getCallingConv());
12825 }
12826 }
12827 }
12828
12829 bool isExternal() const {
12830 const Function *F = getAssociatedFunction();
12831 if (!F)
12832 return true;
12833 return isCallableCC(F->getCallingConv()) &&
12834 getPositionKind() != IRP_CALL_SITE_RETURNED;
12835 }
12836
12837 ChangeStatus updateNoAlias(Attributor &A) {
12838 if (isKnown(IS_NOALIAS) || !isAssumed(IS_NOALIAS))
12839 return ChangeStatus::UNCHANGED;
12840
12841 // Try to use AANoAlias.
12842 if (const auto *ANoAlias = A.getOrCreateAAFor<AANoAlias>(
12843 getIRPosition(), this, DepClassTy::REQUIRED)) {
12844 if (ANoAlias->isKnownNoAlias()) {
12845 addKnownBits(IS_NOALIAS);
12846 return ChangeStatus::CHANGED;
12847 }
12848
12849 if (!ANoAlias->isAssumedNoAlias()) {
12850 removeAssumedBits(IS_NOALIAS);
12851 return ChangeStatus::CHANGED;
12852 }
12853
12854 return ChangeStatus::UNCHANGED;
12855 }
12856
12857 // Try to infer noalias from argument attribute, since it is applicable for
12858 // the duration of the function.
12859 if (const Argument *Arg = getAssociatedArgument()) {
12860 if (Arg->hasNoAliasAttr()) {
12861 addKnownBits(IS_NOALIAS);
12862 return ChangeStatus::UNCHANGED;
12863 }
12864
12865 // Noalias information is not provided, and cannot be inferred,
12866 // so we conservatively assume the pointer aliases.
12867 removeAssumedBits(IS_NOALIAS);
12868 return ChangeStatus::CHANGED;
12869 }
12870
12871 return ChangeStatus::UNCHANGED;
12872 }
12873
12874 ChangeStatus updateNoEffect(Attributor &A) {
12875 if (isKnown(IS_NOEFFECT) || !isAssumed(IS_NOEFFECT))
12876 return ChangeStatus::UNCHANGED;
12877
12878 if (!getAssociatedFunction())
12879 return indicatePessimisticFixpoint();
12880
12881 if (isa<AllocaInst>(&getAssociatedValue()))
12882 return indicatePessimisticFixpoint();
12883
12884 const auto HasNoEffectLoads = [&](const Use &U, bool &) {
12885 const auto *LI = dyn_cast<LoadInst>(U.getUser());
12886 return !LI || !LI->mayHaveSideEffects();
12887 };
12888 if (!A.checkForAllUses(HasNoEffectLoads, *this, getAssociatedValue()))
12889 return indicatePessimisticFixpoint();
12890
12891 if (const auto *AMemoryBehavior = A.getOrCreateAAFor<AAMemoryBehavior>(
12892 getIRPosition(), this, DepClassTy::REQUIRED)) {
12893 // For non-instructions, try to use AAMemoryBehavior to infer the readonly
12894 // attribute
12895 if (!AMemoryBehavior->isAssumedReadOnly())
12896 return indicatePessimisticFixpoint();
12897
12898 if (AMemoryBehavior->isKnownReadOnly()) {
12899 addKnownBits(IS_NOEFFECT);
12900 return ChangeStatus::UNCHANGED;
12901 }
12902
12903 return ChangeStatus::UNCHANGED;
12904 }
12905
12906 if (const Argument *Arg = getAssociatedArgument()) {
12907 if (Arg->onlyReadsMemory()) {
12908 addKnownBits(IS_NOEFFECT);
12909 return ChangeStatus::UNCHANGED;
12910 }
12911
12912 // Readonly information is not provided, and cannot be inferred from
12913 // AAMemoryBehavior.
12914 return indicatePessimisticFixpoint();
12915 }
12916
12917 return ChangeStatus::UNCHANGED;
12918 }
12919
12920 ChangeStatus updateLocalInvariance(Attributor &A) {
12921 if (isKnown(IS_LOCALLY_INVARIANT) || !isAssumed(IS_LOCALLY_INVARIANT))
12922 return ChangeStatus::UNCHANGED;
12923
12924 // try to infer invariance from underlying objects
12925 const auto *AUO = A.getOrCreateAAFor<AAUnderlyingObjects>(
12926 getIRPosition(), this, DepClassTy::REQUIRED);
12927 if (!AUO)
12928 return ChangeStatus::UNCHANGED;
12929
12930 bool UsedAssumedInformation = false;
12931 const auto IsLocallyInvariantLoadIfPointer = [&](const Value &V) {
12932 if (!V.getType()->isPointerTy())
12933 return true;
12934 const auto *IsInvariantLoadPointer =
12935 A.getOrCreateAAFor<AAInvariantLoadPointer>(IRPosition::value(V), this,
12936 DepClassTy::REQUIRED);
12937 // Conservatively fail if invariance cannot be inferred.
12938 if (!IsInvariantLoadPointer)
12939 return false;
12940
12941 if (IsInvariantLoadPointer->isKnownLocallyInvariant())
12942 return true;
12943 if (!IsInvariantLoadPointer->isAssumedLocallyInvariant())
12944 return false;
12945
12946 UsedAssumedInformation = true;
12947 return true;
12948 };
12949 if (!AUO->forallUnderlyingObjects(IsLocallyInvariantLoadIfPointer))
12950 return indicatePessimisticFixpoint();
12951
12952 if (const auto *CB = dyn_cast<CallBase>(&getAnchorValue())) {
12954 CB, /*MustPreserveOffset=*/false)) {
12955 for (const Value *Arg : CB->args()) {
12956 if (!IsLocallyInvariantLoadIfPointer(*Arg))
12957 return indicatePessimisticFixpoint();
12958 }
12959 }
12960 }
12961
12962 if (!UsedAssumedInformation) {
12963 // Pointer is known and not just assumed to be locally invariant.
12964 addKnownBits(IS_LOCALLY_INVARIANT);
12965 return ChangeStatus::CHANGED;
12966 }
12967
12968 return ChangeStatus::UNCHANGED;
12969 }
12970};
12971
12972struct AAInvariantLoadPointerFloating final : AAInvariantLoadPointerImpl {
12973 AAInvariantLoadPointerFloating(const IRPosition &IRP, Attributor &A)
12974 : AAInvariantLoadPointerImpl(IRP, A) {}
12975};
12976
12977struct AAInvariantLoadPointerReturned final : AAInvariantLoadPointerImpl {
12978 AAInvariantLoadPointerReturned(const IRPosition &IRP, Attributor &A)
12979 : AAInvariantLoadPointerImpl(IRP, A) {}
12980
12981 void initialize(Attributor &) override {
12982 removeAssumedBits(IS_LOCALLY_CONSTRAINED);
12983 }
12984};
12985
12986struct AAInvariantLoadPointerCallSiteReturned final
12987 : AAInvariantLoadPointerImpl {
12988 AAInvariantLoadPointerCallSiteReturned(const IRPosition &IRP, Attributor &A)
12989 : AAInvariantLoadPointerImpl(IRP, A) {}
12990
12991 void initialize(Attributor &A) override {
12992 const Function *F = getAssociatedFunction();
12993 assert(F && "no associated function for return from call");
12994
12995 if (!F->isDeclaration() && !F->isIntrinsic())
12996 return AAInvariantLoadPointerImpl::initialize(A);
12997
12998 const auto &CB = cast<CallBase>(getAnchorValue());
13000 &CB, /*MustPreserveOffset=*/false))
13001 return AAInvariantLoadPointerImpl::initialize(A);
13002
13003 if (F->onlyReadsMemory() && F->hasNoSync())
13004 return AAInvariantLoadPointerImpl::initialize(A);
13005
13006 // At this point, the function is opaque, so we conservatively assume
13007 // non-invariance.
13008 indicatePessimisticFixpoint();
13009 }
13010};
13011
13012struct AAInvariantLoadPointerArgument final : AAInvariantLoadPointerImpl {
13013 AAInvariantLoadPointerArgument(const IRPosition &IRP, Attributor &A)
13014 : AAInvariantLoadPointerImpl(IRP, A) {}
13015
13016 void initialize(Attributor &) override {
13017 const Function *F = getAssociatedFunction();
13018 assert(F && "no associated function for argument");
13019
13020 if (!isCallableCC(F->getCallingConv())) {
13021 addKnownBits(IS_LOCALLY_CONSTRAINED);
13022 return;
13023 }
13024
13025 if (!F->hasLocalLinkage())
13026 removeAssumedBits(IS_LOCALLY_CONSTRAINED);
13027 }
13028};
13029
13030struct AAInvariantLoadPointerCallSiteArgument final
13031 : AAInvariantLoadPointerImpl {
13032 AAInvariantLoadPointerCallSiteArgument(const IRPosition &IRP, Attributor &A)
13033 : AAInvariantLoadPointerImpl(IRP, A) {}
13034};
13035} // namespace
13036
13037/// ------------------------ Address Space ------------------------------------
13038namespace {
13039
13040template <typename InstType>
13041static bool makeChange(Attributor &A, InstType *MemInst, const Use &U,
13042 Value *OriginalValue, PointerType *NewPtrTy,
13043 bool UseOriginalValue) {
13044 if (U.getOperandNo() != InstType::getPointerOperandIndex())
13045 return false;
13046
13047 if (MemInst->isVolatile()) {
13048 auto *TTI = A.getInfoCache().getAnalysisResultForFunction<TargetIRAnalysis>(
13049 *MemInst->getFunction());
13050 unsigned NewAS = NewPtrTy->getPointerAddressSpace();
13051 if (!TTI || !TTI->hasVolatileVariant(MemInst, NewAS))
13052 return false;
13053 }
13054
13055 if (UseOriginalValue) {
13056 A.changeUseAfterManifest(const_cast<Use &>(U), *OriginalValue);
13057 return true;
13058 }
13059
13060 Instruction *CastInst = new AddrSpaceCastInst(OriginalValue, NewPtrTy);
13061 CastInst->insertBefore(MemInst->getIterator());
13062 A.changeUseAfterManifest(const_cast<Use &>(U), *CastInst);
13063 return true;
13064}
13065
13066struct AAAddressSpaceImpl : public AAAddressSpace {
13067 AAAddressSpaceImpl(const IRPosition &IRP, Attributor &A)
13068 : AAAddressSpace(IRP, A) {}
13069
13070 uint32_t getAddressSpace() const override {
13071 assert(isValidState() && "the AA is invalid");
13072 return AssumedAddressSpace;
13073 }
13074
13075 /// See AbstractAttribute::initialize(...).
13076 void initialize(Attributor &A) override {
13077 assert(getAssociatedType()->isPtrOrPtrVectorTy() &&
13078 "Associated value is not a pointer");
13079
13080 if (!A.getInfoCache().getFlatAddressSpace().has_value()) {
13081 indicatePessimisticFixpoint();
13082 return;
13083 }
13084
13085 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13086 unsigned AS = getAssociatedType()->getPointerAddressSpace();
13087 if (AS != FlatAS) {
13088 [[maybe_unused]] bool R = takeAddressSpace(AS);
13089 assert(R && "The take should happen");
13090 indicateOptimisticFixpoint();
13091 }
13092 }
13093
13094 ChangeStatus updateImpl(Attributor &A) override {
13095 uint32_t OldAddressSpace = AssumedAddressSpace;
13096 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13097
13098 auto CheckAddressSpace = [&](Value &Obj) {
13099 // Ignore undef.
13100 if (isa<UndefValue>(&Obj))
13101 return true;
13102
13103 // If the object already has a non-flat address space, we simply take it.
13104 unsigned ObjAS = Obj.getType()->getPointerAddressSpace();
13105 if (ObjAS != FlatAS)
13106 return takeAddressSpace(ObjAS);
13107
13108 // At this point, we know Obj is in the flat address space. For a final
13109 // attempt, we want to use getAssumedAddrSpace, but first we must get the
13110 // associated function, if possible.
13111 Function *F = nullptr;
13112 if (auto *Arg = dyn_cast<Argument>(&Obj))
13113 F = Arg->getParent();
13114 else if (auto *I = dyn_cast<Instruction>(&Obj))
13115 F = I->getFunction();
13116
13117 // Use getAssumedAddrSpace if the associated function exists.
13118 if (F) {
13119 auto *TTI =
13120 A.getInfoCache().getAnalysisResultForFunction<TargetIRAnalysis>(*F);
13121 unsigned AssumedAS = TTI->getAssumedAddrSpace(&Obj);
13122 if (AssumedAS != ~0U)
13123 return takeAddressSpace(AssumedAS);
13124 }
13125
13126 // Now we can't do anything else but to take the flat AS.
13127 return takeAddressSpace(FlatAS);
13128 };
13129
13130 auto *AUO = A.getOrCreateAAFor<AAUnderlyingObjects>(getIRPosition(), this,
13131 DepClassTy::REQUIRED);
13132 if (!AUO->forallUnderlyingObjects(CheckAddressSpace))
13133 return indicatePessimisticFixpoint();
13134
13135 return OldAddressSpace == AssumedAddressSpace ? ChangeStatus::UNCHANGED
13136 : ChangeStatus::CHANGED;
13137 }
13138
13139 /// See AbstractAttribute::manifest(...).
13140 ChangeStatus manifest(Attributor &A) override {
13141 unsigned NewAS = getAddressSpace();
13142
13143 if (NewAS == InvalidAddressSpace ||
13144 NewAS == getAssociatedType()->getPointerAddressSpace())
13145 return ChangeStatus::UNCHANGED;
13146
13147 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13148
13149 Value *AssociatedValue = &getAssociatedValue();
13150 Value *OriginalValue = peelAddrspacecast(AssociatedValue, FlatAS);
13151
13152 PointerType *NewPtrTy =
13153 PointerType::get(getAssociatedType()->getContext(), NewAS);
13154 bool UseOriginalValue =
13155 OriginalValue->getType()->getPointerAddressSpace() == NewAS;
13156
13157 bool Changed = false;
13158
13159 auto Pred = [&](const Use &U, bool &) {
13160 if (U.get() != AssociatedValue)
13161 return true;
13162 auto *Inst = dyn_cast<Instruction>(U.getUser());
13163 if (!Inst)
13164 return true;
13165 // This is a WA to make sure we only change uses from the corresponding
13166 // CGSCC if the AA is run on CGSCC instead of the entire module.
13167 if (!A.isRunOn(Inst->getFunction()))
13168 return true;
13169 if (auto *LI = dyn_cast<LoadInst>(Inst)) {
13170 Changed |=
13171 makeChange(A, LI, U, OriginalValue, NewPtrTy, UseOriginalValue);
13172 } else if (auto *SI = dyn_cast<StoreInst>(Inst)) {
13173 Changed |=
13174 makeChange(A, SI, U, OriginalValue, NewPtrTy, UseOriginalValue);
13175 } else if (auto *RMW = dyn_cast<AtomicRMWInst>(Inst)) {
13176 Changed |=
13177 makeChange(A, RMW, U, OriginalValue, NewPtrTy, UseOriginalValue);
13178 } else if (auto *CmpX = dyn_cast<AtomicCmpXchgInst>(Inst)) {
13179 Changed |=
13180 makeChange(A, CmpX, U, OriginalValue, NewPtrTy, UseOriginalValue);
13181 }
13182 return true;
13183 };
13184
13185 // It doesn't matter if we can't check all uses as we can simply
13186 // conservatively ignore those that can not be visited.
13187 (void)A.checkForAllUses(Pred, *this, getAssociatedValue(),
13188 /* CheckBBLivenessOnly */ true);
13189
13190 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
13191 }
13192
13193 /// See AbstractAttribute::getAsStr().
13194 const std::string getAsStr(Attributor *A) const override {
13195 if (!isValidState())
13196 return "addrspace(<invalid>)";
13197 return "addrspace(" +
13198 (AssumedAddressSpace == InvalidAddressSpace
13199 ? "none"
13200 : std::to_string(AssumedAddressSpace)) +
13201 ")";
13202 }
13203
13204private:
13205 uint32_t AssumedAddressSpace = InvalidAddressSpace;
13206
13207 bool takeAddressSpace(uint32_t AS) {
13208 if (AssumedAddressSpace == InvalidAddressSpace) {
13209 AssumedAddressSpace = AS;
13210 return true;
13211 }
13212 return AssumedAddressSpace == AS;
13213 }
13214
13215 static Value *peelAddrspacecast(Value *V, unsigned FlatAS) {
13216 if (auto *I = dyn_cast<AddrSpaceCastInst>(V)) {
13217 assert(I->getSrcAddressSpace() != FlatAS &&
13218 "there should not be flat AS -> non-flat AS");
13219 return I->getPointerOperand();
13220 }
13221 if (auto *C = dyn_cast<ConstantExpr>(V))
13222 if (C->getOpcode() == Instruction::AddrSpaceCast) {
13223 assert(C->getOperand(0)->getType()->getPointerAddressSpace() !=
13224 FlatAS &&
13225 "there should not be flat AS -> non-flat AS X");
13226 return C->getOperand(0);
13227 }
13228 return V;
13229 }
13230};
13231
13232struct AAAddressSpaceFloating final : AAAddressSpaceImpl {
13233 AAAddressSpaceFloating(const IRPosition &IRP, Attributor &A)
13234 : AAAddressSpaceImpl(IRP, A) {}
13235
13236 void trackStatistics() const override {
13238 }
13239};
13240
13241struct AAAddressSpaceReturned final : AAAddressSpaceImpl {
13242 AAAddressSpaceReturned(const IRPosition &IRP, Attributor &A)
13243 : AAAddressSpaceImpl(IRP, A) {}
13244
13245 /// See AbstractAttribute::initialize(...).
13246 void initialize(Attributor &A) override {
13247 // TODO: we don't rewrite function argument for now because it will need to
13248 // rewrite the function signature and all call sites.
13249 (void)indicatePessimisticFixpoint();
13250 }
13251
13252 void trackStatistics() const override {
13253 STATS_DECLTRACK_FNRET_ATTR(addrspace);
13254 }
13255};
13256
13257struct AAAddressSpaceCallSiteReturned final : AAAddressSpaceImpl {
13258 AAAddressSpaceCallSiteReturned(const IRPosition &IRP, Attributor &A)
13259 : AAAddressSpaceImpl(IRP, A) {}
13260
13261 void trackStatistics() const override {
13262 STATS_DECLTRACK_CSRET_ATTR(addrspace);
13263 }
13264};
13265
13266struct AAAddressSpaceArgument final : AAAddressSpaceImpl {
13267 AAAddressSpaceArgument(const IRPosition &IRP, Attributor &A)
13268 : AAAddressSpaceImpl(IRP, A) {}
13269
13270 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(addrspace); }
13271};
13272
13273struct AAAddressSpaceCallSiteArgument final : AAAddressSpaceImpl {
13274 AAAddressSpaceCallSiteArgument(const IRPosition &IRP, Attributor &A)
13275 : AAAddressSpaceImpl(IRP, A) {}
13276
13277 /// See AbstractAttribute::initialize(...).
13278 void initialize(Attributor &A) override {
13279 // TODO: we don't rewrite call site argument for now because it will need to
13280 // rewrite the function signature of the callee.
13281 (void)indicatePessimisticFixpoint();
13282 }
13283
13284 void trackStatistics() const override {
13285 STATS_DECLTRACK_CSARG_ATTR(addrspace);
13286 }
13287};
13288} // namespace
13289
13290/// ------------------------ No Alias Address Space ---------------------------
13291// This attribute assumes flat address space can alias all other address space
13292
13293// TODO: this is similar to AAAddressSpace, most of the code should be merged.
13294// But merging it created failing cased on gateway test that cannot be
13295// reproduced locally. So should open a separated PR to handle the merge of
13296// AANoAliasAddrSpace and AAAddressSpace attribute
13297
13298namespace {
13299struct AANoAliasAddrSpaceImpl : public AANoAliasAddrSpace {
13300 AANoAliasAddrSpaceImpl(const IRPosition &IRP, Attributor &A)
13301 : AANoAliasAddrSpace(IRP, A) {}
13302
13303 void initialize(Attributor &A) override {
13304 assert(getAssociatedType()->isPtrOrPtrVectorTy() &&
13305 "Associated value is not a pointer");
13306
13307 resetASRanges(A);
13308
13309 std::optional<unsigned> FlatAS = A.getInfoCache().getFlatAddressSpace();
13310 if (!FlatAS.has_value()) {
13311 indicatePessimisticFixpoint();
13312 return;
13313 }
13314
13315 removeAS(*FlatAS);
13316
13317 unsigned AS = getAssociatedType()->getPointerAddressSpace();
13318 if (AS != *FlatAS) {
13319 removeAS(AS);
13320 indicateOptimisticFixpoint();
13321 }
13322 }
13323
13324 ChangeStatus updateImpl(Attributor &A) override {
13325 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13326 uint32_t OldAssumed = getAssumed();
13327
13328 auto CheckAddressSpace = [&](Value &Obj) {
13329 if (isa<PoisonValue>(&Obj))
13330 return true;
13331
13332 unsigned AS = Obj.getType()->getPointerAddressSpace();
13333 if (AS == FlatAS)
13334 return false;
13335
13336 removeAS(Obj.getType()->getPointerAddressSpace());
13337 return true;
13338 };
13339
13340 const AAUnderlyingObjects *AUO = A.getOrCreateAAFor<AAUnderlyingObjects>(
13341 getIRPosition(), this, DepClassTy::REQUIRED);
13342 if (!AUO->forallUnderlyingObjects(CheckAddressSpace))
13343 return indicatePessimisticFixpoint();
13344
13345 return OldAssumed == getAssumed() ? ChangeStatus::UNCHANGED
13346 : ChangeStatus::CHANGED;
13347 }
13348
13349 /// See AbstractAttribute::manifest(...).
13350 ChangeStatus manifest(Attributor &A) override {
13351 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13352
13353 unsigned AS = getAssociatedType()->getPointerAddressSpace();
13354 if (AS != FlatAS || Map.empty())
13355 return ChangeStatus::UNCHANGED;
13356
13357 LLVMContext &Ctx = getAssociatedValue().getContext();
13358 MDNode *NoAliasASNode = nullptr;
13359 MDBuilder MDB(Ctx);
13360 // Has to use iterator to get the range info.
13361 for (RangeMap::const_iterator I = Map.begin(); I != Map.end(); I++) {
13362 if (!I.value())
13363 continue;
13364 unsigned Upper = I.stop();
13365 unsigned Lower = I.start();
13366 if (!NoAliasASNode) {
13367 NoAliasASNode = MDB.createRange(APInt(32, Lower), APInt(32, Upper + 1));
13368 continue;
13369 }
13370 MDNode *ASRange = MDB.createRange(APInt(32, Lower), APInt(32, Upper + 1));
13371 NoAliasASNode = MDNode::getMostGenericRange(NoAliasASNode, ASRange);
13372 }
13373
13374 Value *AssociatedValue = &getAssociatedValue();
13375 bool Changed = false;
13376
13377 auto AddNoAliasAttr = [&](const Use &U, bool &) {
13378 if (U.get() != AssociatedValue)
13379 return true;
13380 Instruction *Inst = dyn_cast<Instruction>(U.getUser());
13381 if (!Inst || Inst->hasMetadata(LLVMContext::MD_noalias_addrspace))
13382 return true;
13383 if (!isa<LoadInst>(Inst) && !isa<StoreInst>(Inst) &&
13385 return true;
13386 if (!A.isRunOn(Inst->getFunction()))
13387 return true;
13388 Inst->setMetadata(LLVMContext::MD_noalias_addrspace, NoAliasASNode);
13389 Changed = true;
13390 return true;
13391 };
13392 (void)A.checkForAllUses(AddNoAliasAttr, *this, *AssociatedValue,
13393 /*CheckBBLivenessOnly=*/true);
13394 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
13395 }
13396
13397 /// See AbstractAttribute::getAsStr().
13398 const std::string getAsStr(Attributor *A) const override {
13399 if (!isValidState())
13400 return "<invalid>";
13401 std::string Str;
13402 raw_string_ostream OS(Str);
13403 OS << "CanNotBeAddrSpace(";
13404 for (RangeMap::const_iterator I = Map.begin(); I != Map.end(); I++) {
13405 unsigned Upper = I.stop();
13406 unsigned Lower = I.start();
13407 OS << ' ' << '[' << Upper << ',' << Lower + 1 << ')';
13408 }
13409 OS << " )";
13410 return OS.str();
13411 }
13412
13413private:
13414 void removeAS(unsigned AS) {
13415 RangeMap::iterator I = Map.find(AS);
13416
13417 if (I != Map.end()) {
13418 unsigned Upper = I.stop();
13419 unsigned Lower = I.start();
13420 I.erase();
13421 if (Upper == Lower)
13422 return;
13423 if (AS != ~((unsigned)0) && AS + 1 <= Upper)
13424 Map.insert(AS + 1, Upper, /*what ever this variable name is=*/true);
13425 if (AS != 0 && Lower <= AS - 1)
13426 Map.insert(Lower, AS - 1, true);
13427 }
13428 }
13429
13430 void resetASRanges(Attributor &A) {
13431 Map.clear();
13432 Map.insert(0, A.getInfoCache().getMaxAddrSpace(), true);
13433 }
13434};
13435
13436struct AANoAliasAddrSpaceFloating final : AANoAliasAddrSpaceImpl {
13437 AANoAliasAddrSpaceFloating(const IRPosition &IRP, Attributor &A)
13438 : AANoAliasAddrSpaceImpl(IRP, A) {}
13439
13440 void trackStatistics() const override {
13441 STATS_DECLTRACK_FLOATING_ATTR(noaliasaddrspace);
13442 }
13443};
13444
13445struct AANoAliasAddrSpaceReturned final : AANoAliasAddrSpaceImpl {
13446 AANoAliasAddrSpaceReturned(const IRPosition &IRP, Attributor &A)
13447 : AANoAliasAddrSpaceImpl(IRP, A) {}
13448
13449 void trackStatistics() const override {
13450 STATS_DECLTRACK_FNRET_ATTR(noaliasaddrspace);
13451 }
13452};
13453
13454struct AANoAliasAddrSpaceCallSiteReturned final : AANoAliasAddrSpaceImpl {
13455 AANoAliasAddrSpaceCallSiteReturned(const IRPosition &IRP, Attributor &A)
13456 : AANoAliasAddrSpaceImpl(IRP, A) {}
13457
13458 void trackStatistics() const override {
13459 STATS_DECLTRACK_CSRET_ATTR(noaliasaddrspace);
13460 }
13461};
13462
13463struct AANoAliasAddrSpaceArgument final : AANoAliasAddrSpaceImpl {
13464 AANoAliasAddrSpaceArgument(const IRPosition &IRP, Attributor &A)
13465 : AANoAliasAddrSpaceImpl(IRP, A) {}
13466
13467 void trackStatistics() const override {
13468 STATS_DECLTRACK_ARG_ATTR(noaliasaddrspace);
13469 }
13470};
13471
13472struct AANoAliasAddrSpaceCallSiteArgument final : AANoAliasAddrSpaceImpl {
13473 AANoAliasAddrSpaceCallSiteArgument(const IRPosition &IRP, Attributor &A)
13474 : AANoAliasAddrSpaceImpl(IRP, A) {}
13475
13476 void trackStatistics() const override {
13477 STATS_DECLTRACK_CSARG_ATTR(noaliasaddrspace);
13478 }
13479};
13480} // namespace
13481/// ----------- Allocation Info ----------
13482namespace {
13483struct AAAllocationInfoImpl : public AAAllocationInfo {
13484 AAAllocationInfoImpl(const IRPosition &IRP, Attributor &A)
13485 : AAAllocationInfo(IRP, A) {}
13486
13487 std::optional<TypeSize> getAllocatedSize() const override {
13488 assert(isValidState() && "the AA is invalid");
13489 return AssumedAllocatedSize;
13490 }
13491
13492 std::optional<TypeSize> findInitialAllocationSize(Instruction *I,
13493 const DataLayout &DL) {
13494
13495 // TODO: implement case for malloc like instructions
13496 switch (I->getOpcode()) {
13497 case Instruction::Alloca: {
13498 AllocaInst *AI = cast<AllocaInst>(I);
13499 return AI->getAllocationSize(DL);
13500 }
13501 default:
13502 return std::nullopt;
13503 }
13504 }
13505
13506 ChangeStatus updateImpl(Attributor &A) override {
13507
13508 const IRPosition &IRP = getIRPosition();
13509 Instruction *I = IRP.getCtxI();
13510
13511 // TODO: update check for malloc like calls
13512 if (!isa<AllocaInst>(I))
13513 return indicatePessimisticFixpoint();
13514
13515 bool IsKnownNoCapture;
13517 A, this, IRP, DepClassTy::OPTIONAL, IsKnownNoCapture))
13518 return indicatePessimisticFixpoint();
13519
13520 const AAPointerInfo *PI =
13521 A.getOrCreateAAFor<AAPointerInfo>(IRP, *this, DepClassTy::REQUIRED);
13522
13523 if (!PI)
13524 return indicatePessimisticFixpoint();
13525
13526 if (!PI->getState().isValidState() || PI->reachesReturn())
13527 return indicatePessimisticFixpoint();
13528
13529 const DataLayout &DL = A.getDataLayout();
13530 const auto AllocationSize = findInitialAllocationSize(I, DL);
13531
13532 // If allocation size is nullopt, we give up.
13533 if (!AllocationSize)
13534 return indicatePessimisticFixpoint();
13535
13536 // For zero sized allocations, we give up.
13537 // Since we can't reduce further
13538 if (*AllocationSize == 0)
13539 return indicatePessimisticFixpoint();
13540
13541 int64_t BinSize = PI->numOffsetBins();
13542
13543 // TODO: implement for multiple bins
13544 if (BinSize > 1)
13545 return indicatePessimisticFixpoint();
13546
13547 if (BinSize == 0) {
13548 auto NewAllocationSize = std::make_optional<TypeSize>(0, false);
13549 if (!changeAllocationSize(NewAllocationSize))
13550 return ChangeStatus::UNCHANGED;
13551 return ChangeStatus::CHANGED;
13552 }
13553
13554 // TODO: refactor this to be part of multiple bin case
13555 const auto &It = PI->begin();
13556
13557 // TODO: handle if Offset is not zero
13558 if (It->first.Offset != 0)
13559 return indicatePessimisticFixpoint();
13560
13561 uint64_t SizeOfBin = It->first.Offset + It->first.Size;
13562
13563 if (SizeOfBin >= *AllocationSize)
13564 return indicatePessimisticFixpoint();
13565
13566 auto NewAllocationSize = std::make_optional<TypeSize>(SizeOfBin * 8, false);
13567
13568 if (!changeAllocationSize(NewAllocationSize))
13569 return ChangeStatus::UNCHANGED;
13570
13571 return ChangeStatus::CHANGED;
13572 }
13573
13574 /// See AbstractAttribute::manifest(...).
13575 ChangeStatus manifest(Attributor &A) override {
13576
13577 assert(isValidState() &&
13578 "Manifest should only be called if the state is valid.");
13579
13580 Instruction *I = getIRPosition().getCtxI();
13581
13582 auto FixedAllocatedSizeInBits = getAllocatedSize()->getFixedValue();
13583
13584 unsigned long NumBytesToAllocate = (FixedAllocatedSizeInBits + 7) / 8;
13585
13586 switch (I->getOpcode()) {
13587 // TODO: add case for malloc like calls
13588 case Instruction::Alloca: {
13589
13590 AllocaInst *AI = cast<AllocaInst>(I);
13591
13592 Type *CharType = Type::getInt8Ty(I->getContext());
13593
13594 auto *NumBytesToValue =
13595 ConstantInt::get(I->getContext(), APInt(32, NumBytesToAllocate));
13596
13597 BasicBlock::iterator insertPt = AI->getIterator();
13598 insertPt = std::next(insertPt);
13599 AllocaInst *NewAllocaInst =
13600 new AllocaInst(CharType, AI->getAddressSpace(), NumBytesToValue,
13601 AI->getAlign(), AI->getName(), insertPt);
13602
13603 if (A.changeAfterManifest(IRPosition::inst(*AI), *NewAllocaInst))
13604 return ChangeStatus::CHANGED;
13605
13606 break;
13607 }
13608 default:
13609 break;
13610 }
13611
13612 return ChangeStatus::UNCHANGED;
13613 }
13614
13615 /// See AbstractAttribute::getAsStr().
13616 const std::string getAsStr(Attributor *A) const override {
13617 if (!isValidState())
13618 return "allocationinfo(<invalid>)";
13619 return "allocationinfo(" +
13620 (AssumedAllocatedSize == HasNoAllocationSize
13621 ? "none"
13622 : std::to_string(AssumedAllocatedSize->getFixedValue())) +
13623 ")";
13624 }
13625
13626private:
13627 std::optional<TypeSize> AssumedAllocatedSize = HasNoAllocationSize;
13628
13629 // Maintain the computed allocation size of the object.
13630 // Returns (bool) weather the size of the allocation was modified or not.
13631 bool changeAllocationSize(std::optional<TypeSize> Size) {
13632 if (AssumedAllocatedSize == HasNoAllocationSize ||
13633 AssumedAllocatedSize != Size) {
13634 AssumedAllocatedSize = Size;
13635 return true;
13636 }
13637 return false;
13638 }
13639};
13640
13641struct AAAllocationInfoFloating : AAAllocationInfoImpl {
13642 AAAllocationInfoFloating(const IRPosition &IRP, Attributor &A)
13643 : AAAllocationInfoImpl(IRP, A) {}
13644
13645 void trackStatistics() const override {
13646 STATS_DECLTRACK_FLOATING_ATTR(allocationinfo);
13647 }
13648};
13649
13650struct AAAllocationInfoReturned : AAAllocationInfoImpl {
13651 AAAllocationInfoReturned(const IRPosition &IRP, Attributor &A)
13652 : AAAllocationInfoImpl(IRP, A) {}
13653
13654 /// See AbstractAttribute::initialize(...).
13655 void initialize(Attributor &A) override {
13656 // TODO: we don't rewrite function argument for now because it will need to
13657 // rewrite the function signature and all call sites
13658 (void)indicatePessimisticFixpoint();
13659 }
13660
13661 void trackStatistics() const override {
13662 STATS_DECLTRACK_FNRET_ATTR(allocationinfo);
13663 }
13664};
13665
13666struct AAAllocationInfoCallSiteReturned : AAAllocationInfoImpl {
13667 AAAllocationInfoCallSiteReturned(const IRPosition &IRP, Attributor &A)
13668 : AAAllocationInfoImpl(IRP, A) {}
13669
13670 void trackStatistics() const override {
13671 STATS_DECLTRACK_CSRET_ATTR(allocationinfo);
13672 }
13673};
13674
13675struct AAAllocationInfoArgument : AAAllocationInfoImpl {
13676 AAAllocationInfoArgument(const IRPosition &IRP, Attributor &A)
13677 : AAAllocationInfoImpl(IRP, A) {}
13678
13679 void trackStatistics() const override {
13680 STATS_DECLTRACK_ARG_ATTR(allocationinfo);
13681 }
13682};
13683
13684struct AAAllocationInfoCallSiteArgument : AAAllocationInfoImpl {
13685 AAAllocationInfoCallSiteArgument(const IRPosition &IRP, Attributor &A)
13686 : AAAllocationInfoImpl(IRP, A) {}
13687
13688 /// See AbstractAttribute::initialize(...).
13689 void initialize(Attributor &A) override {
13690
13691 (void)indicatePessimisticFixpoint();
13692 }
13693
13694 void trackStatistics() const override {
13695 STATS_DECLTRACK_CSARG_ATTR(allocationinfo);
13696 }
13697};
13698} // namespace
13699
13700const char AANoUnwind::ID = 0;
13701const char AANoSync::ID = 0;
13702const char AANoFree::ID = 0;
13703const char AANonNull::ID = 0;
13704const char AAMustProgress::ID = 0;
13705const char AANoRecurse::ID = 0;
13706const char AANonConvergent::ID = 0;
13707const char AAWillReturn::ID = 0;
13708const char AAUndefinedBehavior::ID = 0;
13709const char AANoAlias::ID = 0;
13710const char AAIntraFnReachability::ID = 0;
13711const char AANoReturn::ID = 0;
13712const char AAIsDead::ID = 0;
13713const char AADereferenceable::ID = 0;
13714const char AAAlign::ID = 0;
13715const char AAInstanceInfo::ID = 0;
13716const char AANoCapture::ID = 0;
13717const char AAValueSimplify::ID = 0;
13718const char AAHeapToStack::ID = 0;
13719const char AAPrivatizablePtr::ID = 0;
13720const char AAMemoryBehavior::ID = 0;
13721const char AAMemoryLocation::ID = 0;
13722const char AAValueConstantRange::ID = 0;
13723const char AAPotentialConstantValues::ID = 0;
13724const char AAPotentialValues::ID = 0;
13725const char AANoUndef::ID = 0;
13726const char AANoFPClass::ID = 0;
13727const char AACallEdges::ID = 0;
13728const char AAInterFnReachability::ID = 0;
13729const char AAPointerInfo::ID = 0;
13730const char AAAssumptionInfo::ID = 0;
13731const char AAUnderlyingObjects::ID = 0;
13732const char AAInvariantLoadPointer::ID = 0;
13733const char AAAddressSpace::ID = 0;
13734const char AANoAliasAddrSpace::ID = 0;
13735const char AAAllocationInfo::ID = 0;
13736const char AAIndirectCallInfo::ID = 0;
13737const char AAGlobalValueInfo::ID = 0;
13738const char AADenormalFPMath::ID = 0;
13739
13740// Macro magic to create the static generator function for attributes that
13741// follow the naming scheme.
13742
13743#define SWITCH_PK_INV(CLASS, PK, POS_NAME) \
13744 case IRPosition::PK: \
13745 llvm_unreachable("Cannot create " #CLASS " for a " POS_NAME " position!");
13746
13747#define SWITCH_PK_CREATE(CLASS, IRP, PK, SUFFIX) \
13748 case IRPosition::PK: \
13749 AA = new (A.Allocator) CLASS##SUFFIX(IRP, A); \
13750 ++NumAAs; \
13751 break;
13752
13753#define CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13754 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13755 CLASS *AA = nullptr; \
13756 switch (IRP.getPositionKind()) { \
13757 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13758 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
13759 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
13760 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
13761 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
13762 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
13763 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
13764 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
13765 } \
13766 return *AA; \
13767 }
13768
13769#define CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13770 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13771 CLASS *AA = nullptr; \
13772 switch (IRP.getPositionKind()) { \
13773 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13774 SWITCH_PK_INV(CLASS, IRP_FUNCTION, "function") \
13775 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
13776 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
13777 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
13778 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
13779 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
13780 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
13781 } \
13782 return *AA; \
13783 }
13784
13785#define CREATE_ABSTRACT_ATTRIBUTE_FOR_ONE_POSITION(POS, SUFFIX, CLASS) \
13786 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13787 CLASS *AA = nullptr; \
13788 switch (IRP.getPositionKind()) { \
13789 SWITCH_PK_CREATE(CLASS, IRP, POS, SUFFIX) \
13790 default: \
13791 llvm_unreachable("Cannot create " #CLASS " for position otherthan " #POS \
13792 " position!"); \
13793 } \
13794 return *AA; \
13795 }
13796
13797#define CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13798 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13799 CLASS *AA = nullptr; \
13800 switch (IRP.getPositionKind()) { \
13801 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13802 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
13803 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
13804 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
13805 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
13806 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
13807 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
13808 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
13809 } \
13810 return *AA; \
13811 }
13812
13813#define CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13814 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13815 CLASS *AA = nullptr; \
13816 switch (IRP.getPositionKind()) { \
13817 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13818 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
13819 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
13820 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
13821 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
13822 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
13823 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
13824 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
13825 } \
13826 return *AA; \
13827 }
13828
13829#define CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13830 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13831 CLASS *AA = nullptr; \
13832 switch (IRP.getPositionKind()) { \
13833 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13834 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
13835 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
13836 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
13837 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
13838 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
13839 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
13840 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
13841 } \
13842 return *AA; \
13843 }
13844
13854
13872
13877
13882
13889
13891
13892#undef CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION
13893#undef CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION
13894#undef CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION
13895#undef CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION
13896#undef CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION
13897#undef CREATE_ABSTRACT_ATTRIBUTE_FOR_ONE_POSITION
13898#undef SWITCH_PK_CREATE
13899#undef SWITCH_PK_INV
#define Success
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
aarch64 promote const
unsigned 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:270
LLVM_ABI bool onlyReadsMemory() const
Return true if this argument has the readonly or readnone attribute.
Definition Function.cpp:306
LLVM_ABI bool hasPointeeInMemoryValueAttr() const
Return true if this argument has the byval, sret, inalloca, preallocated, or byref attribute.
Definition Function.cpp:173
LLVM_ABI bool hasReturnedAttr() const
Return true if this argument has the returned attribute.
Definition Function.cpp:294
LLVM_ABI bool hasByValAttr() const
Return true if this argument has the byval attribute.
Definition Function.cpp:130
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:266
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:758
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:763
iterator find(const_arg_type_t< KeyT > Val)
Definition DenseMap.h:767
iterator end()
Definition DenseMap.h:687
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition DenseMap.h:828
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
Definition DenseMap.h:857
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:734
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:2101
ConstantInt * getInt64(uint64_t C)
Get a constant 64-bit value.
Definition IRBuilder.h:479
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2918
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:71
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:553
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:319
std::pair< iterator, bool > insert(const ValueT &V)
Definition DenseSet.h:209
constexpr ScalarTy getFixedValue() const
Definition TypeSize.h:200
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
Definition TypeSize.h:168
const ParentTy * getParent() const
Definition ilist_node.h:34
self_iterator getIterator()
Definition ilist_node.h:123
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
Definition ilist_node.h:348
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
A raw_ostream that writes to an std::string.
Changed
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Abstract Attribute helper functions.
Definition Attributor.h:165
LLVM_ABI bool isAssumedReadNone(Attributor &A, const IRPosition &IRP, const AbstractAttribute &QueryingAA, bool &IsKnown)
Return true if IRP is readnone.
LLVM_ABI bool isAssumedReadOnly(Attributor &A, const IRPosition &IRP, const AbstractAttribute &QueryingAA, bool &IsKnown)
Return true if IRP is readonly.
raw_ostream & operator<<(raw_ostream &OS, const RangeTy &R)
Definition Attributor.h: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:58
@ 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.