LLVM 23.0.0git
AttributorAttributes.cpp
Go to the documentation of this file.
1//===- AttributorAttributes.cpp - Attributes for Attributor deduction -----===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// See the Attributor.h file comment and the class descriptions in that file for
10// more information.
11//
12//===----------------------------------------------------------------------===//
13
15
16#include "llvm/ADT/APInt.h"
17#include "llvm/ADT/ArrayRef.h"
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, Cycle **CPtr = nullptr) {
218 if (!CI)
219 return true;
220 auto *BB = I->getParent();
221 auto *C = CI->getCycle(BB);
222 if (!C)
223 return false;
224 if (CPtr)
225 *CPtr = C;
226 return !HeaderOnly || BB == C->getHeader();
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 return true;
266}
267
268/// Get pointer operand of memory accessing instruction. If \p I is
269/// not a memory accessing instruction, return nullptr. If \p AllowVolatile,
270/// is set to false and the instruction is volatile, return nullptr.
272 bool AllowVolatile) {
273 if (!AllowVolatile && I->isVolatile())
274 return nullptr;
275
276 if (auto *LI = dyn_cast<LoadInst>(I)) {
277 return LI->getPointerOperand();
278 }
279
280 if (auto *SI = dyn_cast<StoreInst>(I)) {
281 return SI->getPointerOperand();
282 }
283
284 if (auto *CXI = dyn_cast<AtomicCmpXchgInst>(I)) {
285 return CXI->getPointerOperand();
286 }
287
288 if (auto *RMWI = dyn_cast<AtomicRMWInst>(I)) {
289 return RMWI->getPointerOperand();
290 }
291
292 return nullptr;
293}
294
295/// Helper function to create a pointer based on \p Ptr, and advanced by \p
296/// Offset bytes.
297static Value *constructPointer(Value *Ptr, int64_t Offset,
298 IRBuilder<NoFolder> &IRB) {
299 LLVM_DEBUG(dbgs() << "Construct pointer: " << *Ptr << " + " << Offset
300 << "-bytes\n");
301
302 if (Offset)
303 Ptr = IRB.CreatePtrAdd(Ptr, IRB.getInt64(Offset),
304 Ptr->getName() + ".b" + Twine(Offset));
305 return Ptr;
306}
307
308static const Value *
310 const Value *Val, const DataLayout &DL, APInt &Offset,
311 bool GetMinOffset, bool AllowNonInbounds,
312 bool UseAssumed = false) {
313
314 auto AttributorAnalysis = [&](Value &V, APInt &ROffset) -> bool {
315 const IRPosition &Pos = IRPosition::value(V);
316 // Only track dependence if we are going to use the assumed info.
317 const AAValueConstantRange *ValueConstantRangeAA =
318 A.getAAFor<AAValueConstantRange>(QueryingAA, Pos,
319 UseAssumed ? DepClassTy::OPTIONAL
321 if (!ValueConstantRangeAA)
322 return false;
323 ConstantRange Range = UseAssumed ? ValueConstantRangeAA->getAssumed()
324 : ValueConstantRangeAA->getKnown();
325 if (Range.isFullSet())
326 return false;
327
328 // We can only use the lower part of the range because the upper part can
329 // be higher than what the value can really be.
330 if (GetMinOffset)
331 ROffset = Range.getSignedMin();
332 else
333 ROffset = Range.getSignedMax();
334 return true;
335 };
336
337 return Val->stripAndAccumulateConstantOffsets(DL, Offset, AllowNonInbounds,
338 /* AllowInvariant */ true,
339 AttributorAnalysis);
340}
341
342static const Value *
344 const Value *Ptr, int64_t &BytesOffset,
345 const DataLayout &DL, bool AllowNonInbounds = false) {
346 APInt OffsetAPInt(DL.getIndexTypeSizeInBits(Ptr->getType()), 0);
347 const Value *Base =
348 stripAndAccumulateOffsets(A, QueryingAA, Ptr, DL, OffsetAPInt,
349 /* GetMinOffset */ true, AllowNonInbounds);
350
351 BytesOffset = OffsetAPInt.getSExtValue();
352 return Base;
353}
354
355/// Clamp the information known for all returned values of a function
356/// (identified by \p QueryingAA) into \p S.
357template <typename AAType, typename StateType = typename AAType::StateType,
358 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind,
359 bool RecurseForSelectAndPHI = true>
361 Attributor &A, const AAType &QueryingAA, StateType &S,
362 const IRPosition::CallBaseContext *CBContext = nullptr) {
363 LLVM_DEBUG(dbgs() << "[Attributor] Clamp return value states for "
364 << QueryingAA << " into " << S << "\n");
365
366 assert((QueryingAA.getIRPosition().getPositionKind() ==
368 QueryingAA.getIRPosition().getPositionKind() ==
370 "Can only clamp returned value states for a function returned or call "
371 "site returned position!");
372
373 // Use an optional state as there might not be any return values and we want
374 // to join (IntegerState::operator&) the state of all there are.
375 std::optional<StateType> T;
376
377 // Callback for each possibly returned value.
378 auto CheckReturnValue = [&](Value &RV) -> bool {
379 const IRPosition &RVPos = IRPosition::value(RV, CBContext);
380 // If possible, use the hasAssumedIRAttr interface.
381 if (Attribute::isEnumAttrKind(IRAttributeKind)) {
382 bool IsKnown;
384 A, &QueryingAA, RVPos, DepClassTy::REQUIRED, IsKnown);
385 }
386
387 const AAType *AA =
388 A.getAAFor<AAType>(QueryingAA, RVPos, DepClassTy::REQUIRED);
389 if (!AA)
390 return false;
391 LLVM_DEBUG(dbgs() << "[Attributor] RV: " << RV
392 << " AA: " << AA->getAsStr(&A) << " @ " << RVPos << "\n");
393 const StateType &AAS = AA->getState();
394 if (!T)
395 T = StateType::getBestState(AAS);
396 *T &= AAS;
397 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS << " RV State: " << T
398 << "\n");
399 return T->isValidState();
400 };
401
402 if (!A.checkForAllReturnedValues(CheckReturnValue, QueryingAA,
404 RecurseForSelectAndPHI))
405 S.indicatePessimisticFixpoint();
406 else if (T)
407 S ^= *T;
408}
409
410namespace {
411/// Helper class for generic deduction: return value -> returned position.
412template <typename AAType, typename BaseType,
413 typename StateType = typename BaseType::StateType,
414 bool PropagateCallBaseContext = false,
415 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind,
416 bool RecurseForSelectAndPHI = true>
417struct AAReturnedFromReturnedValues : public BaseType {
418 AAReturnedFromReturnedValues(const IRPosition &IRP, Attributor &A)
419 : BaseType(IRP, A) {}
420
421 /// See AbstractAttribute::updateImpl(...).
422 ChangeStatus updateImpl(Attributor &A) override {
423 StateType S(StateType::getBestState(this->getState()));
424 clampReturnedValueStates<AAType, StateType, IRAttributeKind,
425 RecurseForSelectAndPHI>(
426 A, *this, S,
427 PropagateCallBaseContext ? this->getCallBaseContext() : nullptr);
428 // TODO: If we know we visited all returned values, thus no are assumed
429 // dead, we can take the known information from the state T.
430 return clampStateAndIndicateChange<StateType>(this->getState(), S);
431 }
432};
433
434/// Clamp the information known at all call sites for a given argument
435/// (identified by \p QueryingAA) into \p S.
436template <typename AAType, typename StateType = typename AAType::StateType,
437 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind>
438static void clampCallSiteArgumentStates(Attributor &A, const AAType &QueryingAA,
439 StateType &S) {
440 LLVM_DEBUG(dbgs() << "[Attributor] Clamp call site argument states for "
441 << QueryingAA << " into " << S << "\n");
442
443 assert(QueryingAA.getIRPosition().getPositionKind() ==
445 "Can only clamp call site argument states for an argument position!");
446
447 // Use an optional state as there might not be any return values and we want
448 // to join (IntegerState::operator&) the state of all there are.
449 std::optional<StateType> T;
450
451 // The argument number which is also the call site argument number.
452 unsigned ArgNo = QueryingAA.getIRPosition().getCallSiteArgNo();
453
454 auto CallSiteCheck = [&](AbstractCallSite ACS) {
455 const IRPosition &ACSArgPos = IRPosition::callsite_argument(ACS, ArgNo);
456 // Check if a coresponding argument was found or if it is on not associated
457 // (which can happen for callback calls).
458 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
459 return false;
460
461 // If possible, use the hasAssumedIRAttr interface.
462 if (Attribute::isEnumAttrKind(IRAttributeKind)) {
463 bool IsKnown;
465 A, &QueryingAA, ACSArgPos, DepClassTy::REQUIRED, IsKnown);
466 }
467
468 const AAType *AA =
469 A.getAAFor<AAType>(QueryingAA, ACSArgPos, DepClassTy::REQUIRED);
470 if (!AA)
471 return false;
472 LLVM_DEBUG(dbgs() << "[Attributor] ACS: " << *ACS.getInstruction()
473 << " AA: " << AA->getAsStr(&A) << " @" << ACSArgPos
474 << "\n");
475 const StateType &AAS = AA->getState();
476 if (!T)
477 T = StateType::getBestState(AAS);
478 *T &= AAS;
479 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS << " CSA State: " << T
480 << "\n");
481 return T->isValidState();
482 };
483
484 bool UsedAssumedInformation = false;
485 if (!A.checkForAllCallSites(CallSiteCheck, QueryingAA, true,
486 UsedAssumedInformation))
487 S.indicatePessimisticFixpoint();
488 else if (T)
489 S ^= *T;
490}
491
492/// This function is the bridge between argument position and the call base
493/// context.
494template <typename AAType, typename BaseType,
495 typename StateType = typename AAType::StateType,
496 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind>
497bool getArgumentStateFromCallBaseContext(Attributor &A,
498 BaseType &QueryingAttribute,
499 IRPosition &Pos, StateType &State) {
501 "Expected an 'argument' position !");
502 const CallBase *CBContext = Pos.getCallBaseContext();
503 if (!CBContext)
504 return false;
505
506 int ArgNo = Pos.getCallSiteArgNo();
507 assert(ArgNo >= 0 && "Invalid Arg No!");
508 const IRPosition CBArgPos = IRPosition::callsite_argument(*CBContext, ArgNo);
509
510 // If possible, use the hasAssumedIRAttr interface.
511 if (Attribute::isEnumAttrKind(IRAttributeKind)) {
512 bool IsKnown;
514 A, &QueryingAttribute, CBArgPos, DepClassTy::REQUIRED, IsKnown);
515 }
516
517 const auto *AA =
518 A.getAAFor<AAType>(QueryingAttribute, CBArgPos, DepClassTy::REQUIRED);
519 if (!AA)
520 return false;
521 const StateType &CBArgumentState =
522 static_cast<const StateType &>(AA->getState());
523
524 LLVM_DEBUG(dbgs() << "[Attributor] Briding Call site context to argument"
525 << "Position:" << Pos << "CB Arg state:" << CBArgumentState
526 << "\n");
527
528 // NOTE: If we want to do call site grouping it should happen here.
529 State ^= CBArgumentState;
530 return true;
531}
532
533/// Helper class for generic deduction: call site argument -> argument position.
534template <typename AAType, typename BaseType,
535 typename StateType = typename AAType::StateType,
536 bool BridgeCallBaseContext = false,
537 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind>
538struct AAArgumentFromCallSiteArguments : public BaseType {
539 AAArgumentFromCallSiteArguments(const IRPosition &IRP, Attributor &A)
540 : BaseType(IRP, A) {}
541
542 /// See AbstractAttribute::updateImpl(...).
543 ChangeStatus updateImpl(Attributor &A) override {
544 StateType S = StateType::getBestState(this->getState());
545
546 if (BridgeCallBaseContext) {
547 bool Success =
548 getArgumentStateFromCallBaseContext<AAType, BaseType, StateType,
549 IRAttributeKind>(
550 A, *this, this->getIRPosition(), S);
551 if (Success)
552 return clampStateAndIndicateChange<StateType>(this->getState(), S);
553 }
554 clampCallSiteArgumentStates<AAType, StateType, IRAttributeKind>(A, *this,
555 S);
556
557 // TODO: If we know we visited all incoming values, thus no are assumed
558 // dead, we can take the known information from the state T.
559 return clampStateAndIndicateChange<StateType>(this->getState(), S);
560 }
561};
562
563/// Helper class for generic replication: function returned -> cs returned.
564template <typename AAType, typename BaseType,
565 typename StateType = typename BaseType::StateType,
566 bool IntroduceCallBaseContext = false,
567 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind>
568struct AACalleeToCallSite : public BaseType {
569 AACalleeToCallSite(const IRPosition &IRP, Attributor &A) : BaseType(IRP, A) {}
570
571 /// See AbstractAttribute::updateImpl(...).
572 ChangeStatus updateImpl(Attributor &A) override {
573 auto IRPKind = this->getIRPosition().getPositionKind();
575 IRPKind == IRPosition::IRP_CALL_SITE) &&
576 "Can only wrap function returned positions for call site "
577 "returned positions!");
578 auto &S = this->getState();
579
580 CallBase &CB = cast<CallBase>(this->getAnchorValue());
581 if (IntroduceCallBaseContext)
582 LLVM_DEBUG(dbgs() << "[Attributor] Introducing call base context:" << CB
583 << "\n");
584
585 ChangeStatus Changed = ChangeStatus::UNCHANGED;
586 auto CalleePred = [&](ArrayRef<const Function *> Callees) {
587 for (const Function *Callee : Callees) {
588 IRPosition FnPos =
590 ? IRPosition::returned(*Callee,
591 IntroduceCallBaseContext ? &CB : nullptr)
592 : IRPosition::function(
593 *Callee, IntroduceCallBaseContext ? &CB : nullptr);
594 // If possible, use the hasAssumedIRAttr interface.
595 if (Attribute::isEnumAttrKind(IRAttributeKind)) {
596 bool IsKnown;
598 A, this, FnPos, DepClassTy::REQUIRED, IsKnown))
599 return false;
600 continue;
601 }
602
603 const AAType *AA =
604 A.getAAFor<AAType>(*this, FnPos, DepClassTy::REQUIRED);
605 if (!AA)
606 return false;
607 Changed |= clampStateAndIndicateChange(S, AA->getState());
608 if (S.isAtFixpoint())
609 return S.isValidState();
610 }
611 return true;
612 };
613 if (!A.checkForAllCallees(CalleePred, *this, CB))
614 return S.indicatePessimisticFixpoint();
615 return Changed;
616 }
617};
618
619/// Helper function to accumulate uses.
620template <class AAType, typename StateType = typename AAType::StateType>
621static void followUsesInContext(AAType &AA, Attributor &A,
623 const Instruction *CtxI,
625 StateType &State) {
626 auto EIt = Explorer.begin(CtxI), EEnd = Explorer.end(CtxI);
627 for (unsigned u = 0; u < Uses.size(); ++u) {
628 const Use *U = Uses[u];
629 if (const Instruction *UserI = dyn_cast<Instruction>(U->getUser())) {
630 bool Found = Explorer.findInContextOf(UserI, EIt, EEnd);
631 if (Found && AA.followUseInMBEC(A, U, UserI, State))
632 Uses.insert_range(llvm::make_pointer_range(UserI->uses()));
633 }
634 }
635}
636
637/// Use the must-be-executed-context around \p I to add information into \p S.
638/// The AAType class is required to have `followUseInMBEC` method with the
639/// following signature and behaviour:
640///
641/// bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I)
642/// U - Underlying use.
643/// I - The user of the \p U.
644/// Returns true if the value should be tracked transitively.
645///
646template <class AAType, typename StateType = typename AAType::StateType>
647static void followUsesInMBEC(AAType &AA, Attributor &A, StateType &S,
648 Instruction &CtxI) {
649 const Value &Val = AA.getIRPosition().getAssociatedValue();
650 if (isa<ConstantData>(Val))
651 return;
652
654 A.getInfoCache().getMustBeExecutedContextExplorer();
655 if (!Explorer)
656 return;
657
658 // Container for (transitive) uses of the associated value.
660 for (const Use &U : Val.uses())
661 Uses.insert(&U);
662
663 followUsesInContext<AAType>(AA, A, *Explorer, &CtxI, Uses, S);
664
665 if (S.isAtFixpoint())
666 return;
667
669 auto Pred = [&](const Instruction *I) {
670 if (const CondBrInst *Br = dyn_cast<CondBrInst>(I))
671 BrInsts.push_back(Br);
672 return true;
673 };
674
675 // Here, accumulate conditional branch instructions in the context. We
676 // explore the child paths and collect the known states. The disjunction of
677 // those states can be merged to its own state. Let ParentState_i be a state
678 // to indicate the known information for an i-th branch instruction in the
679 // context. ChildStates are created for its successors respectively.
680 //
681 // ParentS_1 = ChildS_{1, 1} /\ ChildS_{1, 2} /\ ... /\ ChildS_{1, n_1}
682 // ParentS_2 = ChildS_{2, 1} /\ ChildS_{2, 2} /\ ... /\ ChildS_{2, n_2}
683 // ...
684 // ParentS_m = ChildS_{m, 1} /\ ChildS_{m, 2} /\ ... /\ ChildS_{m, n_m}
685 //
686 // Known State |= ParentS_1 \/ ParentS_2 \/... \/ ParentS_m
687 //
688 // FIXME: Currently, recursive branches are not handled. For example, we
689 // can't deduce that ptr must be dereferenced in below function.
690 //
691 // void f(int a, int c, int *ptr) {
692 // if(a)
693 // if (b) {
694 // *ptr = 0;
695 // } else {
696 // *ptr = 1;
697 // }
698 // else {
699 // if (b) {
700 // *ptr = 0;
701 // } else {
702 // *ptr = 1;
703 // }
704 // }
705 // }
706
707 Explorer->checkForAllContext(&CtxI, Pred);
708 for (const CondBrInst *Br : BrInsts) {
709 StateType ParentState;
710
711 // The known state of the parent state is a conjunction of children's
712 // known states so it is initialized with a best state.
713 ParentState.indicateOptimisticFixpoint();
714
715 for (const BasicBlock *BB : Br->successors()) {
716 StateType ChildState;
717
718 size_t BeforeSize = Uses.size();
719 followUsesInContext(AA, A, *Explorer, &BB->front(), Uses, ChildState);
720
721 // Erase uses which only appear in the child.
722 for (auto It = Uses.begin() + BeforeSize; It != Uses.end();)
723 It = Uses.erase(It);
724
725 ParentState &= ChildState;
726 }
727
728 // Use only known state.
729 S += ParentState;
730 }
731}
732} // namespace
733
734/// ------------------------ PointerInfo ---------------------------------------
735
736namespace llvm {
737namespace AA {
738namespace PointerInfo {
739
740struct State;
741
742} // namespace PointerInfo
743} // namespace AA
744
745/// Helper for AA::PointerInfo::Access DenseMap/Set usage.
746template <>
749 static unsigned getHashValue(const Access &A);
750 static bool isEqual(const Access &LHS, const Access &RHS);
751};
752
753/// Helper that allows RangeTy as a key in a DenseMap.
754template <> struct DenseMapInfo<AA::RangeTy> {
760
761 static bool isEqual(const AA::RangeTy &A, const AA::RangeTy B) {
762 return A == B;
763 }
764};
765
766/// Helper for AA::PointerInfo::Access DenseMap/Set usage ignoring everythign
767/// but the instruction
768struct AccessAsInstructionInfo : DenseMapInfo<Instruction *> {
771 static unsigned getHashValue(const Access &A);
772 static bool isEqual(const Access &LHS, const Access &RHS);
773};
774
775} // namespace llvm
776
777/// A type to track pointer/struct usage and accesses for AAPointerInfo.
779 /// Return the best possible representable state.
780 static State getBestState(const State &SIS) { return State(); }
781
782 /// Return the worst possible representable state.
783 static State getWorstState(const State &SIS) {
784 State R;
785 R.indicatePessimisticFixpoint();
786 return R;
787 }
788
789 State() = default;
790 State(State &&SIS) = default;
791
792 const State &getAssumed() const { return *this; }
793
794 /// See AbstractState::isValidState().
795 bool isValidState() const override { return BS.isValidState(); }
796
797 /// See AbstractState::isAtFixpoint().
798 bool isAtFixpoint() const override { return BS.isAtFixpoint(); }
799
800 /// See AbstractState::indicateOptimisticFixpoint().
802 BS.indicateOptimisticFixpoint();
804 }
805
806 /// See AbstractState::indicatePessimisticFixpoint().
808 BS.indicatePessimisticFixpoint();
810 }
811
812 State &operator=(const State &R) {
813 if (this == &R)
814 return *this;
815 BS = R.BS;
816 AccessList = R.AccessList;
817 OffsetBins = R.OffsetBins;
818 RemoteIMap = R.RemoteIMap;
819 ReturnedOffsets = R.ReturnedOffsets;
820 return *this;
821 }
822
824 if (this == &R)
825 return *this;
826 std::swap(BS, R.BS);
827 std::swap(AccessList, R.AccessList);
828 std::swap(OffsetBins, R.OffsetBins);
829 std::swap(RemoteIMap, R.RemoteIMap);
830 std::swap(ReturnedOffsets, R.ReturnedOffsets);
831 return *this;
832 }
833
834 /// Add a new Access to the state at offset \p Offset and with size \p Size.
835 /// The access is associated with \p I, writes \p Content (if anything), and
836 /// is of kind \p Kind. If an Access already exists for the same \p I and same
837 /// \p RemoteI, the two are combined, potentially losing information about
838 /// offset and size. The resulting access must now be moved from its original
839 /// OffsetBin to the bin for its new offset.
840 ///
841 /// \Returns CHANGED, if the state changed, UNCHANGED otherwise.
843 Instruction &I, std::optional<Value *> Content,
845 Instruction *RemoteI = nullptr);
846
849 int64_t numOffsetBins() const { return OffsetBins.size(); }
850
851 const AAPointerInfo::Access &getAccess(unsigned Index) const {
852 return AccessList[Index];
853 }
854
855protected:
856 // Every memory instruction results in an Access object. We maintain a list of
857 // all Access objects that we own, along with the following maps:
858 //
859 // - OffsetBins: RangeTy -> { Access }
860 // - RemoteIMap: RemoteI x LocalI -> Access
861 //
862 // A RemoteI is any instruction that accesses memory. RemoteI is different
863 // from LocalI if and only if LocalI is a call; then RemoteI is some
864 // instruction in the callgraph starting from LocalI. Multiple paths in the
865 // callgraph from LocalI to RemoteI may produce multiple accesses, but these
866 // are all combined into a single Access object. This may result in loss of
867 // information in RangeTy in the Access object.
871
872 /// Flag to determine if the underlying pointer is reaching a return statement
873 /// in the associated function or not. Returns in other functions cause
874 /// invalidation.
876
877 /// See AAPointerInfo::forallInterferingAccesses.
878 template <typename F>
880 if (!isValidState() || !ReturnedOffsets.isUnassigned())
881 return false;
882
883 for (const auto &It : OffsetBins) {
884 AA::RangeTy ItRange = It.getFirst();
885 if (!Range.mayOverlap(ItRange))
886 continue;
887 bool IsExact = Range == ItRange && !Range.offsetOrSizeAreUnknown();
888 for (auto Index : It.getSecond()) {
889 auto &Access = AccessList[Index];
890 if (!CB(Access, IsExact))
891 return false;
892 }
893 }
894 return true;
895 }
896
897 /// See AAPointerInfo::forallInterferingAccesses.
898 template <typename F>
900 AA::RangeTy &Range) const {
901 if (!isValidState() || !ReturnedOffsets.isUnassigned())
902 return false;
903
904 auto LocalList = RemoteIMap.find(&I);
905 if (LocalList == RemoteIMap.end()) {
906 return true;
907 }
908
909 for (unsigned Index : LocalList->getSecond()) {
910 for (auto &R : AccessList[Index]) {
911 Range &= R;
912 if (Range.offsetAndSizeAreUnknown())
913 break;
914 }
915 }
917 }
918
919private:
920 /// State to track fixpoint and validity.
921 BooleanState BS;
922};
923
926 std::optional<Value *> Content, AAPointerInfo::AccessKind Kind, Type *Ty,
927 Instruction *RemoteI) {
928 RemoteI = RemoteI ? RemoteI : &I;
929
930 // Check if we have an access for this instruction, if not, simply add it.
931 auto &LocalList = RemoteIMap[RemoteI];
932 bool AccExists = false;
933 unsigned AccIndex = AccessList.size();
934 for (auto Index : LocalList) {
935 auto &A = AccessList[Index];
936 if (A.getLocalInst() == &I) {
937 AccExists = true;
938 AccIndex = Index;
939 break;
940 }
941 }
942
943 auto AddToBins = [&](const AAPointerInfo::RangeList &ToAdd) {
944 LLVM_DEBUG(if (ToAdd.size()) dbgs()
945 << "[AAPointerInfo] Inserting access in new offset bins\n";);
946
947 for (auto Key : ToAdd) {
948 LLVM_DEBUG(dbgs() << " key " << Key << "\n");
949 OffsetBins[Key].insert(AccIndex);
950 }
951 };
952
953 if (!AccExists) {
954 AccessList.emplace_back(&I, RemoteI, Ranges, Content, Kind, Ty);
955 assert((AccessList.size() == AccIndex + 1) &&
956 "New Access should have been at AccIndex");
957 LocalList.push_back(AccIndex);
958 AddToBins(AccessList[AccIndex].getRanges());
960 }
961
962 // Combine the new Access with the existing Access, and then update the
963 // mapping in the offset bins.
964 AAPointerInfo::Access Acc(&I, RemoteI, Ranges, Content, Kind, Ty);
965 auto &Current = AccessList[AccIndex];
966 auto Before = Current;
967 Current &= Acc;
968 if (Current == Before)
970
971 auto &ExistingRanges = Before.getRanges();
972 auto &NewRanges = Current.getRanges();
973
974 // Ranges that are in the old access but not the new access need to be removed
975 // from the offset bins.
977 AAPointerInfo::RangeList::set_difference(ExistingRanges, NewRanges, ToRemove);
978 LLVM_DEBUG(if (ToRemove.size()) dbgs()
979 << "[AAPointerInfo] Removing access from old offset bins\n";);
980
981 for (auto Key : ToRemove) {
982 LLVM_DEBUG(dbgs() << " key " << Key << "\n");
983 assert(OffsetBins.count(Key) && "Existing Access must be in some bin.");
984 auto &Bin = OffsetBins[Key];
985 assert(Bin.count(AccIndex) &&
986 "Expected bin to actually contain the Access.");
987 Bin.erase(AccIndex);
988 }
989
990 // Ranges that are in the new access but not the old access need to be added
991 // to the offset bins.
993 AAPointerInfo::RangeList::set_difference(NewRanges, ExistingRanges, ToAdd);
994 AddToBins(ToAdd);
996}
997
998namespace {
999
1000#ifndef NDEBUG
1002 const AAPointerInfo::OffsetInfo &OI) {
1003 OS << llvm::interleaved_array(OI);
1004 return OS;
1005}
1006#endif // NDEBUG
1007
1008struct AAPointerInfoImpl
1009 : public StateWrapper<AA::PointerInfo::State, AAPointerInfo> {
1011 AAPointerInfoImpl(const IRPosition &IRP, Attributor &A) : BaseTy(IRP) {}
1012
1013 /// See AbstractAttribute::getAsStr().
1014 const std::string getAsStr(Attributor *A) const override {
1015 return std::string("PointerInfo ") +
1016 (isValidState() ? (std::string("#") +
1017 std::to_string(OffsetBins.size()) + " bins")
1018 : "<invalid>") +
1019 (reachesReturn()
1020 ? (" (returned:" +
1021 join(map_range(ReturnedOffsets,
1022 [](int64_t O) { return std::to_string(O); }),
1023 ", ") +
1024 ")")
1025 : "");
1026 }
1027
1028 /// See AbstractAttribute::manifest(...).
1029 ChangeStatus manifest(Attributor &A) override {
1030 return AAPointerInfo::manifest(A);
1031 }
1032
1033 const_bin_iterator begin() const override { return State::begin(); }
1034 const_bin_iterator end() const override { return State::end(); }
1035 int64_t numOffsetBins() const override { return State::numOffsetBins(); }
1036 bool reachesReturn() const override {
1037 return !ReturnedOffsets.isUnassigned();
1038 }
1039 void addReturnedOffsetsTo(OffsetInfo &OI) const override {
1040 if (ReturnedOffsets.isUnknown()) {
1041 OI.setUnknown();
1042 return;
1043 }
1044
1045 OffsetInfo MergedOI;
1046 for (auto Offset : ReturnedOffsets) {
1047 OffsetInfo TmpOI = OI;
1048 TmpOI.addToAll(Offset);
1049 MergedOI.merge(TmpOI);
1050 }
1051 OI = std::move(MergedOI);
1052 }
1053
1054 ChangeStatus setReachesReturn(const OffsetInfo &ReachedReturnedOffsets) {
1055 if (ReturnedOffsets.isUnknown())
1056 return ChangeStatus::UNCHANGED;
1057 if (ReachedReturnedOffsets.isUnknown()) {
1058 ReturnedOffsets.setUnknown();
1059 return ChangeStatus::CHANGED;
1060 }
1061 if (ReturnedOffsets.merge(ReachedReturnedOffsets))
1062 return ChangeStatus::CHANGED;
1063 return ChangeStatus::UNCHANGED;
1064 }
1065
1066 bool forallInterferingAccesses(
1067 AA::RangeTy Range,
1068 function_ref<bool(const AAPointerInfo::Access &, bool)> CB)
1069 const override {
1070 return State::forallInterferingAccesses(Range, CB);
1071 }
1072
1073 bool forallInterferingAccesses(
1074 Attributor &A, const AbstractAttribute &QueryingAA, Instruction &I,
1075 bool FindInterferingWrites, bool FindInterferingReads,
1076 function_ref<bool(const Access &, bool)> UserCB, bool &HasBeenWrittenTo,
1077 AA::RangeTy &Range,
1078 function_ref<bool(const Access &)> SkipCB) const override {
1079 HasBeenWrittenTo = false;
1080
1081 SmallPtrSet<const Access *, 8> DominatingWrites;
1082 SmallVector<std::pair<const Access *, bool>, 8> InterferingAccesses;
1083
1084 Function &Scope = *I.getFunction();
1085 bool IsKnownNoSync;
1086 bool IsAssumedNoSync = AA::hasAssumedIRAttr<Attribute::NoSync>(
1087 A, &QueryingAA, IRPosition::function(Scope), DepClassTy::OPTIONAL,
1088 IsKnownNoSync);
1089 const auto *ExecDomainAA = A.lookupAAFor<AAExecutionDomain>(
1090 IRPosition::function(Scope), &QueryingAA, DepClassTy::NONE);
1091 bool AllInSameNoSyncFn = IsAssumedNoSync;
1092 bool InstIsExecutedByInitialThreadOnly =
1093 ExecDomainAA && ExecDomainAA->isExecutedByInitialThreadOnly(I);
1094
1095 // If the function is not ending in aligned barriers, we need the stores to
1096 // be in aligned barriers. The load being in one is not sufficient since the
1097 // store might be executed by a thread that disappears after, causing the
1098 // aligned barrier guarding the load to unblock and the load to read a value
1099 // that has no CFG path to the load.
1100 bool InstIsExecutedInAlignedRegion =
1101 FindInterferingReads && ExecDomainAA &&
1102 ExecDomainAA->isExecutedInAlignedRegion(A, I);
1103
1104 if (InstIsExecutedInAlignedRegion || InstIsExecutedByInitialThreadOnly)
1105 A.recordDependence(*ExecDomainAA, QueryingAA, DepClassTy::OPTIONAL);
1106
1107 InformationCache &InfoCache = A.getInfoCache();
1108 bool IsThreadLocalObj =
1109 AA::isAssumedThreadLocalObject(A, getAssociatedValue(), *this);
1110
1111 // Helper to determine if we need to consider threading, which we cannot
1112 // right now. However, if the function is (assumed) nosync or the thread
1113 // executing all instructions is the main thread only we can ignore
1114 // threading. Also, thread-local objects do not require threading reasoning.
1115 // Finally, we can ignore threading if either access is executed in an
1116 // aligned region.
1117 auto CanIgnoreThreadingForInst = [&](const Instruction &I) -> bool {
1118 if (IsThreadLocalObj || AllInSameNoSyncFn)
1119 return true;
1120 const auto *FnExecDomainAA =
1121 I.getFunction() == &Scope
1122 ? ExecDomainAA
1123 : A.lookupAAFor<AAExecutionDomain>(
1124 IRPosition::function(*I.getFunction()), &QueryingAA,
1125 DepClassTy::NONE);
1126 if (!FnExecDomainAA)
1127 return false;
1128 if (InstIsExecutedInAlignedRegion ||
1129 (FindInterferingWrites &&
1130 FnExecDomainAA->isExecutedInAlignedRegion(A, I))) {
1131 A.recordDependence(*FnExecDomainAA, QueryingAA, DepClassTy::OPTIONAL);
1132 return true;
1133 }
1134 if (InstIsExecutedByInitialThreadOnly &&
1135 FnExecDomainAA->isExecutedByInitialThreadOnly(I)) {
1136 A.recordDependence(*FnExecDomainAA, QueryingAA, DepClassTy::OPTIONAL);
1137 return true;
1138 }
1139 return false;
1140 };
1141
1142 // Helper to determine if the access is executed by the same thread as the
1143 // given instruction, for now it is sufficient to avoid any potential
1144 // threading effects as we cannot deal with them anyway.
1145 auto CanIgnoreThreading = [&](const Access &Acc) -> bool {
1146 return CanIgnoreThreadingForInst(*Acc.getRemoteInst()) ||
1147 (Acc.getRemoteInst() != Acc.getLocalInst() &&
1148 CanIgnoreThreadingForInst(*Acc.getLocalInst()));
1149 };
1150
1151 // TODO: Use inter-procedural reachability and dominance.
1152 bool IsKnownNoRecurse;
1154 A, this, IRPosition::function(Scope), DepClassTy::OPTIONAL,
1155 IsKnownNoRecurse);
1156
1157 // TODO: Use reaching kernels from AAKernelInfo (or move it to
1158 // AAExecutionDomain) such that we allow scopes other than kernels as long
1159 // as the reaching kernels are disjoint.
1160 bool InstInKernel = A.getInfoCache().isKernel(Scope);
1161 bool ObjHasKernelLifetime = false;
1162 const bool UseDominanceReasoning =
1163 FindInterferingWrites && IsKnownNoRecurse;
1164 const DominatorTree *DT =
1165 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(Scope);
1166
1167 // Helper to check if a value has "kernel lifetime", that is it will not
1168 // outlive a GPU kernel. This is true for shared, constant, and local
1169 // globals on AMD and NVIDIA GPUs.
1170 auto HasKernelLifetime = [&](Value *V, Module &M) {
1171 if (!AA::isGPU(M))
1172 return false;
1173 unsigned VAS = V->getType()->getPointerAddressSpace();
1174 return AA::isGPUSharedAddressSpace(M, VAS) ||
1177 };
1178
1179 // The IsLiveInCalleeCB will be used by the AA::isPotentiallyReachable query
1180 // to determine if we should look at reachability from the callee. For
1181 // certain pointers we know the lifetime and we do not have to step into the
1182 // callee to determine reachability as the pointer would be dead in the
1183 // callee. See the conditional initialization below.
1184 std::function<bool(const Function &)> IsLiveInCalleeCB;
1185
1186 if (auto *AI = dyn_cast<AllocaInst>(&getAssociatedValue())) {
1187 // If the alloca containing function is not recursive the alloca
1188 // must be dead in the callee.
1189 const Function *AIFn = AI->getFunction();
1190 ObjHasKernelLifetime = A.getInfoCache().isKernel(*AIFn);
1191 bool IsKnownNoRecurse;
1193 A, this, IRPosition::function(*AIFn), DepClassTy::OPTIONAL,
1194 IsKnownNoRecurse)) {
1195 IsLiveInCalleeCB = [AIFn](const Function &Fn) { return AIFn != &Fn; };
1196 }
1197 } else if (auto *GV = dyn_cast<GlobalValue>(&getAssociatedValue())) {
1198 // If the global has kernel lifetime we can stop if we reach a kernel
1199 // as it is "dead" in the (unknown) callees.
1200 ObjHasKernelLifetime = HasKernelLifetime(GV, *GV->getParent());
1201 if (ObjHasKernelLifetime)
1202 IsLiveInCalleeCB = [&A](const Function &Fn) {
1203 return !A.getInfoCache().isKernel(Fn);
1204 };
1205 }
1206
1207 // Set of accesses/instructions that will overwrite the result and are
1208 // therefore blockers in the reachability traversal.
1209 AA::InstExclusionSetTy ExclusionSet;
1210
1211 auto AccessCB = [&](const Access &Acc, bool Exact) {
1212 Function *AccScope = Acc.getRemoteInst()->getFunction();
1213 bool AccInSameScope = AccScope == &Scope;
1214
1215 // If the object has kernel lifetime we can ignore accesses only reachable
1216 // by other kernels. For now we only skip accesses *in* other kernels.
1217 if (InstInKernel && ObjHasKernelLifetime && !AccInSameScope &&
1218 A.getInfoCache().isKernel(*AccScope))
1219 return true;
1220
1221 if (Exact && Acc.isMustAccess() && Acc.getRemoteInst() != &I) {
1222 if (Acc.isWrite() || (isa<LoadInst>(I) && Acc.isWriteOrAssumption()))
1223 ExclusionSet.insert(Acc.getRemoteInst());
1224 }
1225
1226 if ((!FindInterferingWrites || !Acc.isWriteOrAssumption()) &&
1227 (!FindInterferingReads || !Acc.isRead()))
1228 return true;
1229
1230 bool Dominates = FindInterferingWrites && DT && Exact &&
1231 Acc.isMustAccess() && AccInSameScope &&
1232 DT->dominates(Acc.getRemoteInst(), &I);
1233 if (Dominates)
1234 DominatingWrites.insert(&Acc);
1235
1236 // Track if all interesting accesses are in the same `nosync` function as
1237 // the given instruction.
1238 AllInSameNoSyncFn &= Acc.getRemoteInst()->getFunction() == &Scope;
1239
1240 InterferingAccesses.push_back({&Acc, Exact});
1241 return true;
1242 };
1243 if (!State::forallInterferingAccesses(I, AccessCB, Range))
1244 return false;
1245
1246 HasBeenWrittenTo = !DominatingWrites.empty();
1247
1248 // Dominating writes form a chain, find the least/lowest member.
1249 Instruction *LeastDominatingWriteInst = nullptr;
1250 for (const Access *Acc : DominatingWrites) {
1251 if (!LeastDominatingWriteInst) {
1252 LeastDominatingWriteInst = Acc->getRemoteInst();
1253 } else if (DT->dominates(LeastDominatingWriteInst,
1254 Acc->getRemoteInst())) {
1255 LeastDominatingWriteInst = Acc->getRemoteInst();
1256 }
1257 }
1258
1259 // Helper to determine if we can skip a specific write access.
1260 auto CanSkipAccess = [&](const Access &Acc, bool Exact) {
1261 if (SkipCB && SkipCB(Acc))
1262 return true;
1263 if (!CanIgnoreThreading(Acc))
1264 return false;
1265
1266 // Check read (RAW) dependences and write (WAR) dependences as necessary.
1267 // If we successfully excluded all effects we are interested in, the
1268 // access can be skipped.
1269 bool ReadChecked = !FindInterferingReads;
1270 bool WriteChecked = !FindInterferingWrites;
1271
1272 // If the instruction cannot reach the access, the former does not
1273 // interfere with what the access reads.
1274 if (!ReadChecked) {
1275 if (!AA::isPotentiallyReachable(A, I, *Acc.getRemoteInst(), QueryingAA,
1276 &ExclusionSet, IsLiveInCalleeCB))
1277 ReadChecked = true;
1278 }
1279 // If the instruction cannot be reach from the access, the latter does not
1280 // interfere with what the instruction reads.
1281 if (!WriteChecked) {
1282 if (!AA::isPotentiallyReachable(A, *Acc.getRemoteInst(), I, QueryingAA,
1283 &ExclusionSet, IsLiveInCalleeCB))
1284 WriteChecked = true;
1285 }
1286
1287 // If we still might be affected by the write of the access but there are
1288 // dominating writes in the function of the instruction
1289 // (HasBeenWrittenTo), we can try to reason that the access is overwritten
1290 // by them. This would have happend above if they are all in the same
1291 // function, so we only check the inter-procedural case. Effectively, we
1292 // want to show that there is no call after the dominting write that might
1293 // reach the access, and when it returns reach the instruction with the
1294 // updated value. To this end, we iterate all call sites, check if they
1295 // might reach the instruction without going through another access
1296 // (ExclusionSet) and at the same time might reach the access. However,
1297 // that is all part of AAInterFnReachability.
1298 if (!WriteChecked && HasBeenWrittenTo &&
1299 Acc.getRemoteInst()->getFunction() != &Scope) {
1300
1301 const auto *FnReachabilityAA = A.getAAFor<AAInterFnReachability>(
1302 QueryingAA, IRPosition::function(Scope), DepClassTy::OPTIONAL);
1303 if (FnReachabilityAA) {
1304 // Without going backwards in the call tree, can we reach the access
1305 // from the least dominating write. Do not allow to pass the
1306 // instruction itself either.
1307 bool Inserted = ExclusionSet.insert(&I).second;
1308
1309 if (!FnReachabilityAA->instructionCanReach(
1310 A, *LeastDominatingWriteInst,
1311 *Acc.getRemoteInst()->getFunction(), &ExclusionSet))
1312 WriteChecked = true;
1313
1314 if (Inserted)
1315 ExclusionSet.erase(&I);
1316 }
1317 }
1318
1319 if (ReadChecked && WriteChecked)
1320 return true;
1321
1322 if (!DT || !UseDominanceReasoning)
1323 return false;
1324 if (!DominatingWrites.count(&Acc))
1325 return false;
1326 return LeastDominatingWriteInst != Acc.getRemoteInst();
1327 };
1328
1329 // Run the user callback on all accesses we cannot skip and return if
1330 // that succeeded for all or not.
1331 for (auto &It : InterferingAccesses) {
1332 if ((!AllInSameNoSyncFn && !IsThreadLocalObj && !ExecDomainAA) ||
1333 !CanSkipAccess(*It.first, It.second)) {
1334 if (!UserCB(*It.first, It.second))
1335 return false;
1336 }
1337 }
1338 return true;
1339 }
1340
1341 ChangeStatus translateAndAddStateFromCallee(Attributor &A,
1342 const AAPointerInfo &OtherAA,
1343 CallBase &CB) {
1344 using namespace AA::PointerInfo;
1345 if (!OtherAA.getState().isValidState() || !isValidState())
1346 return indicatePessimisticFixpoint();
1347
1348 ChangeStatus Changed = ChangeStatus::UNCHANGED;
1349 const auto &OtherAAImpl = static_cast<const AAPointerInfoImpl &>(OtherAA);
1350 bool IsByval = OtherAAImpl.getAssociatedArgument()->hasByValAttr();
1351 Changed |= setReachesReturn(OtherAAImpl.ReturnedOffsets);
1352
1353 // Combine the accesses bin by bin.
1354 const auto &State = OtherAAImpl.getState();
1355 for (const auto &It : State) {
1356 for (auto Index : It.getSecond()) {
1357 const auto &RAcc = State.getAccess(Index);
1358 if (IsByval && !RAcc.isRead())
1359 continue;
1360 bool UsedAssumedInformation = false;
1361 AccessKind AK = RAcc.getKind();
1362 auto Content = A.translateArgumentToCallSiteContent(
1363 RAcc.getContent(), CB, *this, UsedAssumedInformation);
1364 AK = AccessKind(AK & (IsByval ? AccessKind::AK_R : AccessKind::AK_RW));
1365 AK = AccessKind(AK | (RAcc.isMayAccess() ? AK_MAY : AK_MUST));
1366
1367 Changed |= addAccess(A, RAcc.getRanges(), CB, Content, AK,
1368 RAcc.getType(), RAcc.getRemoteInst());
1369 }
1370 }
1371 return Changed;
1372 }
1373
1374 ChangeStatus translateAndAddState(Attributor &A, const AAPointerInfo &OtherAA,
1375 const OffsetInfo &Offsets, CallBase &CB,
1376 bool IsMustAcc) {
1377 using namespace AA::PointerInfo;
1378 if (!OtherAA.getState().isValidState() || !isValidState())
1379 return indicatePessimisticFixpoint();
1380
1381 const auto &OtherAAImpl = static_cast<const AAPointerInfoImpl &>(OtherAA);
1382
1383 // Combine the accesses bin by bin.
1384 ChangeStatus Changed = ChangeStatus::UNCHANGED;
1385 const auto &State = OtherAAImpl.getState();
1386 for (const auto &It : State) {
1387 for (auto Index : It.getSecond()) {
1388 const auto &RAcc = State.getAccess(Index);
1389 if (!IsMustAcc && RAcc.isAssumption())
1390 continue;
1391 for (auto Offset : Offsets) {
1392 auto NewRanges = Offset == AA::RangeTy::Unknown
1394 : RAcc.getRanges();
1395 if (!NewRanges.isUnknown()) {
1396 NewRanges.addToAllOffsets(Offset);
1397 }
1398 AccessKind AK = RAcc.getKind();
1399 if (!IsMustAcc)
1400 AK = AccessKind((AK & ~AK_MUST) | AK_MAY);
1401 Changed |= addAccess(A, NewRanges, CB, RAcc.getContent(), AK,
1402 RAcc.getType(), RAcc.getRemoteInst());
1403 }
1404 }
1405 }
1406 return Changed;
1407 }
1408
1409 /// Statistic tracking for all AAPointerInfo implementations.
1410 /// See AbstractAttribute::trackStatistics().
1411 void trackPointerInfoStatistics(const IRPosition &IRP) const {}
1412
1413 /// Dump the state into \p O.
1414 void dumpState(raw_ostream &O) {
1415 for (auto &It : OffsetBins) {
1416 O << "[" << It.first.Offset << "-" << It.first.Offset + It.first.Size
1417 << "] : " << It.getSecond().size() << "\n";
1418 for (auto AccIndex : It.getSecond()) {
1419 auto &Acc = AccessList[AccIndex];
1420 O << " - " << Acc.getKind() << " - " << *Acc.getLocalInst() << "\n";
1421 if (Acc.getLocalInst() != Acc.getRemoteInst())
1422 O << " --> " << *Acc.getRemoteInst()
1423 << "\n";
1424 if (!Acc.isWrittenValueYetUndetermined()) {
1425 if (isa_and_nonnull<Function>(Acc.getWrittenValue()))
1426 O << " - c: func " << Acc.getWrittenValue()->getName()
1427 << "\n";
1428 else if (Acc.getWrittenValue())
1429 O << " - c: " << *Acc.getWrittenValue() << "\n";
1430 else
1431 O << " - c: <unknown>\n";
1432 }
1433 }
1434 }
1435 }
1436};
1437
1438struct AAPointerInfoFloating : public AAPointerInfoImpl {
1440 AAPointerInfoFloating(const IRPosition &IRP, Attributor &A)
1441 : AAPointerInfoImpl(IRP, A) {}
1442
1443 /// Deal with an access and signal if it was handled successfully.
1444 bool handleAccess(Attributor &A, Instruction &I,
1445 std::optional<Value *> Content, AccessKind Kind,
1446 OffsetInfo::VecTy &Offsets, ChangeStatus &Changed,
1447 Type &Ty) {
1448 using namespace AA::PointerInfo;
1450 const DataLayout &DL = A.getDataLayout();
1451 TypeSize AccessSize = DL.getTypeStoreSize(&Ty);
1452 if (!AccessSize.isScalable())
1453 Size = AccessSize.getFixedValue();
1454
1455 // Make a strictly ascending list of offsets as required by addAccess()
1456 SmallVector<int64_t> OffsetsSorted(Offsets.begin(), Offsets.end());
1457 llvm::sort(OffsetsSorted);
1458
1460 if (!VT || VT->getElementCount().isScalable() ||
1461 !Content.value_or(nullptr) || !isa<Constant>(*Content) ||
1462 (*Content)->getType() != VT ||
1463 DL.getTypeStoreSize(VT->getElementType()).isScalable()) {
1464 Changed =
1465 Changed | addAccess(A, {OffsetsSorted, Size}, I, Content, Kind, &Ty);
1466 } else {
1467 // Handle vector stores with constant content element-wise.
1468 // TODO: We could look for the elements or create instructions
1469 // representing them.
1470 // TODO: We need to push the Content into the range abstraction
1471 // (AA::RangeTy) to allow different content values for different
1472 // ranges. ranges. Hence, support vectors storing different values.
1473 Type *ElementType = VT->getElementType();
1474 int64_t ElementSize = DL.getTypeStoreSize(ElementType).getFixedValue();
1475 auto *ConstContent = cast<Constant>(*Content);
1476 Type *Int32Ty = Type::getInt32Ty(ElementType->getContext());
1477 SmallVector<int64_t> ElementOffsets(Offsets.begin(), Offsets.end());
1478
1479 for (int i = 0, e = VT->getElementCount().getFixedValue(); i != e; ++i) {
1480 Value *ElementContent = ConstantExpr::getExtractElement(
1481 ConstContent, ConstantInt::get(Int32Ty, i));
1482
1483 // Add the element access.
1484 Changed = Changed | addAccess(A, {ElementOffsets, ElementSize}, I,
1485 ElementContent, Kind, ElementType);
1486
1487 // Advance the offsets for the next element.
1488 for (auto &ElementOffset : ElementOffsets)
1489 ElementOffset += ElementSize;
1490 }
1491 }
1492 return true;
1493 };
1494
1495 /// See AbstractAttribute::updateImpl(...).
1496 ChangeStatus updateImpl(Attributor &A) override;
1497
1498 /// If the indices to \p GEP can be traced to constants, incorporate all
1499 /// of these into \p UsrOI.
1500 ///
1501 /// \return true iff \p UsrOI is updated.
1502 bool collectConstantsForGEP(Attributor &A, const DataLayout &DL,
1503 OffsetInfo &UsrOI, const OffsetInfo &PtrOI,
1504 const GEPOperator *GEP);
1505
1506 /// See AbstractAttribute::trackStatistics()
1507 void trackStatistics() const override {
1508 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
1509 }
1510};
1511
1512bool AAPointerInfoFloating::collectConstantsForGEP(Attributor &A,
1513 const DataLayout &DL,
1514 OffsetInfo &UsrOI,
1515 const OffsetInfo &PtrOI,
1516 const GEPOperator *GEP) {
1517 unsigned BitWidth = DL.getIndexTypeSizeInBits(GEP->getType());
1518 SmallMapVector<Value *, APInt, 4> VariableOffsets;
1519 APInt ConstantOffset(BitWidth, 0);
1520
1521 assert(!UsrOI.isUnknown() && !PtrOI.isUnknown() &&
1522 "Don't look for constant values if the offset has already been "
1523 "determined to be unknown.");
1524
1525 if (!GEP->collectOffset(DL, BitWidth, VariableOffsets, ConstantOffset)) {
1526 UsrOI.setUnknown();
1527 return true;
1528 }
1529
1530 LLVM_DEBUG(dbgs() << "[AAPointerInfo] GEP offset is "
1531 << (VariableOffsets.empty() ? "" : "not") << " constant "
1532 << *GEP << "\n");
1533
1534 auto Union = PtrOI;
1535 Union.addToAll(ConstantOffset.getSExtValue());
1536
1537 // Each VI in VariableOffsets has a set of potential constant values. Every
1538 // combination of elements, picked one each from these sets, is separately
1539 // added to the original set of offsets, thus resulting in more offsets.
1540 for (const auto &VI : VariableOffsets) {
1541 auto *PotentialConstantsAA = A.getAAFor<AAPotentialConstantValues>(
1542 *this, IRPosition::value(*VI.first), DepClassTy::OPTIONAL);
1543 if (!PotentialConstantsAA || !PotentialConstantsAA->isValidState()) {
1544 UsrOI.setUnknown();
1545 return true;
1546 }
1547
1548 // UndefValue is treated as a zero, which leaves Union as is.
1549 if (PotentialConstantsAA->undefIsContained())
1550 continue;
1551
1552 // We need at least one constant in every set to compute an actual offset.
1553 // Otherwise, we end up pessimizing AAPointerInfo by respecting offsets that
1554 // don't actually exist. In other words, the absence of constant values
1555 // implies that the operation can be assumed dead for now.
1556 auto &AssumedSet = PotentialConstantsAA->getAssumedSet();
1557 if (AssumedSet.empty())
1558 return false;
1559
1560 OffsetInfo Product;
1561 for (const auto &ConstOffset : AssumedSet) {
1562 auto CopyPerOffset = Union;
1563 CopyPerOffset.addToAll(ConstOffset.getSExtValue() *
1564 VI.second.getZExtValue());
1565 Product.merge(CopyPerOffset);
1566 }
1567 Union = Product;
1568 }
1569
1570 UsrOI = std::move(Union);
1571 return true;
1572}
1573
1574ChangeStatus AAPointerInfoFloating::updateImpl(Attributor &A) {
1575 using namespace AA::PointerInfo;
1577 const DataLayout &DL = A.getDataLayout();
1578 Value &AssociatedValue = getAssociatedValue();
1579
1580 DenseMap<Value *, OffsetInfo> OffsetInfoMap;
1581 OffsetInfoMap[&AssociatedValue].insert(0);
1582
1583 auto HandlePassthroughUser = [&](Value *Usr, Value *CurPtr, bool &Follow) {
1584 // One does not simply walk into a map and assign a reference to a possibly
1585 // new location. That can cause an invalidation before the assignment
1586 // happens, like so:
1587 //
1588 // OffsetInfoMap[Usr] = OffsetInfoMap[CurPtr]; /* bad idea! */
1589 //
1590 // The RHS is a reference that may be invalidated by an insertion caused by
1591 // the LHS. So we ensure that the side-effect of the LHS happens first.
1592
1593 assert(OffsetInfoMap.contains(CurPtr) &&
1594 "CurPtr does not exist in the map!");
1595
1596 auto &UsrOI = OffsetInfoMap[Usr];
1597 auto &PtrOI = OffsetInfoMap[CurPtr];
1598 assert(!PtrOI.isUnassigned() &&
1599 "Cannot pass through if the input Ptr was not visited!");
1600 UsrOI.merge(PtrOI);
1601 Follow = true;
1602 return true;
1603 };
1604
1605 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
1606 Value *CurPtr = U.get();
1607 User *Usr = U.getUser();
1608 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Analyze " << *CurPtr << " in " << *Usr
1609 << "\n");
1610 assert(OffsetInfoMap.count(CurPtr) &&
1611 "The current pointer offset should have been seeded!");
1612 assert(!OffsetInfoMap[CurPtr].isUnassigned() &&
1613 "Current pointer should be assigned");
1614
1615 if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Usr)) {
1616 if (CE->isCast())
1617 return HandlePassthroughUser(Usr, CurPtr, Follow);
1618 if (!isa<GEPOperator>(CE)) {
1619 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Unhandled constant user " << *CE
1620 << "\n");
1621 return false;
1622 }
1623 }
1624 if (auto *GEP = dyn_cast<GEPOperator>(Usr)) {
1625 // Note the order here, the Usr access might change the map, CurPtr is
1626 // already in it though.
1627 auto &UsrOI = OffsetInfoMap[Usr];
1628 auto &PtrOI = OffsetInfoMap[CurPtr];
1629
1630 if (UsrOI.isUnknown())
1631 return true;
1632
1633 if (PtrOI.isUnknown()) {
1634 Follow = true;
1635 UsrOI.setUnknown();
1636 return true;
1637 }
1638
1639 Follow = collectConstantsForGEP(A, DL, UsrOI, PtrOI, GEP);
1640 return true;
1641 }
1642 if (isa<PtrToIntInst>(Usr))
1643 return false;
1644 if (isa<CastInst>(Usr) || isa<SelectInst>(Usr))
1645 return HandlePassthroughUser(Usr, CurPtr, Follow);
1646 // Returns are allowed if they are in the associated functions. Users can
1647 // then check the call site return. Returns from other functions can't be
1648 // tracked and are cause for invalidation.
1649 if (auto *RI = dyn_cast<ReturnInst>(Usr)) {
1650 if (RI->getFunction() == getAssociatedFunction()) {
1651 auto &PtrOI = OffsetInfoMap[CurPtr];
1652 Changed |= setReachesReturn(PtrOI);
1653 return true;
1654 }
1655 return false;
1656 }
1657
1658 // For PHIs we need to take care of the recurrence explicitly as the value
1659 // might change while we iterate through a loop. For now, we give up if
1660 // the PHI is not invariant.
1661 if (auto *PHI = dyn_cast<PHINode>(Usr)) {
1662 // Note the order here, the Usr access might change the map, CurPtr is
1663 // already in it though.
1664 auto [PhiIt, IsFirstPHIUser] = OffsetInfoMap.try_emplace(PHI);
1665 auto &UsrOI = PhiIt->second;
1666 auto &PtrOI = OffsetInfoMap[CurPtr];
1667
1668 // Check if the PHI operand has already an unknown offset as we can't
1669 // improve on that anymore.
1670 if (PtrOI.isUnknown()) {
1671 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI operand offset unknown "
1672 << *CurPtr << " in " << *PHI << "\n");
1673 Follow = !UsrOI.isUnknown();
1674 UsrOI.setUnknown();
1675 return true;
1676 }
1677
1678 // Check if the PHI is invariant (so far).
1679 if (UsrOI == PtrOI) {
1680 assert(!PtrOI.isUnassigned() &&
1681 "Cannot assign if the current Ptr was not visited!");
1682 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI is invariant (so far)");
1683 return true;
1684 }
1685
1686 // Check if the PHI operand can be traced back to AssociatedValue.
1687 APInt Offset(
1688 DL.getIndexSizeInBits(CurPtr->getType()->getPointerAddressSpace()),
1689 0);
1690 Value *CurPtrBase = CurPtr->stripAndAccumulateConstantOffsets(
1691 DL, Offset, /* AllowNonInbounds */ true);
1692 auto It = OffsetInfoMap.find(CurPtrBase);
1693 if (It == OffsetInfoMap.end()) {
1694 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI operand is too complex "
1695 << *CurPtr << " in " << *PHI
1696 << " (base: " << *CurPtrBase << ")\n");
1697 UsrOI.setUnknown();
1698 Follow = true;
1699 return true;
1700 }
1701
1702 // Check if the PHI operand is not dependent on the PHI itself. Every
1703 // recurrence is a cyclic net of PHIs in the data flow, and has an
1704 // equivalent Cycle in the control flow. One of those PHIs must be in the
1705 // header of that control flow Cycle. This is independent of the choice of
1706 // Cycles reported by CycleInfo. It is sufficient to check the PHIs in
1707 // every Cycle header; if such a node is marked unknown, this will
1708 // eventually propagate through the whole net of PHIs in the recurrence.
1709 const auto *CI =
1710 A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>(
1711 *PHI->getFunction());
1712 if (mayBeInCycle(CI, cast<Instruction>(Usr), /* HeaderOnly */ true)) {
1713 auto BaseOI = It->getSecond();
1714 BaseOI.addToAll(Offset.getZExtValue());
1715 if (IsFirstPHIUser || BaseOI == UsrOI) {
1716 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI is invariant " << *CurPtr
1717 << " in " << *Usr << "\n");
1718 return HandlePassthroughUser(Usr, CurPtr, Follow);
1719 }
1720
1721 LLVM_DEBUG(
1722 dbgs() << "[AAPointerInfo] PHI operand pointer offset mismatch "
1723 << *CurPtr << " in " << *PHI << "\n");
1724 UsrOI.setUnknown();
1725 Follow = true;
1726 return true;
1727 }
1728
1729 UsrOI.merge(PtrOI);
1730 Follow = true;
1731 return true;
1732 }
1733
1734 if (auto *LoadI = dyn_cast<LoadInst>(Usr)) {
1735 // If the access is to a pointer that may or may not be the associated
1736 // value, e.g. due to a PHI, we cannot assume it will be read.
1737 AccessKind AK = AccessKind::AK_R;
1738 if (getUnderlyingObject(CurPtr) == &AssociatedValue)
1739 AK = AccessKind(AK | AccessKind::AK_MUST);
1740 else
1741 AK = AccessKind(AK | AccessKind::AK_MAY);
1742 if (!handleAccess(A, *LoadI, /* Content */ nullptr, AK,
1743 OffsetInfoMap[CurPtr].Offsets, Changed,
1744 *LoadI->getType()))
1745 return false;
1746
1747 auto IsAssumption = [](Instruction &I) {
1748 if (auto *II = dyn_cast<IntrinsicInst>(&I))
1749 return II->isAssumeLikeIntrinsic();
1750 return false;
1751 };
1752
1753 auto IsImpactedInRange = [&](Instruction *FromI, Instruction *ToI) {
1754 // Check if the assumption and the load are executed together without
1755 // memory modification.
1756 do {
1757 if (FromI->mayWriteToMemory() && !IsAssumption(*FromI))
1758 return true;
1759 FromI = FromI->getNextNode();
1760 } while (FromI && FromI != ToI);
1761 return false;
1762 };
1763
1764 BasicBlock *BB = LoadI->getParent();
1765 auto IsValidAssume = [&](IntrinsicInst &IntrI) {
1766 if (IntrI.getIntrinsicID() != Intrinsic::assume)
1767 return false;
1768 BasicBlock *IntrBB = IntrI.getParent();
1769 if (IntrI.getParent() == BB) {
1770 if (IsImpactedInRange(LoadI->getNextNode(), &IntrI))
1771 return false;
1772 } else {
1773 auto PredIt = pred_begin(IntrBB);
1774 if (PredIt == pred_end(IntrBB))
1775 return false;
1776 if ((*PredIt) != BB)
1777 return false;
1778 if (++PredIt != pred_end(IntrBB))
1779 return false;
1780 for (auto *SuccBB : successors(BB)) {
1781 if (SuccBB == IntrBB)
1782 continue;
1783 if (isa<UnreachableInst>(SuccBB->getTerminator()))
1784 continue;
1785 return false;
1786 }
1787 if (IsImpactedInRange(LoadI->getNextNode(), BB->getTerminator()))
1788 return false;
1789 if (IsImpactedInRange(&IntrBB->front(), &IntrI))
1790 return false;
1791 }
1792 return true;
1793 };
1794
1795 std::pair<Value *, IntrinsicInst *> Assumption;
1796 for (const Use &LoadU : LoadI->uses()) {
1797 if (auto *CmpI = dyn_cast<CmpInst>(LoadU.getUser())) {
1798 if (!CmpI->isEquality() || !CmpI->isTrueWhenEqual())
1799 continue;
1800 for (const Use &CmpU : CmpI->uses()) {
1801 if (auto *IntrI = dyn_cast<IntrinsicInst>(CmpU.getUser())) {
1802 if (!IsValidAssume(*IntrI))
1803 continue;
1804 int Idx = CmpI->getOperandUse(0) == LoadU;
1805 Assumption = {CmpI->getOperand(Idx), IntrI};
1806 break;
1807 }
1808 }
1809 }
1810 if (Assumption.first)
1811 break;
1812 }
1813
1814 // Check if we found an assumption associated with this load.
1815 if (!Assumption.first || !Assumption.second)
1816 return true;
1817
1818 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Assumption found "
1819 << *Assumption.second << ": " << *LoadI
1820 << " == " << *Assumption.first << "\n");
1821 bool UsedAssumedInformation = false;
1822 std::optional<Value *> Content = nullptr;
1823 if (Assumption.first)
1824 Content =
1825 A.getAssumedSimplified(*Assumption.first, *this,
1826 UsedAssumedInformation, AA::Interprocedural);
1827 return handleAccess(
1828 A, *Assumption.second, Content, AccessKind::AK_ASSUMPTION,
1829 OffsetInfoMap[CurPtr].Offsets, Changed, *LoadI->getType());
1830 }
1831
1832 auto HandleStoreLike = [&](Instruction &I, Value *ValueOp, Type &ValueTy,
1833 ArrayRef<Value *> OtherOps, AccessKind AK) {
1834 for (auto *OtherOp : OtherOps) {
1835 if (OtherOp == CurPtr) {
1836 LLVM_DEBUG(
1837 dbgs()
1838 << "[AAPointerInfo] Escaping use in store like instruction " << I
1839 << "\n");
1840 return false;
1841 }
1842 }
1843
1844 // If the access is to a pointer that may or may not be the associated
1845 // value, e.g. due to a PHI, we cannot assume it will be written.
1846 if (getUnderlyingObject(CurPtr) == &AssociatedValue)
1847 AK = AccessKind(AK | AccessKind::AK_MUST);
1848 else
1849 AK = AccessKind(AK | AccessKind::AK_MAY);
1850 bool UsedAssumedInformation = false;
1851 std::optional<Value *> Content = nullptr;
1852 if (ValueOp)
1853 Content = A.getAssumedSimplified(
1854 *ValueOp, *this, UsedAssumedInformation, AA::Interprocedural);
1855 return handleAccess(A, I, Content, AK, OffsetInfoMap[CurPtr].Offsets,
1856 Changed, ValueTy);
1857 };
1858
1859 if (auto *StoreI = dyn_cast<StoreInst>(Usr))
1860 return HandleStoreLike(*StoreI, StoreI->getValueOperand(),
1861 *StoreI->getValueOperand()->getType(),
1862 {StoreI->getValueOperand()}, AccessKind::AK_W);
1863 if (auto *RMWI = dyn_cast<AtomicRMWInst>(Usr))
1864 return HandleStoreLike(*RMWI, nullptr, *RMWI->getValOperand()->getType(),
1865 {RMWI->getValOperand()}, AccessKind::AK_RW);
1866 if (auto *CXI = dyn_cast<AtomicCmpXchgInst>(Usr))
1867 return HandleStoreLike(
1868 *CXI, nullptr, *CXI->getNewValOperand()->getType(),
1869 {CXI->getCompareOperand(), CXI->getNewValOperand()},
1870 AccessKind::AK_RW);
1871
1872 if (auto *CB = dyn_cast<CallBase>(Usr)) {
1873 if (CB->isLifetimeStartOrEnd())
1874 return true;
1875 const auto *TLI =
1876 A.getInfoCache().getTargetLibraryInfoForFunction(*CB->getFunction());
1877 if (getFreedOperand(CB, TLI) == U)
1878 return true;
1879 if (CB->isArgOperand(&U)) {
1880 unsigned ArgNo = CB->getArgOperandNo(&U);
1881 const auto *CSArgPI = A.getAAFor<AAPointerInfo>(
1882 *this, IRPosition::callsite_argument(*CB, ArgNo),
1884 if (!CSArgPI)
1885 return false;
1886 bool IsArgMustAcc = (getUnderlyingObject(CurPtr) == &AssociatedValue);
1887 Changed = translateAndAddState(A, *CSArgPI, OffsetInfoMap[CurPtr], *CB,
1888 IsArgMustAcc) |
1889 Changed;
1890 if (!CSArgPI->reachesReturn())
1891 return isValidState();
1892
1894 if (!Callee || Callee->arg_size() <= ArgNo)
1895 return false;
1896 bool UsedAssumedInformation = false;
1897 auto ReturnedValue = A.getAssumedSimplified(
1898 IRPosition::returned(*Callee), *this, UsedAssumedInformation,
1900 auto *ReturnedArg =
1901 dyn_cast_or_null<Argument>(ReturnedValue.value_or(nullptr));
1902 auto *Arg = Callee->getArg(ArgNo);
1903 if (ReturnedArg && Arg != ReturnedArg)
1904 return true;
1905 bool IsRetMustAcc = IsArgMustAcc && (ReturnedArg == Arg);
1906 const auto *CSRetPI = A.getAAFor<AAPointerInfo>(
1908 if (!CSRetPI)
1909 return false;
1910 OffsetInfo OI = OffsetInfoMap[CurPtr];
1911 CSArgPI->addReturnedOffsetsTo(OI);
1912 Changed =
1913 translateAndAddState(A, *CSRetPI, OI, *CB, IsRetMustAcc) | Changed;
1914 return isValidState();
1915 }
1916 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Call user not handled " << *CB
1917 << "\n");
1918 return false;
1919 }
1920
1921 LLVM_DEBUG(dbgs() << "[AAPointerInfo] User not handled " << *Usr << "\n");
1922 return false;
1923 };
1924 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) {
1925 assert(OffsetInfoMap.count(OldU) && "Old use should be known already!");
1926 assert(!OffsetInfoMap[OldU].isUnassigned() && "Old use should be assinged");
1927 if (OffsetInfoMap.count(NewU)) {
1928 LLVM_DEBUG({
1929 if (!(OffsetInfoMap[NewU] == OffsetInfoMap[OldU])) {
1930 dbgs() << "[AAPointerInfo] Equivalent use callback failed: "
1931 << OffsetInfoMap[NewU] << " vs " << OffsetInfoMap[OldU]
1932 << "\n";
1933 }
1934 });
1935 return OffsetInfoMap[NewU] == OffsetInfoMap[OldU];
1936 }
1937 bool Unused;
1938 return HandlePassthroughUser(NewU.get(), OldU.get(), Unused);
1939 };
1940 if (!A.checkForAllUses(UsePred, *this, AssociatedValue,
1941 /* CheckBBLivenessOnly */ true, DepClassTy::OPTIONAL,
1942 /* IgnoreDroppableUses */ true, EquivalentUseCB)) {
1943 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Check for all uses failed, abort!\n");
1944 return indicatePessimisticFixpoint();
1945 }
1946
1947 LLVM_DEBUG({
1948 dbgs() << "Accesses by bin after update:\n";
1949 dumpState(dbgs());
1950 });
1951
1952 return Changed;
1953}
1954
1955struct AAPointerInfoReturned final : AAPointerInfoImpl {
1956 AAPointerInfoReturned(const IRPosition &IRP, Attributor &A)
1957 : AAPointerInfoImpl(IRP, A) {}
1958
1959 /// See AbstractAttribute::updateImpl(...).
1960 ChangeStatus updateImpl(Attributor &A) override {
1961 return indicatePessimisticFixpoint();
1962 }
1963
1964 /// See AbstractAttribute::trackStatistics()
1965 void trackStatistics() const override {
1966 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
1967 }
1968};
1969
1970struct AAPointerInfoArgument final : AAPointerInfoFloating {
1971 AAPointerInfoArgument(const IRPosition &IRP, Attributor &A)
1972 : AAPointerInfoFloating(IRP, A) {}
1973
1974 /// See AbstractAttribute::trackStatistics()
1975 void trackStatistics() const override {
1976 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
1977 }
1978};
1979
1980struct AAPointerInfoCallSiteArgument final : AAPointerInfoFloating {
1981 AAPointerInfoCallSiteArgument(const IRPosition &IRP, Attributor &A)
1982 : AAPointerInfoFloating(IRP, A) {}
1983
1984 /// See AbstractAttribute::updateImpl(...).
1985 ChangeStatus updateImpl(Attributor &A) override {
1986 using namespace AA::PointerInfo;
1987 // We handle memory intrinsics explicitly, at least the first (=
1988 // destination) and second (=source) arguments as we know how they are
1989 // accessed.
1990 if (auto *MI = dyn_cast_or_null<MemIntrinsic>(getCtxI())) {
1991 int64_t LengthVal = AA::RangeTy::Unknown;
1992 if (auto Length = MI->getLengthInBytes())
1993 LengthVal = Length->getSExtValue();
1994 unsigned ArgNo = getIRPosition().getCallSiteArgNo();
1995 ChangeStatus Changed = ChangeStatus::UNCHANGED;
1996 if (ArgNo > 1) {
1997 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Unhandled memory intrinsic "
1998 << *MI << "\n");
1999 return indicatePessimisticFixpoint();
2000 } else {
2001 auto Kind =
2002 ArgNo == 0 ? AccessKind::AK_MUST_WRITE : AccessKind::AK_MUST_READ;
2003 Changed =
2004 Changed | addAccess(A, {0, LengthVal}, *MI, nullptr, Kind, nullptr);
2005 }
2006 LLVM_DEBUG({
2007 dbgs() << "Accesses by bin after update:\n";
2008 dumpState(dbgs());
2009 });
2010
2011 return Changed;
2012 }
2013
2014 // TODO: Once we have call site specific value information we can provide
2015 // call site specific liveness information and then it makes
2016 // sense to specialize attributes for call sites arguments instead of
2017 // redirecting requests to the callee argument.
2018 Argument *Arg = getAssociatedArgument();
2019 if (Arg) {
2020 const IRPosition &ArgPos = IRPosition::argument(*Arg);
2021 auto *ArgAA =
2022 A.getAAFor<AAPointerInfo>(*this, ArgPos, DepClassTy::REQUIRED);
2023 if (ArgAA && ArgAA->getState().isValidState())
2024 return translateAndAddStateFromCallee(A, *ArgAA,
2025 *cast<CallBase>(getCtxI()));
2026 if (!Arg->getParent()->isDeclaration())
2027 return indicatePessimisticFixpoint();
2028 }
2029
2030 bool IsKnownNoCapture;
2032 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNoCapture))
2033 return indicatePessimisticFixpoint();
2034
2035 bool IsKnown = false;
2036 if (AA::isAssumedReadNone(A, getIRPosition(), *this, IsKnown))
2037 return ChangeStatus::UNCHANGED;
2038 bool ReadOnly = AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown);
2039 auto Kind =
2040 ReadOnly ? AccessKind::AK_MAY_READ : AccessKind::AK_MAY_READ_WRITE;
2041 return addAccess(A, AA::RangeTy::getUnknown(), *getCtxI(), nullptr, Kind,
2042 nullptr);
2043 }
2044
2045 /// See AbstractAttribute::trackStatistics()
2046 void trackStatistics() const override {
2047 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
2048 }
2049};
2050
2051struct AAPointerInfoCallSiteReturned final : AAPointerInfoFloating {
2052 AAPointerInfoCallSiteReturned(const IRPosition &IRP, Attributor &A)
2053 : AAPointerInfoFloating(IRP, A) {}
2054
2055 /// See AbstractAttribute::trackStatistics()
2056 void trackStatistics() const override {
2057 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
2058 }
2059};
2060} // namespace
2061
2062/// -----------------------NoUnwind Function Attribute--------------------------
2063
2064namespace {
2065struct AANoUnwindImpl : AANoUnwind {
2066 AANoUnwindImpl(const IRPosition &IRP, Attributor &A) : AANoUnwind(IRP, A) {}
2067
2068 /// See AbstractAttribute::initialize(...).
2069 void initialize(Attributor &A) override {
2070 bool IsKnown;
2072 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
2073 (void)IsKnown;
2074 }
2075
2076 const std::string getAsStr(Attributor *A) const override {
2077 return getAssumed() ? "nounwind" : "may-unwind";
2078 }
2079
2080 /// See AbstractAttribute::updateImpl(...).
2081 ChangeStatus updateImpl(Attributor &A) override {
2082 auto Opcodes = {
2083 (unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,
2084 (unsigned)Instruction::Call, (unsigned)Instruction::CleanupRet,
2085 (unsigned)Instruction::CatchSwitch, (unsigned)Instruction::Resume};
2086
2087 auto CheckForNoUnwind = [&](Instruction &I) {
2088 if (!I.mayThrow(/* IncludePhaseOneUnwind */ true))
2089 return true;
2090
2091 if (const auto *CB = dyn_cast<CallBase>(&I)) {
2092 bool IsKnownNoUnwind;
2094 A, this, IRPosition::callsite_function(*CB), DepClassTy::REQUIRED,
2095 IsKnownNoUnwind);
2096 }
2097 return false;
2098 };
2099
2100 bool UsedAssumedInformation = false;
2101 if (!A.checkForAllInstructions(CheckForNoUnwind, *this, Opcodes,
2102 UsedAssumedInformation))
2103 return indicatePessimisticFixpoint();
2104
2105 return ChangeStatus::UNCHANGED;
2106 }
2107};
2108
2109struct AANoUnwindFunction final : public AANoUnwindImpl {
2110 AANoUnwindFunction(const IRPosition &IRP, Attributor &A)
2111 : AANoUnwindImpl(IRP, A) {}
2112
2113 /// See AbstractAttribute::trackStatistics()
2114 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nounwind) }
2115};
2116
2117/// NoUnwind attribute deduction for a call sites.
2118struct AANoUnwindCallSite final
2119 : AACalleeToCallSite<AANoUnwind, AANoUnwindImpl> {
2120 AANoUnwindCallSite(const IRPosition &IRP, Attributor &A)
2121 : AACalleeToCallSite<AANoUnwind, AANoUnwindImpl>(IRP, A) {}
2122
2123 /// See AbstractAttribute::trackStatistics()
2124 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nounwind); }
2125};
2126} // namespace
2127
2128/// ------------------------ NoSync Function Attribute -------------------------
2129
2130bool AANoSync::isAlignedBarrier(const CallBase &CB, bool ExecutedAligned) {
2131 switch (CB.getIntrinsicID()) {
2132 case Intrinsic::nvvm_barrier_cta_sync_aligned_all:
2133 case Intrinsic::nvvm_barrier_cta_sync_aligned_count:
2134 case Intrinsic::nvvm_barrier_cta_red_and_aligned_all:
2135 case Intrinsic::nvvm_barrier_cta_red_and_aligned_count:
2136 case Intrinsic::nvvm_barrier_cta_red_or_aligned_all:
2137 case Intrinsic::nvvm_barrier_cta_red_or_aligned_count:
2138 case Intrinsic::nvvm_barrier_cta_red_popc_aligned_all:
2139 case Intrinsic::nvvm_barrier_cta_red_popc_aligned_count:
2140 return true;
2141 case Intrinsic::amdgcn_s_barrier:
2142 if (ExecutedAligned)
2143 return true;
2144 break;
2145 default:
2146 break;
2147 }
2148 return hasAssumption(CB, KnownAssumptionString("ompx_aligned_barrier"));
2149}
2150
2152 if (!I->isAtomic())
2153 return false;
2154
2155 if (auto *FI = dyn_cast<FenceInst>(I))
2156 // All legal orderings for fence are stronger than monotonic.
2157 return FI->getSyncScopeID() != SyncScope::SingleThread;
2158 if (auto *AI = dyn_cast<AtomicCmpXchgInst>(I)) {
2159 // Unordered is not a legal ordering for cmpxchg.
2160 return (AI->getSuccessOrdering() != AtomicOrdering::Monotonic ||
2161 AI->getFailureOrdering() != AtomicOrdering::Monotonic);
2162 }
2163
2164 AtomicOrdering Ordering;
2165 switch (I->getOpcode()) {
2166 case Instruction::AtomicRMW:
2167 Ordering = cast<AtomicRMWInst>(I)->getOrdering();
2168 break;
2169 case Instruction::Store:
2170 Ordering = cast<StoreInst>(I)->getOrdering();
2171 break;
2172 case Instruction::Load:
2173 Ordering = cast<LoadInst>(I)->getOrdering();
2174 break;
2175 default:
2177 "New atomic operations need to be known in the attributor.");
2178 }
2179
2180 return (Ordering != AtomicOrdering::Unordered &&
2181 Ordering != AtomicOrdering::Monotonic);
2182}
2183
2184namespace {
2185struct AANoSyncImpl : AANoSync {
2186 AANoSyncImpl(const IRPosition &IRP, Attributor &A) : AANoSync(IRP, A) {}
2187
2188 /// See AbstractAttribute::initialize(...).
2189 void initialize(Attributor &A) override {
2190 bool IsKnown;
2191 assert(!AA::hasAssumedIRAttr<Attribute::NoSync>(A, nullptr, getIRPosition(),
2192 DepClassTy::NONE, IsKnown));
2193 (void)IsKnown;
2194 }
2195
2196 const std::string getAsStr(Attributor *A) const override {
2197 return getAssumed() ? "nosync" : "may-sync";
2198 }
2199
2200 /// See AbstractAttribute::updateImpl(...).
2201 ChangeStatus updateImpl(Attributor &A) override;
2202};
2203
2204ChangeStatus AANoSyncImpl::updateImpl(Attributor &A) {
2205
2206 auto CheckRWInstForNoSync = [&](Instruction &I) {
2207 return AA::isNoSyncInst(A, I, *this);
2208 };
2209
2210 auto CheckForNoSync = [&](Instruction &I) {
2211 // At this point we handled all read/write effects and they are all
2212 // nosync, so they can be skipped.
2213 if (I.mayReadOrWriteMemory())
2214 return true;
2215
2216 bool IsKnown;
2217 CallBase &CB = cast<CallBase>(I);
2220 IsKnown))
2221 return true;
2222
2223 // non-convergent and readnone imply nosync.
2224 return !CB.isConvergent();
2225 };
2226
2227 bool UsedAssumedInformation = false;
2228 if (!A.checkForAllReadWriteInstructions(CheckRWInstForNoSync, *this,
2229 UsedAssumedInformation) ||
2230 !A.checkForAllCallLikeInstructions(CheckForNoSync, *this,
2231 UsedAssumedInformation))
2232 return indicatePessimisticFixpoint();
2233
2235}
2236
2237struct AANoSyncFunction final : public AANoSyncImpl {
2238 AANoSyncFunction(const IRPosition &IRP, Attributor &A)
2239 : AANoSyncImpl(IRP, A) {}
2240
2241 /// See AbstractAttribute::trackStatistics()
2242 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nosync) }
2243};
2244
2245/// NoSync attribute deduction for a call sites.
2246struct AANoSyncCallSite final : AACalleeToCallSite<AANoSync, AANoSyncImpl> {
2247 AANoSyncCallSite(const IRPosition &IRP, Attributor &A)
2248 : AACalleeToCallSite<AANoSync, AANoSyncImpl>(IRP, A) {}
2249
2250 /// See AbstractAttribute::trackStatistics()
2251 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nosync); }
2252};
2253} // namespace
2254
2255/// ------------------------ No-Free Attributes ----------------------------
2256
2257namespace {
2258struct AANoFreeImpl : public AANoFree {
2259 AANoFreeImpl(const IRPosition &IRP, Attributor &A) : AANoFree(IRP, A) {}
2260
2261 /// See AbstractAttribute::initialize(...).
2262 void initialize(Attributor &A) override {
2263 bool IsKnown;
2264 assert(!AA::hasAssumedIRAttr<Attribute::NoFree>(A, nullptr, getIRPosition(),
2265 DepClassTy::NONE, IsKnown));
2266 (void)IsKnown;
2267 }
2268
2269 /// See AbstractAttribute::updateImpl(...).
2270 ChangeStatus updateImpl(Attributor &A) override {
2271 auto CheckForNoFree = [&](Instruction &I) {
2272 if (auto *CB = dyn_cast<CallBase>(&I)) {
2273 bool IsKnown;
2275 A, this, IRPosition::callsite_function(*CB), DepClassTy::REQUIRED,
2276 IsKnown);
2277 }
2278 // Make sure that synchronization cannot establish happens-before with a
2279 // free on another thread.
2280 return AA::isNoSyncInst(A, I, *this);
2281 };
2282
2283 bool UsedAssumedInformation = false;
2284 if (!A.checkForAllReadWriteInstructions(CheckForNoFree, *this,
2285 UsedAssumedInformation) ||
2286 !A.checkForAllCallLikeInstructions(CheckForNoFree, *this,
2287 UsedAssumedInformation))
2288 return indicatePessimisticFixpoint();
2289
2290 return ChangeStatus::UNCHANGED;
2291 }
2292
2293 /// See AbstractAttribute::getAsStr().
2294 const std::string getAsStr(Attributor *A) const override {
2295 return getAssumed() ? "nofree" : "may-free";
2296 }
2297};
2298
2299struct AANoFreeFunction final : public AANoFreeImpl {
2300 AANoFreeFunction(const IRPosition &IRP, Attributor &A)
2301 : AANoFreeImpl(IRP, A) {}
2302
2303 /// See AbstractAttribute::trackStatistics()
2304 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nofree) }
2305};
2306
2307/// NoFree attribute deduction for a call sites.
2308struct AANoFreeCallSite final : AACalleeToCallSite<AANoFree, AANoFreeImpl> {
2309 AANoFreeCallSite(const IRPosition &IRP, Attributor &A)
2310 : AACalleeToCallSite<AANoFree, AANoFreeImpl>(IRP, A) {}
2311
2312 /// See AbstractAttribute::trackStatistics()
2313 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nofree); }
2314};
2315
2316/// NoFree attribute for floating values.
2317struct AANoFreeFloating : AANoFreeImpl {
2318 AANoFreeFloating(const IRPosition &IRP, Attributor &A)
2319 : AANoFreeImpl(IRP, A) {}
2320
2321 /// See AbstractAttribute::trackStatistics()
2322 void trackStatistics() const override{STATS_DECLTRACK_FLOATING_ATTR(nofree)}
2323
2324 /// See Abstract Attribute::updateImpl(...).
2325 ChangeStatus updateImpl(Attributor &A) override {
2326 const IRPosition &IRP = getIRPosition();
2327
2328 bool IsKnown;
2331 DepClassTy::OPTIONAL, IsKnown))
2332 return ChangeStatus::UNCHANGED;
2333
2334 Value &AssociatedValue = getIRPosition().getAssociatedValue();
2335 auto Pred = [&](const Use &U, bool &Follow) -> bool {
2336 Instruction *UserI = cast<Instruction>(U.getUser());
2337 if (auto *CB = dyn_cast<CallBase>(UserI)) {
2338 if (CB->isBundleOperand(&U))
2339 return false;
2340 if (!CB->isArgOperand(&U))
2341 return true;
2342 unsigned ArgNo = CB->getArgOperandNo(&U);
2343
2344 // Even if the argument is nofree, we still need to check for nocapture,
2345 // as the call may capture the argument without freeing it, and the
2346 // captured argument is freed later.
2347 bool IsKnown;
2349 A, this, IRPosition::callsite_argument(*CB, ArgNo),
2350 DepClassTy::REQUIRED, IsKnown))
2351 return false;
2352
2353 const AANoCapture *NoCaptureAA = nullptr;
2355 A, this, IRPosition::callsite_argument(*CB, ArgNo),
2356 DepClassTy::REQUIRED, IsKnown,
2357 /*IgnoreSubsumingPositions=*/false, &NoCaptureAA)) {
2358 if (NoCaptureAA && NoCaptureAA->isAssumedNoCaptureMaybeReturned()) {
2359 Follow = true;
2360 return true;
2361 }
2362 return false;
2363 }
2364
2365 return true;
2366 }
2367
2368 UseCaptureInfo CI = DetermineUseCaptureKind(U, /*Base=*/nullptr);
2369 if (!capturesAnyProvenance(CI))
2370 return true;
2372 Follow = true;
2373 return true;
2374 }
2375
2376 if (isa<ReturnInst>(UserI) && getIRPosition().isArgumentPosition())
2377 return true;
2378
2379 // Capturing user.
2380 return false;
2381 };
2382 if (!A.checkForAllUses(Pred, *this, AssociatedValue))
2383 return indicatePessimisticFixpoint();
2384
2385 return ChangeStatus::UNCHANGED;
2386 }
2387};
2388
2389/// NoFree attribute for a call site argument.
2390struct AANoFreeArgument final : AANoFreeFloating {
2391 AANoFreeArgument(const IRPosition &IRP, Attributor &A)
2392 : AANoFreeFloating(IRP, A) {}
2393
2394 /// See AbstractAttribute::trackStatistics()
2395 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nofree) }
2396};
2397
2398/// NoFree attribute for call site arguments.
2399struct AANoFreeCallSiteArgument final : AANoFreeFloating {
2400 AANoFreeCallSiteArgument(const IRPosition &IRP, Attributor &A)
2401 : AANoFreeFloating(IRP, A) {}
2402
2403 /// See AbstractAttribute::updateImpl(...).
2404 ChangeStatus updateImpl(Attributor &A) override {
2405 // TODO: Once we have call site specific value information we can provide
2406 // call site specific liveness information and then it makes
2407 // sense to specialize attributes for call sites arguments instead of
2408 // redirecting requests to the callee argument.
2409 Argument *Arg = getAssociatedArgument();
2410 if (!Arg)
2411 return indicatePessimisticFixpoint();
2412 const IRPosition &ArgPos = IRPosition::argument(*Arg);
2413 bool IsKnown;
2415 DepClassTy::REQUIRED, IsKnown))
2416 return ChangeStatus::UNCHANGED;
2417 return indicatePessimisticFixpoint();
2418 }
2419
2420 /// See AbstractAttribute::trackStatistics()
2421 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(nofree) };
2422};
2423
2424/// NoFree attribute for function return value.
2425struct AANoFreeReturned final : AANoFreeFloating {
2426 AANoFreeReturned(const IRPosition &IRP, Attributor &A)
2427 : AANoFreeFloating(IRP, A) {
2428 llvm_unreachable("NoFree is not applicable to function returns!");
2429 }
2430
2431 /// See AbstractAttribute::initialize(...).
2432 void initialize(Attributor &A) override {
2433 llvm_unreachable("NoFree is not applicable to function returns!");
2434 }
2435
2436 /// See AbstractAttribute::updateImpl(...).
2437 ChangeStatus updateImpl(Attributor &A) override {
2438 llvm_unreachable("NoFree is not applicable to function returns!");
2439 }
2440
2441 /// See AbstractAttribute::trackStatistics()
2442 void trackStatistics() const override {}
2443};
2444
2445/// NoFree attribute deduction for a call site return value.
2446struct AANoFreeCallSiteReturned final : AANoFreeFloating {
2447 AANoFreeCallSiteReturned(const IRPosition &IRP, Attributor &A)
2448 : AANoFreeFloating(IRP, A) {}
2449
2450 ChangeStatus manifest(Attributor &A) override {
2451 return ChangeStatus::UNCHANGED;
2452 }
2453 /// See AbstractAttribute::trackStatistics()
2454 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(nofree) }
2455};
2456} // namespace
2457
2458/// ------------------------ NonNull Argument Attribute ------------------------
2459
2461 Attribute::AttrKind ImpliedAttributeKind,
2462 bool IgnoreSubsumingPositions) {
2464 AttrKinds.push_back(Attribute::NonNull);
2467 AttrKinds.push_back(Attribute::Dereferenceable);
2468 if (A.hasAttr(IRP, AttrKinds, IgnoreSubsumingPositions, Attribute::NonNull))
2469 return true;
2470
2471 DominatorTree *DT = nullptr;
2472 AssumptionCache *AC = nullptr;
2473 InformationCache &InfoCache = A.getInfoCache();
2474 if (const Function *Fn = IRP.getAnchorScope()) {
2475 if (!Fn->isDeclaration()) {
2478 }
2479 }
2480
2482 if (IRP.getPositionKind() != IRP_RETURNED) {
2483 Worklist.push_back({IRP.getAssociatedValue(), IRP.getCtxI()});
2484 } else {
2485 bool UsedAssumedInformation = false;
2486 if (!A.checkForAllInstructions(
2487 [&](Instruction &I) {
2488 Worklist.push_back({*cast<ReturnInst>(I).getReturnValue(), &I});
2489 return true;
2490 },
2491 IRP.getAssociatedFunction(), nullptr, {Instruction::Ret},
2492 UsedAssumedInformation, false, /*CheckPotentiallyDead=*/true))
2493 return false;
2494 }
2495
2496 if (llvm::any_of(Worklist, [&](AA::ValueAndContext VAC) {
2497 return !isKnownNonZero(
2498 VAC.getValue(),
2499 SimplifyQuery(A.getDataLayout(), DT, AC, VAC.getCtxI()));
2500 }))
2501 return false;
2502
2503 A.manifestAttrs(IRP, {Attribute::get(IRP.getAnchorValue().getContext(),
2504 Attribute::NonNull)});
2505 return true;
2506}
2507
2508namespace {
2509static int64_t getKnownNonNullAndDerefBytesForUse(
2510 Attributor &A, const AbstractAttribute &QueryingAA, Value &AssociatedValue,
2511 const Use *U, const Instruction *I, bool &IsNonNull, bool &TrackUse) {
2512 TrackUse = false;
2513
2514 const Value *UseV = U->get();
2515 if (!UseV->getType()->isPointerTy())
2516 return 0;
2517
2518 // We need to follow common pointer manipulation uses to the accesses they
2519 // feed into. We can try to be smart to avoid looking through things we do not
2520 // like for now, e.g., non-inbounds GEPs.
2521 if (isa<CastInst>(I)) {
2522 TrackUse = true;
2523 return 0;
2524 }
2525
2527 TrackUse = true;
2528 return 0;
2529 }
2530
2531 Type *PtrTy = UseV->getType();
2532 const Function *F = I->getFunction();
2535 const DataLayout &DL = A.getInfoCache().getDL();
2536 if (const auto *CB = dyn_cast<CallBase>(I)) {
2537 if (CB->isBundleOperand(U)) {
2538 if (RetainedKnowledge RK = getKnowledgeFromUse(
2539 U, {Attribute::NonNull, Attribute::Dereferenceable})) {
2540 IsNonNull |=
2541 (RK.AttrKind == Attribute::NonNull || !NullPointerIsDefined);
2542 return RK.ArgValue;
2543 }
2544 return 0;
2545 }
2546
2547 if (CB->isCallee(U)) {
2548 IsNonNull |= !NullPointerIsDefined;
2549 return 0;
2550 }
2551
2552 unsigned ArgNo = CB->getArgOperandNo(U);
2553 IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo);
2554 // As long as we only use known information there is no need to track
2555 // dependences here.
2556 bool IsKnownNonNull;
2558 DepClassTy::NONE, IsKnownNonNull);
2559 IsNonNull |= IsKnownNonNull;
2560 auto *DerefAA =
2561 A.getAAFor<AADereferenceable>(QueryingAA, IRP, DepClassTy::NONE);
2562 return DerefAA ? DerefAA->getKnownDereferenceableBytes() : 0;
2563 }
2564
2565 std::optional<MemoryLocation> Loc = MemoryLocation::getOrNone(I);
2566 if (!Loc || Loc->Ptr != UseV || !Loc->Size.isPrecise() ||
2567 Loc->Size.isScalable() || I->isVolatile())
2568 return 0;
2569
2570 int64_t Offset;
2571 const Value *Base =
2572 getMinimalBaseOfPointer(A, QueryingAA, Loc->Ptr, Offset, DL);
2573 if (Base && Base == &AssociatedValue) {
2574 int64_t DerefBytes = Loc->Size.getValue() + Offset;
2575 IsNonNull |= !NullPointerIsDefined;
2576 return std::max(int64_t(0), DerefBytes);
2577 }
2578
2579 /// Corner case when an offset is 0.
2581 /*AllowNonInbounds*/ true);
2582 if (Base && Base == &AssociatedValue && Offset == 0) {
2583 int64_t DerefBytes = Loc->Size.getValue();
2584 IsNonNull |= !NullPointerIsDefined;
2585 return std::max(int64_t(0), DerefBytes);
2586 }
2587
2588 return 0;
2589}
2590
2591struct AANonNullImpl : AANonNull {
2592 AANonNullImpl(const IRPosition &IRP, Attributor &A) : AANonNull(IRP, A) {}
2593
2594 /// See AbstractAttribute::initialize(...).
2595 void initialize(Attributor &A) override {
2596 Value &V = *getAssociatedValue().stripPointerCasts();
2597 if (isa<ConstantPointerNull>(V)) {
2598 indicatePessimisticFixpoint();
2599 return;
2600 }
2601
2602 if (Instruction *CtxI = getCtxI())
2603 followUsesInMBEC(*this, A, getState(), *CtxI);
2604 }
2605
2606 /// See followUsesInMBEC
2607 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
2608 AANonNull::StateType &State) {
2609 bool IsNonNull = false;
2610 bool TrackUse = false;
2611 getKnownNonNullAndDerefBytesForUse(A, *this, getAssociatedValue(), U, I,
2612 IsNonNull, TrackUse);
2613 State.setKnown(IsNonNull);
2614 return TrackUse;
2615 }
2616
2617 /// See AbstractAttribute::getAsStr().
2618 const std::string getAsStr(Attributor *A) const override {
2619 return getAssumed() ? "nonnull" : "may-null";
2620 }
2621};
2622
2623/// NonNull attribute for a floating value.
2624struct AANonNullFloating : public AANonNullImpl {
2625 AANonNullFloating(const IRPosition &IRP, Attributor &A)
2626 : AANonNullImpl(IRP, A) {}
2627
2628 /// See AbstractAttribute::updateImpl(...).
2629 ChangeStatus updateImpl(Attributor &A) override {
2630 auto CheckIRP = [&](const IRPosition &IRP) {
2631 bool IsKnownNonNull;
2633 A, *this, IRP, DepClassTy::OPTIONAL, IsKnownNonNull);
2634 };
2635
2636 bool Stripped;
2637 bool UsedAssumedInformation = false;
2638 Value *AssociatedValue = &getAssociatedValue();
2640 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
2641 AA::AnyScope, UsedAssumedInformation))
2642 Stripped = false;
2643 else
2644 Stripped =
2645 Values.size() != 1 || Values.front().getValue() != AssociatedValue;
2646
2647 if (!Stripped) {
2648 bool IsKnown;
2649 if (auto *PHI = dyn_cast<PHINode>(AssociatedValue))
2650 if (llvm::all_of(PHI->incoming_values(), [&](Value *Op) {
2651 return AA::hasAssumedIRAttr<Attribute::NonNull>(
2652 A, this, IRPosition::value(*Op), DepClassTy::OPTIONAL,
2653 IsKnown);
2654 }))
2655 return ChangeStatus::UNCHANGED;
2656 if (auto *Select = dyn_cast<SelectInst>(AssociatedValue))
2658 A, this, IRPosition::value(*Select->getFalseValue()),
2659 DepClassTy::OPTIONAL, IsKnown) &&
2661 A, this, IRPosition::value(*Select->getTrueValue()),
2662 DepClassTy::OPTIONAL, IsKnown))
2663 return ChangeStatus::UNCHANGED;
2664
2665 // If we haven't stripped anything we might still be able to use a
2666 // different AA, but only if the IRP changes. Effectively when we
2667 // interpret this not as a call site value but as a floating/argument
2668 // value.
2669 const IRPosition AVIRP = IRPosition::value(*AssociatedValue);
2670 if (AVIRP == getIRPosition() || !CheckIRP(AVIRP))
2671 return indicatePessimisticFixpoint();
2672 return ChangeStatus::UNCHANGED;
2673 }
2674
2675 for (const auto &VAC : Values)
2676 if (!CheckIRP(IRPosition::value(*VAC.getValue())))
2677 return indicatePessimisticFixpoint();
2678
2679 return ChangeStatus::UNCHANGED;
2680 }
2681
2682 /// See AbstractAttribute::trackStatistics()
2683 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
2684};
2685
2686/// NonNull attribute for function return value.
2687struct AANonNullReturned final
2688 : AAReturnedFromReturnedValues<AANonNull, AANonNull, AANonNull::StateType,
2689 false, AANonNull::IRAttributeKind, false> {
2690 AANonNullReturned(const IRPosition &IRP, Attributor &A)
2691 : AAReturnedFromReturnedValues<AANonNull, AANonNull, AANonNull::StateType,
2692 false, Attribute::NonNull, false>(IRP, A) {
2693 }
2694
2695 /// See AbstractAttribute::getAsStr().
2696 const std::string getAsStr(Attributor *A) const override {
2697 return getAssumed() ? "nonnull" : "may-null";
2698 }
2699
2700 /// See AbstractAttribute::trackStatistics()
2701 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
2702};
2703
2704/// NonNull attribute for function argument.
2705struct AANonNullArgument final
2706 : AAArgumentFromCallSiteArguments<AANonNull, AANonNullImpl> {
2707 AANonNullArgument(const IRPosition &IRP, Attributor &A)
2708 : AAArgumentFromCallSiteArguments<AANonNull, AANonNullImpl>(IRP, A) {}
2709
2710 /// See AbstractAttribute::trackStatistics()
2711 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nonnull) }
2712};
2713
2714struct AANonNullCallSiteArgument final : AANonNullFloating {
2715 AANonNullCallSiteArgument(const IRPosition &IRP, Attributor &A)
2716 : AANonNullFloating(IRP, A) {}
2717
2718 /// See AbstractAttribute::trackStatistics()
2719 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(nonnull) }
2720};
2721
2722/// NonNull attribute for a call site return position.
2723struct AANonNullCallSiteReturned final
2724 : AACalleeToCallSite<AANonNull, AANonNullImpl> {
2725 AANonNullCallSiteReturned(const IRPosition &IRP, Attributor &A)
2726 : AACalleeToCallSite<AANonNull, AANonNullImpl>(IRP, A) {}
2727
2728 /// See AbstractAttribute::trackStatistics()
2729 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(nonnull) }
2730};
2731} // namespace
2732
2733/// ------------------------ Must-Progress Attributes --------------------------
2734namespace {
2735struct AAMustProgressImpl : public AAMustProgress {
2736 AAMustProgressImpl(const IRPosition &IRP, Attributor &A)
2737 : AAMustProgress(IRP, A) {}
2738
2739 /// See AbstractAttribute::initialize(...).
2740 void initialize(Attributor &A) override {
2741 bool IsKnown;
2743 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
2744 (void)IsKnown;
2745 }
2746
2747 /// See AbstractAttribute::getAsStr()
2748 const std::string getAsStr(Attributor *A) const override {
2749 return getAssumed() ? "mustprogress" : "may-not-progress";
2750 }
2751};
2752
2753struct AAMustProgressFunction final : AAMustProgressImpl {
2754 AAMustProgressFunction(const IRPosition &IRP, Attributor &A)
2755 : AAMustProgressImpl(IRP, A) {}
2756
2757 /// See AbstractAttribute::updateImpl(...).
2758 ChangeStatus updateImpl(Attributor &A) override {
2759 bool IsKnown;
2761 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnown)) {
2762 if (IsKnown)
2763 return indicateOptimisticFixpoint();
2764 return ChangeStatus::UNCHANGED;
2765 }
2766
2767 auto CheckForMustProgress = [&](AbstractCallSite ACS) {
2768 IRPosition IPos = IRPosition::callsite_function(*ACS.getInstruction());
2769 bool IsKnownMustProgress;
2771 A, this, IPos, DepClassTy::REQUIRED, IsKnownMustProgress,
2772 /* IgnoreSubsumingPositions */ true);
2773 };
2774
2775 bool AllCallSitesKnown = true;
2776 if (!A.checkForAllCallSites(CheckForMustProgress, *this,
2777 /* RequireAllCallSites */ true,
2778 AllCallSitesKnown))
2779 return indicatePessimisticFixpoint();
2780
2781 return ChangeStatus::UNCHANGED;
2782 }
2783
2784 /// See AbstractAttribute::trackStatistics()
2785 void trackStatistics() const override {
2786 STATS_DECLTRACK_FN_ATTR(mustprogress)
2787 }
2788};
2789
2790/// MustProgress attribute deduction for a call sites.
2791struct AAMustProgressCallSite final : AAMustProgressImpl {
2792 AAMustProgressCallSite(const IRPosition &IRP, Attributor &A)
2793 : AAMustProgressImpl(IRP, A) {}
2794
2795 /// See AbstractAttribute::updateImpl(...).
2796 ChangeStatus updateImpl(Attributor &A) override {
2797 // TODO: Once we have call site specific value information we can provide
2798 // call site specific liveness information and then it makes
2799 // sense to specialize attributes for call sites arguments instead of
2800 // redirecting requests to the callee argument.
2801 const IRPosition &FnPos = IRPosition::function(*getAnchorScope());
2802 bool IsKnownMustProgress;
2804 A, this, FnPos, DepClassTy::REQUIRED, IsKnownMustProgress))
2805 return indicatePessimisticFixpoint();
2806 return ChangeStatus::UNCHANGED;
2807 }
2808
2809 /// See AbstractAttribute::trackStatistics()
2810 void trackStatistics() const override {
2811 STATS_DECLTRACK_CS_ATTR(mustprogress);
2812 }
2813};
2814} // namespace
2815
2816/// ------------------------ No-Recurse Attributes ----------------------------
2817
2818namespace {
2819struct AANoRecurseImpl : public AANoRecurse {
2820 AANoRecurseImpl(const IRPosition &IRP, Attributor &A) : AANoRecurse(IRP, A) {}
2821
2822 /// See AbstractAttribute::initialize(...).
2823 void initialize(Attributor &A) override {
2824 bool IsKnown;
2826 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
2827 (void)IsKnown;
2828 }
2829
2830 /// See AbstractAttribute::getAsStr()
2831 const std::string getAsStr(Attributor *A) const override {
2832 return getAssumed() ? "norecurse" : "may-recurse";
2833 }
2834};
2835
2836struct AANoRecurseFunction final : AANoRecurseImpl {
2837 AANoRecurseFunction(const IRPosition &IRP, Attributor &A)
2838 : AANoRecurseImpl(IRP, A) {}
2839
2840 /// See AbstractAttribute::updateImpl(...).
2841 ChangeStatus updateImpl(Attributor &A) override {
2842
2843 // If all live call sites are known to be no-recurse, we are as well.
2844 auto CallSitePred = [&](AbstractCallSite ACS) {
2845 bool IsKnownNoRecurse;
2847 A, this,
2848 IRPosition::function(*ACS.getInstruction()->getFunction()),
2849 DepClassTy::NONE, IsKnownNoRecurse))
2850 return false;
2851 return IsKnownNoRecurse;
2852 };
2853 bool UsedAssumedInformation = false;
2854 if (A.checkForAllCallSites(CallSitePred, *this, true,
2855 UsedAssumedInformation)) {
2856 // If we know all call sites and all are known no-recurse, we are done.
2857 // If all known call sites, which might not be all that exist, are known
2858 // to be no-recurse, we are not done but we can continue to assume
2859 // no-recurse. If one of the call sites we have not visited will become
2860 // live, another update is triggered.
2861 if (!UsedAssumedInformation)
2862 indicateOptimisticFixpoint();
2863 return ChangeStatus::UNCHANGED;
2864 }
2865
2866 const AAInterFnReachability *EdgeReachability =
2867 A.getAAFor<AAInterFnReachability>(*this, getIRPosition(),
2868 DepClassTy::REQUIRED);
2869 if (EdgeReachability && EdgeReachability->canReach(A, *getAnchorScope()))
2870 return indicatePessimisticFixpoint();
2871 return ChangeStatus::UNCHANGED;
2872 }
2873
2874 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(norecurse) }
2875};
2876
2877/// NoRecurse attribute deduction for a call sites.
2878struct AANoRecurseCallSite final
2879 : AACalleeToCallSite<AANoRecurse, AANoRecurseImpl> {
2880 AANoRecurseCallSite(const IRPosition &IRP, Attributor &A)
2881 : AACalleeToCallSite<AANoRecurse, AANoRecurseImpl>(IRP, A) {}
2882
2883 /// See AbstractAttribute::trackStatistics()
2884 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(norecurse); }
2885};
2886} // namespace
2887
2888/// ------------------------ No-Convergent Attribute --------------------------
2889
2890namespace {
2891struct AANonConvergentImpl : public AANonConvergent {
2892 AANonConvergentImpl(const IRPosition &IRP, Attributor &A)
2893 : AANonConvergent(IRP, A) {}
2894
2895 /// See AbstractAttribute::getAsStr()
2896 const std::string getAsStr(Attributor *A) const override {
2897 return getAssumed() ? "non-convergent" : "may-be-convergent";
2898 }
2899};
2900
2901struct AANonConvergentFunction final : AANonConvergentImpl {
2902 AANonConvergentFunction(const IRPosition &IRP, Attributor &A)
2903 : AANonConvergentImpl(IRP, A) {}
2904
2905 /// See AbstractAttribute::updateImpl(...).
2906 ChangeStatus updateImpl(Attributor &A) override {
2907 // If all function calls are known to not be convergent, we are not
2908 // convergent.
2909 auto CalleeIsNotConvergent = [&](Instruction &Inst) {
2910 CallBase &CB = cast<CallBase>(Inst);
2912 if (!Callee || Callee->isIntrinsic()) {
2913 return false;
2914 }
2915 if (Callee->isDeclaration()) {
2916 return !Callee->hasFnAttribute(Attribute::Convergent);
2917 }
2918 const auto *ConvergentAA = A.getAAFor<AANonConvergent>(
2919 *this, IRPosition::function(*Callee), DepClassTy::REQUIRED);
2920 return ConvergentAA && ConvergentAA->isAssumedNotConvergent();
2921 };
2922
2923 bool UsedAssumedInformation = false;
2924 if (!A.checkForAllCallLikeInstructions(CalleeIsNotConvergent, *this,
2925 UsedAssumedInformation)) {
2926 return indicatePessimisticFixpoint();
2927 }
2928 return ChangeStatus::UNCHANGED;
2929 }
2930
2931 ChangeStatus manifest(Attributor &A) override {
2932 if (isKnownNotConvergent() &&
2933 A.hasAttr(getIRPosition(), Attribute::Convergent)) {
2934 A.removeAttrs(getIRPosition(), {Attribute::Convergent});
2935 return ChangeStatus::CHANGED;
2936 }
2937 return ChangeStatus::UNCHANGED;
2938 }
2939
2940 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(convergent) }
2941};
2942} // namespace
2943
2944/// -------------------- Undefined-Behavior Attributes ------------------------
2945
2946namespace {
2947struct AAUndefinedBehaviorImpl : public AAUndefinedBehavior {
2948 AAUndefinedBehaviorImpl(const IRPosition &IRP, Attributor &A)
2949 : AAUndefinedBehavior(IRP, A) {}
2950
2951 struct UBInfo {
2952 enum Kind {
2953 NullPtrAccess,
2954 UndefPtrAccess,
2955 UndefBranchCondition,
2956 UndefReturnValue,
2957 NullReturnViolatesNonNull,
2958 UndefCallArgument,
2959 NullArgViolatesNonNull,
2960 };
2961
2962 Kind K;
2963 std::optional<unsigned> ArgNo;
2964
2965 UBInfo(Kind K) : K(K), ArgNo(std::nullopt) {}
2966
2967 UBInfo(Kind K, std::optional<unsigned> ArgNo) : K(K), ArgNo(ArgNo) {}
2968 };
2969
2970 /// See AbstractAttribute::updateImpl(...).
2971 // through a pointer (i.e. also branches etc.)
2972 ChangeStatus updateImpl(Attributor &A) override {
2973 const size_t UBPrevSize = KnownUBInsts.size();
2974 const size_t NoUBPrevSize = AssumedNoUBInsts.size();
2975
2976 auto InspectMemAccessInstForUB = [&](Instruction &I) {
2977 // Volatile accesses on null are not necessarily UB.
2978 if (I.isVolatile())
2979 return true;
2980
2981 // Skip instructions that are already saved.
2982 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
2983 return true;
2984
2985 // If we reach here, we know we have an instruction
2986 // that accesses memory through a pointer operand,
2987 // for which getPointerOperand() should give it to us.
2988 Value *PtrOp =
2989 const_cast<Value *>(getPointerOperand(&I, /* AllowVolatile */ true));
2990 assert(PtrOp &&
2991 "Expected pointer operand of memory accessing instruction");
2992
2993 // Either we stopped and the appropriate action was taken,
2994 // or we got back a simplified value to continue.
2995 std::optional<Value *> SimplifiedPtrOp =
2996 stopOnUndefOrAssumed(A, PtrOp, &I, UBInfo::UndefPtrAccess);
2997 if (!SimplifiedPtrOp || !*SimplifiedPtrOp)
2998 return true;
2999 const Value *PtrOpVal = *SimplifiedPtrOp;
3000
3001 // A memory access through a pointer is considered UB
3002 // only if the pointer has constant null value.
3003 // TODO: Expand it to not only check constant values.
3004 if (!isa<ConstantPointerNull>(PtrOpVal)) {
3005 AssumedNoUBInsts.insert(&I);
3006 return true;
3007 }
3008 const Type *PtrTy = PtrOpVal->getType();
3009
3010 // Because we only consider instructions inside functions,
3011 // assume that a parent function exists.
3012 const Function *F = I.getFunction();
3013
3014 // A memory access using constant null pointer is only considered UB
3015 // if null pointer is _not_ defined for the target platform.
3017 AssumedNoUBInsts.insert(&I);
3018 else
3019 KnownUBInsts.try_emplace(&I, UBInfo::NullPtrAccess);
3020 return true;
3021 };
3022
3023 auto InspectBrInstForUB = [&](Instruction &I) {
3024 // A conditional branch instruction is considered UB if it has `undef`
3025 // condition.
3026
3027 // Skip instructions that are already saved.
3028 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
3029 return true;
3030
3031 // We know we have a branch instruction.
3032 auto *BrInst = cast<CondBrInst>(&I);
3033
3034 // Either we stopped and the appropriate action was taken,
3035 // or we got back a simplified value to continue.
3036 std::optional<Value *> SimplifiedCond = stopOnUndefOrAssumed(
3037 A, BrInst->getCondition(), BrInst, UBInfo::UndefBranchCondition);
3038 if (!SimplifiedCond || !*SimplifiedCond)
3039 return true;
3040 AssumedNoUBInsts.insert(&I);
3041 return true;
3042 };
3043
3044 auto InspectCallSiteForUB = [&](Instruction &I) {
3045 // Check whether a callsite always cause UB or not
3046
3047 // Skip instructions that are already saved.
3048 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
3049 return true;
3050
3051 // Check nonnull and noundef argument attribute violation for each
3052 // callsite.
3053 CallBase &CB = cast<CallBase>(I);
3055 if (!Callee)
3056 return true;
3057 for (unsigned idx = 0; idx < CB.arg_size(); idx++) {
3058 // If current argument is known to be simplified to null pointer and the
3059 // corresponding argument position is known to have nonnull attribute,
3060 // the argument is poison. Furthermore, if the argument is poison and
3061 // the position is known to have noundef attriubte, this callsite is
3062 // considered UB.
3063 if (idx >= Callee->arg_size())
3064 break;
3065 Value *ArgVal = CB.getArgOperand(idx);
3066 if (!ArgVal)
3067 continue;
3068 // Here, we handle three cases.
3069 // (1) Not having a value means it is dead. (we can replace the value
3070 // with undef)
3071 // (2) Simplified to undef. The argument violate noundef attriubte.
3072 // (3) Simplified to null pointer where known to be nonnull.
3073 // The argument is a poison value and violate noundef attribute.
3074 IRPosition CalleeArgumentIRP = IRPosition::callsite_argument(CB, idx);
3075 bool IsKnownNoUndef;
3077 A, this, CalleeArgumentIRP, DepClassTy::NONE, IsKnownNoUndef);
3078 if (!IsKnownNoUndef)
3079 continue;
3080 bool UsedAssumedInformation = false;
3081 std::optional<Value *> SimplifiedVal =
3082 A.getAssumedSimplified(IRPosition::value(*ArgVal), *this,
3083 UsedAssumedInformation, AA::Interprocedural);
3084 if (UsedAssumedInformation)
3085 continue;
3086 if (SimplifiedVal && !*SimplifiedVal)
3087 return true;
3088 if (!SimplifiedVal || isa<UndefValue>(**SimplifiedVal)) {
3089 KnownUBInsts.try_emplace(&I, UBInfo(UBInfo::UndefCallArgument, idx));
3090 continue;
3091 }
3092 if (!ArgVal->getType()->isPointerTy() ||
3093 !isa<ConstantPointerNull>(**SimplifiedVal))
3094 continue;
3095 bool IsKnownNonNull;
3097 A, this, CalleeArgumentIRP, DepClassTy::NONE, IsKnownNonNull);
3098 if (IsKnownNonNull)
3099 KnownUBInsts.try_emplace(&I,
3100 UBInfo(UBInfo::NullArgViolatesNonNull, idx));
3101 }
3102 return true;
3103 };
3104
3105 auto InspectReturnInstForUB = [&](Instruction &I) {
3106 auto &RI = cast<ReturnInst>(I);
3107 // Either we stopped and the appropriate action was taken,
3108 // or we got back a simplified return value to continue.
3109 std::optional<Value *> SimplifiedRetValue = stopOnUndefOrAssumed(
3110 A, RI.getReturnValue(), &I, UBInfo::UndefReturnValue);
3111 if (!SimplifiedRetValue || !*SimplifiedRetValue)
3112 return true;
3113
3114 // Check if a return instruction always cause UB or not
3115 // Note: It is guaranteed that the returned position of the anchor
3116 // scope has noundef attribute when this is called.
3117 // We also ensure the return position is not "assumed dead"
3118 // because the returned value was then potentially simplified to
3119 // `undef` in AAReturnedValues without removing the `noundef`
3120 // attribute yet.
3121
3122 // When the returned position has noundef attriubte, UB occurs in the
3123 // following cases.
3124 // (1) Returned value is known to be undef.
3125 // (2) The value is known to be a null pointer and the returned
3126 // position has nonnull attribute (because the returned value is
3127 // poison).
3128 if (isa<ConstantPointerNull>(*SimplifiedRetValue)) {
3129 bool IsKnownNonNull;
3131 A, this, IRPosition::returned(*getAnchorScope()), DepClassTy::NONE,
3132 IsKnownNonNull);
3133 if (IsKnownNonNull)
3134 KnownUBInsts.try_emplace(&I, UBInfo::NullReturnViolatesNonNull);
3135 }
3136
3137 return true;
3138 };
3139
3140 bool UsedAssumedInformation = false;
3141 A.checkForAllInstructions(InspectMemAccessInstForUB, *this,
3142 {Instruction::Load, Instruction::Store,
3143 Instruction::AtomicCmpXchg,
3144 Instruction::AtomicRMW},
3145 UsedAssumedInformation,
3146 /* CheckBBLivenessOnly */ true);
3147 A.checkForAllInstructions(InspectBrInstForUB, *this, {Instruction::CondBr},
3148 UsedAssumedInformation,
3149 /* CheckBBLivenessOnly */ true);
3150 A.checkForAllCallLikeInstructions(InspectCallSiteForUB, *this,
3151 UsedAssumedInformation);
3152
3153 // If the returned position of the anchor scope has noundef attriubte, check
3154 // all returned instructions.
3155 if (!getAnchorScope()->getReturnType()->isVoidTy()) {
3156 const IRPosition &ReturnIRP = IRPosition::returned(*getAnchorScope());
3157 if (!A.isAssumedDead(ReturnIRP, this, nullptr, UsedAssumedInformation)) {
3158 bool IsKnownNoUndef;
3160 A, this, ReturnIRP, DepClassTy::NONE, IsKnownNoUndef);
3161 if (IsKnownNoUndef)
3162 A.checkForAllInstructions(InspectReturnInstForUB, *this,
3163 {Instruction::Ret}, UsedAssumedInformation,
3164 /* CheckBBLivenessOnly */ true);
3165 }
3166 }
3167
3168 if (NoUBPrevSize != AssumedNoUBInsts.size() ||
3169 UBPrevSize != KnownUBInsts.size())
3170 return ChangeStatus::CHANGED;
3171 return ChangeStatus::UNCHANGED;
3172 }
3173
3174 bool isKnownToCauseUB(Instruction *I) const override {
3175 return KnownUBInsts.count(I);
3176 }
3177
3178 bool isAssumedToCauseUB(Instruction *I) const override {
3179 // In simple words, if an instruction is not in the assumed to _not_
3180 // cause UB, then it is assumed UB (that includes those
3181 // in the KnownUBInsts set). The rest is boilerplate
3182 // is to ensure that it is one of the instructions we test
3183 // for UB.
3184
3185 switch (I->getOpcode()) {
3186 case Instruction::Load:
3187 case Instruction::Store:
3188 case Instruction::AtomicCmpXchg:
3189 case Instruction::AtomicRMW:
3190 case Instruction::CondBr:
3191 return !AssumedNoUBInsts.count(I);
3192 default:
3193 return false;
3194 }
3195 return false;
3196 }
3197
3198 /// Emit an optimization remark explaining why \p I is known to cause UB,
3199 /// per \p Info, right before it is replaced with 'unreachable'.
3200 static void emitUBRemark(Attributor &A, Instruction *I, const UBInfo &Info) {
3201 auto Remark = [&](OptimizationRemark OR) {
3202 switch (Info.K) {
3203 case UBInfo::NullPtrAccess:
3204 case UBInfo::UndefPtrAccess: {
3205 return OR << "Memory access through a pointer known to be "
3206 << ore::NV("Pointer",
3207 getPointerOperand(I, /*AllowVolatile*/ true))
3208 << " is undefined behavior; replacing with 'unreachable'.";
3209 }
3210 case UBInfo::UndefBranchCondition:
3211 return OR << "Branch condition known to be "
3212 << ore::NV("Condition", cast<CondBrInst>(I)->getCondition())
3213 << " is undefined behavior; replacing with 'unreachable'.";
3214 case UBInfo::UndefReturnValue:
3215 case UBInfo::NullReturnViolatesNonNull:
3216 return OR << "Value returned known to be "
3217 << ore::NV("ReturnValue",
3218 cast<ReturnInst>(I)->getReturnValue())
3219 << " is undefined behavior; replacing with 'unreachable'.";
3220 case UBInfo::UndefCallArgument:
3221 case UBInfo::NullArgViolatesNonNull: {
3222 bool IsUndef = Info.K == UBInfo::UndefCallArgument;
3223 CallBase &CB = *cast<CallBase>(I);
3224 OR << "Argument " << ore::NV("ArgNo", *Info.ArgNo)
3225 << " passed to parameter of ";
3226 if (auto *Callee = dyn_cast_if_present<Function>(CB.getCalledOperand()))
3227 OR << ore::NV("Callee", Callee);
3228 else
3229 OR << "the callee";
3230 return OR << " known to be "
3231 << ore::NV("Argument", IsUndef ? "undef" : "null")
3232 << " is undefined behavior; replacing with 'unreachable'.";
3233 }
3234 }
3235 llvm_unreachable("Unknown UBInfo::Kind");
3236 };
3237 A.emitRemark<OptimizationRemark>(I, "UndefinedBehavior", Remark);
3238 }
3239
3240 ChangeStatus manifest(Attributor &A) override {
3241 if (KnownUBInsts.empty())
3242 return ChangeStatus::UNCHANGED;
3243 for (const auto &[I, Info] : KnownUBInsts) {
3244 emitUBRemark(A, I, Info);
3245 A.changeToUnreachableAfterManifest(I);
3246 }
3247 return ChangeStatus::CHANGED;
3248 }
3249
3250 /// See AbstractAttribute::getAsStr()
3251 const std::string getAsStr(Attributor *A) const override {
3252 return getAssumed() ? "undefined-behavior" : "no-ub";
3253 }
3254
3255 /// Note: The correctness of this analysis depends on the fact that the
3256 /// following 2 sets will stop changing after some point.
3257 /// "Change" here means that their size changes.
3258 /// The size of each set is monotonically increasing
3259 /// (we only add items to them) and it is upper bounded by the number of
3260 /// instructions in the processed function (we can never save more
3261 /// elements in either set than this number). Hence, at some point,
3262 /// they will stop increasing.
3263 /// Consequently, at some point, both sets will have stopped
3264 /// changing, effectively making the analysis reach a fixpoint.
3265
3266 /// Note: These 2 sets are disjoint and an instruction can be considered
3267 /// one of 3 things:
3268 /// 1) Known to cause UB (AAUndefinedBehavior could prove it) and put it in
3269 /// the KnownUBInsts set.
3270 /// 2) Assumed to cause UB (in every updateImpl, AAUndefinedBehavior
3271 /// has a reason to assume it).
3272 /// 3) Assumed to not cause UB. very other instruction - AAUndefinedBehavior
3273 /// could not find a reason to assume or prove that it can cause UB,
3274 /// hence it assumes it doesn't. We have a set for these instructions
3275 /// so that we don't reprocess them in every update.
3276 /// Note however that instructions in this set may cause UB.
3277
3278protected:
3279 /// A map from all live instructions _known_ to cause UB to the reason why,
3280 /// used to build actionable optimization remarks in manifest().
3281 MapVector<Instruction *, UBInfo> KnownUBInsts;
3282
3283private:
3284 /// A set of all the (live) instructions that are assumed to _not_ cause UB.
3285 SmallPtrSet<Instruction *, 8> AssumedNoUBInsts;
3286
3287 // Should be called on updates in which if we're processing an instruction
3288 // \p I that depends on a value \p V, one of the following has to happen:
3289 // - If the value is assumed, then stop.
3290 // - If the value is known but undef, then consider it UB for \p K.
3291 // - Otherwise, do specific processing with the simplified value.
3292 // We return std::nullopt in the first 2 cases to signify that an appropriate
3293 // action was taken and the caller should stop.
3294 // Otherwise, we return the simplified value that the caller should
3295 // use for specific processing.
3296 std::optional<Value *> stopOnUndefOrAssumed(Attributor &A, Value *V,
3297 Instruction *I, UBInfo::Kind K) {
3298 bool UsedAssumedInformation = false;
3299 std::optional<Value *> SimplifiedV =
3300 A.getAssumedSimplified(IRPosition::value(*V), *this,
3301 UsedAssumedInformation, AA::Interprocedural);
3302 if (!UsedAssumedInformation) {
3303 // Don't depend on assumed values.
3304 if (!SimplifiedV) {
3305 // If it is known (which we tested above) but it doesn't have a value,
3306 // then we can assume `undef` and hence the instruction is UB.
3307 KnownUBInsts.try_emplace(I, K);
3308 return std::nullopt;
3309 }
3310 if (!*SimplifiedV)
3311 return nullptr;
3312 V = *SimplifiedV;
3313 }
3314 if (isa<UndefValue>(V)) {
3315 KnownUBInsts.try_emplace(I, K);
3316 return std::nullopt;
3317 }
3318 return V;
3319 }
3320};
3321
3322struct AAUndefinedBehaviorFunction final : AAUndefinedBehaviorImpl {
3323 AAUndefinedBehaviorFunction(const IRPosition &IRP, Attributor &A)
3324 : AAUndefinedBehaviorImpl(IRP, A) {}
3325
3326 /// See AbstractAttribute::trackStatistics()
3327 void trackStatistics() const override {
3328 STATS_DECL(UndefinedBehaviorInstruction, Instruction,
3329 "Number of instructions known to have UB");
3330 BUILD_STAT_NAME(UndefinedBehaviorInstruction, Instruction) +=
3331 KnownUBInsts.size();
3332 }
3333};
3334} // namespace
3335
3336/// ------------------------ Will-Return Attributes ----------------------------
3337
3338namespace {
3339// Helper function that checks whether a function has any cycle which we don't
3340// know if it is bounded or not.
3341// Loops with maximum trip count are considered bounded, any other cycle not.
3342static bool mayContainUnboundedCycle(Function &F, Attributor &A) {
3343 ScalarEvolution *SE =
3344 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(F);
3345 LoopInfo *LI = A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(F);
3346 // If either SCEV or LoopInfo is not available for the function then we assume
3347 // any cycle to be unbounded cycle.
3348 // We use scc_iterator which uses Tarjan algorithm to find all the maximal
3349 // SCCs.To detect if there's a cycle, we only need to find the maximal ones.
3350 if (!SE || !LI) {
3351 for (scc_iterator<Function *> SCCI = scc_begin(&F); !SCCI.isAtEnd(); ++SCCI)
3352 if (SCCI.hasCycle())
3353 return true;
3354 return false;
3355 }
3356
3357 // If there's irreducible control, the function may contain non-loop cycles.
3359 return true;
3360
3361 // Any loop that does not have a max trip count is considered unbounded cycle.
3362 for (auto *L : LI->getLoopsInPreorder()) {
3363 if (!SE->getSmallConstantMaxTripCount(L))
3364 return true;
3365 }
3366 return false;
3367}
3368
3369struct AAWillReturnImpl : public AAWillReturn {
3370 AAWillReturnImpl(const IRPosition &IRP, Attributor &A)
3371 : AAWillReturn(IRP, A) {}
3372
3373 /// See AbstractAttribute::initialize(...).
3374 void initialize(Attributor &A) override {
3375 bool IsKnown;
3377 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
3378 (void)IsKnown;
3379 }
3380
3381 /// Check for `mustprogress` and `readonly` as they imply `willreturn`.
3382 bool isImpliedByMustprogressAndReadonly(Attributor &A, bool KnownOnly) {
3383 if (!A.hasAttr(getIRPosition(), {Attribute::MustProgress}))
3384 return false;
3385
3386 bool IsKnown;
3387 if (AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown))
3388 return IsKnown || !KnownOnly;
3389 return false;
3390 }
3391
3392 /// See AbstractAttribute::updateImpl(...).
3393 ChangeStatus updateImpl(Attributor &A) override {
3394 if (isImpliedByMustprogressAndReadonly(A, /* KnownOnly */ false))
3395 return ChangeStatus::UNCHANGED;
3396
3397 auto CheckForWillReturn = [&](Instruction &I) {
3399 bool IsKnown;
3401 A, this, IPos, DepClassTy::REQUIRED, IsKnown)) {
3402 if (IsKnown)
3403 return true;
3404 } else {
3405 return false;
3406 }
3407 bool IsKnownNoRecurse;
3409 A, this, IPos, DepClassTy::REQUIRED, IsKnownNoRecurse);
3410 };
3411
3412 bool UsedAssumedInformation = false;
3413 if (!A.checkForAllCallLikeInstructions(CheckForWillReturn, *this,
3414 UsedAssumedInformation))
3415 return indicatePessimisticFixpoint();
3416
3417 auto CheckForVolatile = [&](Instruction &I) {
3418 // Volatile operations are not willreturn.
3419 return !I.isVolatile();
3420 };
3421 if (!A.checkForAllInstructions(CheckForVolatile, *this,
3422 {Instruction::Load, Instruction::Store,
3423 Instruction::AtomicCmpXchg,
3424 Instruction::AtomicRMW},
3425 UsedAssumedInformation))
3426 return indicatePessimisticFixpoint();
3427
3428 return ChangeStatus::UNCHANGED;
3429 }
3430
3431 /// See AbstractAttribute::getAsStr()
3432 const std::string getAsStr(Attributor *A) const override {
3433 return getAssumed() ? "willreturn" : "may-noreturn";
3434 }
3435};
3436
3437struct AAWillReturnFunction final : AAWillReturnImpl {
3438 AAWillReturnFunction(const IRPosition &IRP, Attributor &A)
3439 : AAWillReturnImpl(IRP, A) {}
3440
3441 /// See AbstractAttribute::initialize(...).
3442 void initialize(Attributor &A) override {
3443 AAWillReturnImpl::initialize(A);
3444
3445 Function *F = getAnchorScope();
3446 assert(F && "Did expect an anchor function");
3447 if (F->isDeclaration() || mayContainUnboundedCycle(*F, A))
3448 indicatePessimisticFixpoint();
3449 }
3450
3451 /// See AbstractAttribute::trackStatistics()
3452 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(willreturn) }
3453};
3454
3455/// WillReturn attribute deduction for a call sites.
3456struct AAWillReturnCallSite final
3457 : AACalleeToCallSite<AAWillReturn, AAWillReturnImpl> {
3458 AAWillReturnCallSite(const IRPosition &IRP, Attributor &A)
3459 : AACalleeToCallSite<AAWillReturn, AAWillReturnImpl>(IRP, A) {}
3460
3461 /// See AbstractAttribute::updateImpl(...).
3462 ChangeStatus updateImpl(Attributor &A) override {
3463 if (isImpliedByMustprogressAndReadonly(A, /* KnownOnly */ false))
3464 return ChangeStatus::UNCHANGED;
3465
3466 return AACalleeToCallSite::updateImpl(A);
3467 }
3468
3469 /// See AbstractAttribute::trackStatistics()
3470 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(willreturn); }
3471};
3472} // namespace
3473
3474/// -------------------AAIntraFnReachability Attribute--------------------------
3475
3476/// All information associated with a reachability query. This boilerplate code
3477/// is used by both AAIntraFnReachability and AAInterFnReachability, with
3478/// different \p ToTy values.
3479template <typename ToTy> struct ReachabilityQueryInfo {
3480 enum class Reachable {
3483 };
3484
3485 /// Start here,
3486 const Instruction *From = nullptr;
3487 /// reach this place,
3488 const ToTy *To = nullptr;
3489 /// without going through any of these instructions,
3491 /// and remember if it worked:
3493
3494 /// Precomputed hash for this RQI.
3495 unsigned Hash = 0;
3496
3497 unsigned computeHashValue() const {
3498 assert(Hash == 0 && "Computed hash twice!");
3501 return const_cast<ReachabilityQueryInfo<ToTy> *>(this)->Hash =
3502 detail::combineHashValue(PairDMI ::getHashValue({From, To}),
3503 InstSetDMI::getHashValue(ExclusionSet));
3504 }
3505
3507 : From(From), To(To) {}
3508
3509 /// Constructor replacement to ensure unique and stable sets are used for the
3510 /// cache.
3512 const AA::InstExclusionSetTy *ES, bool MakeUnique)
3513 : From(&From), To(&To), ExclusionSet(ES) {
3514
3515 if (!ES || ES->empty()) {
3516 ExclusionSet = nullptr;
3517 } else if (MakeUnique) {
3518 ExclusionSet = A.getInfoCache().getOrCreateUniqueBlockExecutionSet(ES);
3519 }
3520 }
3521
3524};
3525
3526namespace llvm {
3527template <typename ToTy> struct DenseMapInfo<ReachabilityQueryInfo<ToTy> *> {
3530
3531 static unsigned getHashValue(const ReachabilityQueryInfo<ToTy> *RQI) {
3532 return RQI->Hash ? RQI->Hash : RQI->computeHashValue();
3533 }
3534 static bool isEqual(const ReachabilityQueryInfo<ToTy> *LHS,
3535 const ReachabilityQueryInfo<ToTy> *RHS) {
3536 if (!PairDMI::isEqual({LHS->From, LHS->To}, {RHS->From, RHS->To}))
3537 return false;
3538 return InstSetDMI::isEqual(LHS->ExclusionSet, RHS->ExclusionSet);
3539 }
3540};
3541
3542} // namespace llvm
3543
3544namespace {
3545
3546template <typename BaseTy, typename ToTy>
3547struct CachedReachabilityAA : public BaseTy {
3548 using RQITy = ReachabilityQueryInfo<ToTy>;
3549
3550 CachedReachabilityAA(const IRPosition &IRP, Attributor &A) : BaseTy(IRP, A) {}
3551
3552 /// See AbstractAttribute::isQueryAA.
3553 bool isQueryAA() const override { return true; }
3554
3555 /// See AbstractAttribute::updateImpl(...).
3556 ChangeStatus updateImpl(Attributor &A) override {
3557 ChangeStatus Changed = ChangeStatus::UNCHANGED;
3558 for (unsigned u = 0, e = QueryVector.size(); u < e; ++u) {
3559 RQITy *RQI = QueryVector[u];
3560 if (RQI->Result == RQITy::Reachable::No &&
3561 isReachableImpl(A, *RQI, /*IsTemporaryRQI=*/false))
3562 Changed = ChangeStatus::CHANGED;
3563 }
3564 return Changed;
3565 }
3566
3567 virtual bool isReachableImpl(Attributor &A, RQITy &RQI,
3568 bool IsTemporaryRQI) = 0;
3569
3570 bool rememberResult(Attributor &A, typename RQITy::Reachable Result,
3571 RQITy &RQI, bool UsedExclusionSet, bool IsTemporaryRQI) {
3572 RQI.Result = Result;
3573
3574 // Remove the temporary RQI from the cache.
3575 if (IsTemporaryRQI)
3576 QueryCache.erase(&RQI);
3577
3578 // Insert a plain RQI (w/o exclusion set) if that makes sense. Two options:
3579 // 1) If it is reachable, it doesn't matter if we have an exclusion set for
3580 // this query. 2) We did not use the exclusion set, potentially because
3581 // there is none.
3582 if (Result == RQITy::Reachable::Yes || !UsedExclusionSet) {
3583 RQITy PlainRQI(RQI.From, RQI.To);
3584 if (!QueryCache.count(&PlainRQI)) {
3585 RQITy *RQIPtr = new (A.Allocator) RQITy(RQI.From, RQI.To);
3586 RQIPtr->Result = Result;
3587 QueryVector.push_back(RQIPtr);
3588 QueryCache.insert(RQIPtr);
3589 }
3590 }
3591
3592 // Check if we need to insert a new permanent RQI with the exclusion set.
3593 if (IsTemporaryRQI && Result != RQITy::Reachable::Yes && UsedExclusionSet) {
3594 assert((!RQI.ExclusionSet || !RQI.ExclusionSet->empty()) &&
3595 "Did not expect empty set!");
3596 RQITy *RQIPtr = new (A.Allocator)
3597 RQITy(A, *RQI.From, *RQI.To, RQI.ExclusionSet, true);
3598 assert(RQIPtr->Result == RQITy::Reachable::No && "Already reachable?");
3599 RQIPtr->Result = Result;
3600 assert(!QueryCache.count(RQIPtr));
3601 QueryVector.push_back(RQIPtr);
3602 QueryCache.insert(RQIPtr);
3603 }
3604
3605 if (Result == RQITy::Reachable::No && IsTemporaryRQI)
3606 A.registerForUpdate(*this);
3607 return Result == RQITy::Reachable::Yes;
3608 }
3609
3610 const std::string getAsStr(Attributor *A) const override {
3611 // TODO: Return the number of reachable queries.
3612 return "#queries(" + std::to_string(QueryVector.size()) + ")";
3613 }
3614
3615 bool checkQueryCache(Attributor &A, RQITy &StackRQI,
3616 typename RQITy::Reachable &Result) {
3617 if (!this->getState().isValidState()) {
3618 Result = RQITy::Reachable::Yes;
3619 return true;
3620 }
3621
3622 // If we have an exclusion set we might be able to find our answer by
3623 // ignoring it first.
3624 if (StackRQI.ExclusionSet) {
3625 RQITy PlainRQI(StackRQI.From, StackRQI.To);
3626 auto It = QueryCache.find(&PlainRQI);
3627 if (It != QueryCache.end() && (*It)->Result == RQITy::Reachable::No) {
3628 Result = RQITy::Reachable::No;
3629 return true;
3630 }
3631 }
3632
3633 auto It = QueryCache.find(&StackRQI);
3634 if (It != QueryCache.end()) {
3635 Result = (*It)->Result;
3636 return true;
3637 }
3638
3639 // Insert a temporary for recursive queries. We will replace it with a
3640 // permanent entry later.
3641 QueryCache.insert(&StackRQI);
3642 return false;
3643 }
3644
3645private:
3646 SmallVector<RQITy *> QueryVector;
3647 DenseSet<RQITy *> QueryCache;
3648};
3649
3650struct AAIntraFnReachabilityFunction final
3651 : public CachedReachabilityAA<AAIntraFnReachability, Instruction> {
3652 using Base = CachedReachabilityAA<AAIntraFnReachability, Instruction>;
3653 AAIntraFnReachabilityFunction(const IRPosition &IRP, Attributor &A)
3654 : Base(IRP, A) {
3655 DT = A.getInfoCache().getAnalysisResultForFunction<DominatorTreeAnalysis>(
3656 *IRP.getAssociatedFunction());
3657 }
3658
3659 bool isAssumedReachable(
3660 Attributor &A, const Instruction &From, const Instruction &To,
3661 const AA::InstExclusionSetTy *ExclusionSet) const override {
3662 auto *NonConstThis = const_cast<AAIntraFnReachabilityFunction *>(this);
3663 if (&From == &To)
3664 return true;
3665
3666 RQITy StackRQI(A, From, To, ExclusionSet, false);
3667 RQITy::Reachable Result;
3668 if (!NonConstThis->checkQueryCache(A, StackRQI, Result))
3669 return NonConstThis->isReachableImpl(A, StackRQI,
3670 /*IsTemporaryRQI=*/true);
3671 return Result == RQITy::Reachable::Yes;
3672 }
3673
3674 ChangeStatus updateImpl(Attributor &A) override {
3675 // We only depend on liveness. DeadEdges is all we care about, check if any
3676 // of them changed.
3677 auto *LivenessAA =
3678 A.getAAFor<AAIsDead>(*this, getIRPosition(), DepClassTy::OPTIONAL);
3679 if (LivenessAA &&
3680 llvm::all_of(DeadEdges,
3681 [&](const auto &DeadEdge) {
3682 return LivenessAA->isEdgeDead(DeadEdge.first,
3683 DeadEdge.second);
3684 }) &&
3685 llvm::all_of(DeadBlocks, [&](const BasicBlock *BB) {
3686 return LivenessAA->isAssumedDead(BB);
3687 })) {
3688 return ChangeStatus::UNCHANGED;
3689 }
3690 DeadEdges.clear();
3691 DeadBlocks.clear();
3692 return Base::updateImpl(A);
3693 }
3694
3695 bool isReachableImpl(Attributor &A, RQITy &RQI,
3696 bool IsTemporaryRQI) override {
3697 const Instruction *Origin = RQI.From;
3698 bool UsedExclusionSet = false;
3699
3700 auto WillReachInBlock = [&](const Instruction &From, const Instruction &To,
3701 const AA::InstExclusionSetTy *ExclusionSet) {
3702 const Instruction *IP = &From;
3703 while (IP && IP != &To) {
3704 if (ExclusionSet && IP != Origin && ExclusionSet->count(IP)) {
3705 UsedExclusionSet = true;
3706 break;
3707 }
3708 IP = IP->getNextNode();
3709 }
3710 return IP == &To;
3711 };
3712
3713 const BasicBlock *FromBB = RQI.From->getParent();
3714 const BasicBlock *ToBB = RQI.To->getParent();
3715 assert(FromBB->getParent() == ToBB->getParent() &&
3716 "Not an intra-procedural query!");
3717
3718 // Check intra-block reachability, however, other reaching paths are still
3719 // possible.
3720 if (FromBB == ToBB &&
3721 WillReachInBlock(*RQI.From, *RQI.To, RQI.ExclusionSet))
3722 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
3723 IsTemporaryRQI);
3724
3725 // Check if reaching the ToBB block is sufficient or if even that would not
3726 // ensure reaching the target. In the latter case we are done.
3727 if (!WillReachInBlock(ToBB->front(), *RQI.To, RQI.ExclusionSet))
3728 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
3729 IsTemporaryRQI);
3730
3731 const Function *Fn = FromBB->getParent();
3732 SmallPtrSet<const BasicBlock *, 16> ExclusionBlocks;
3733 if (RQI.ExclusionSet)
3734 for (auto *I : *RQI.ExclusionSet)
3735 if (I->getFunction() == Fn)
3736 ExclusionBlocks.insert(I->getParent());
3737
3738 // Check if we make it out of the FromBB block at all.
3739 if (ExclusionBlocks.count(FromBB) &&
3740 !WillReachInBlock(*RQI.From, *FromBB->getTerminator(),
3741 RQI.ExclusionSet))
3742 return rememberResult(A, RQITy::Reachable::No, RQI, true, IsTemporaryRQI);
3743
3744 auto *LivenessAA =
3745 A.getAAFor<AAIsDead>(*this, getIRPosition(), DepClassTy::OPTIONAL);
3746 if (LivenessAA && LivenessAA->isAssumedDead(ToBB)) {
3747 DeadBlocks.insert(ToBB);
3748 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
3749 IsTemporaryRQI);
3750 }
3751
3752 SmallPtrSet<const BasicBlock *, 16> Visited;
3754 Worklist.push_back(FromBB);
3755
3756 DenseSet<std::pair<const BasicBlock *, const BasicBlock *>> LocalDeadEdges;
3757 while (!Worklist.empty()) {
3758 const BasicBlock *BB = Worklist.pop_back_val();
3759 if (!Visited.insert(BB).second)
3760 continue;
3761 for (const BasicBlock *SuccBB : successors(BB)) {
3762 if (LivenessAA && LivenessAA->isEdgeDead(BB, SuccBB)) {
3763 LocalDeadEdges.insert({BB, SuccBB});
3764 continue;
3765 }
3766 // We checked before if we just need to reach the ToBB block.
3767 if (SuccBB == ToBB)
3768 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
3769 IsTemporaryRQI);
3770 if (DT && ExclusionBlocks.empty() && DT->dominates(BB, ToBB))
3771 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
3772 IsTemporaryRQI);
3773
3774 if (ExclusionBlocks.count(SuccBB)) {
3775 UsedExclusionSet = true;
3776 continue;
3777 }
3778 Worklist.push_back(SuccBB);
3779 }
3780 }
3781
3782 DeadEdges.insert_range(LocalDeadEdges);
3783 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
3784 IsTemporaryRQI);
3785 }
3786
3787 /// See AbstractAttribute::trackStatistics()
3788 void trackStatistics() const override {}
3789
3790private:
3791 // Set of assumed dead blocks we used in the last query. If any changes we
3792 // update the state.
3793 DenseSet<const BasicBlock *> DeadBlocks;
3794
3795 // Set of assumed dead edges we used in the last query. If any changes we
3796 // update the state.
3797 DenseSet<std::pair<const BasicBlock *, const BasicBlock *>> DeadEdges;
3798
3799 /// The dominator tree of the function to short-circuit reasoning.
3800 const DominatorTree *DT = nullptr;
3801};
3802} // namespace
3803
3804/// ------------------------ NoAlias Argument Attribute ------------------------
3805
3807 Attribute::AttrKind ImpliedAttributeKind,
3808 bool IgnoreSubsumingPositions) {
3809 assert(ImpliedAttributeKind == Attribute::NoAlias &&
3810 "Unexpected attribute kind");
3811 Value *Val = &IRP.getAssociatedValue();
3813 if (isa<AllocaInst>(Val))
3814 return true;
3815 } else {
3816 IgnoreSubsumingPositions = true;
3817 }
3818
3819 if (isa<UndefValue>(Val))
3820 return true;
3821
3822 if (isa<ConstantPointerNull>(Val) &&
3825 return true;
3826
3827 if (A.hasAttr(IRP, {Attribute::ByVal, Attribute::NoAlias},
3828 IgnoreSubsumingPositions, Attribute::NoAlias))
3829 return true;
3830
3831 return false;
3832}
3833
3834namespace {
3835struct AANoAliasImpl : AANoAlias {
3836 AANoAliasImpl(const IRPosition &IRP, Attributor &A) : AANoAlias(IRP, A) {
3837 assert(getAssociatedType()->isPointerTy() &&
3838 "Noalias is a pointer attribute");
3839 }
3840
3841 const std::string getAsStr(Attributor *A) const override {
3842 return getAssumed() ? "noalias" : "may-alias";
3843 }
3844};
3845
3846/// NoAlias attribute for a floating value.
3847struct AANoAliasFloating final : AANoAliasImpl {
3848 AANoAliasFloating(const IRPosition &IRP, Attributor &A)
3849 : AANoAliasImpl(IRP, A) {}
3850
3851 /// See AbstractAttribute::updateImpl(...).
3852 ChangeStatus updateImpl(Attributor &A) override {
3853 // TODO: Implement this.
3854 return indicatePessimisticFixpoint();
3855 }
3856
3857 /// See AbstractAttribute::trackStatistics()
3858 void trackStatistics() const override {
3860 }
3861};
3862
3863/// NoAlias attribute for an argument.
3864struct AANoAliasArgument final
3865 : AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl> {
3866 using Base = AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl>;
3867 AANoAliasArgument(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {}
3868
3869 /// See AbstractAttribute::update(...).
3870 ChangeStatus updateImpl(Attributor &A) override {
3871 // We have to make sure no-alias on the argument does not break
3872 // synchronization when this is a callback argument, see also [1] below.
3873 // If synchronization cannot be affected, we delegate to the base updateImpl
3874 // function, otherwise we give up for now.
3875
3876 // If the function is no-sync, no-alias cannot break synchronization.
3877 bool IsKnownNoSycn;
3879 A, this, IRPosition::function_scope(getIRPosition()),
3880 DepClassTy::OPTIONAL, IsKnownNoSycn))
3881 return Base::updateImpl(A);
3882
3883 // If the argument is read-only, no-alias cannot break synchronization.
3884 bool IsKnown;
3885 if (AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown))
3886 return Base::updateImpl(A);
3887
3888 // If the argument is never passed through callbacks, no-alias cannot break
3889 // synchronization.
3890 bool UsedAssumedInformation = false;
3891 if (A.checkForAllCallSites(
3892 [](AbstractCallSite ACS) { return !ACS.isCallbackCall(); }, *this,
3893 true, UsedAssumedInformation))
3894 return Base::updateImpl(A);
3895
3896 // TODO: add no-alias but make sure it doesn't break synchronization by
3897 // introducing fake uses. See:
3898 // [1] Compiler Optimizations for OpenMP, J. Doerfert and H. Finkel,
3899 // International Workshop on OpenMP 2018,
3900 // http://compilers.cs.uni-saarland.de/people/doerfert/par_opt18.pdf
3901
3902 return indicatePessimisticFixpoint();
3903 }
3904
3905 /// See AbstractAttribute::trackStatistics()
3906 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noalias) }
3907};
3908
3909struct AANoAliasCallSiteArgument final : AANoAliasImpl {
3910 AANoAliasCallSiteArgument(const IRPosition &IRP, Attributor &A)
3911 : AANoAliasImpl(IRP, A) {}
3912
3913 /// Determine if the underlying value may alias with the call site argument
3914 /// \p OtherArgNo of \p ICS (= the underlying call site).
3915 bool mayAliasWithArgument(Attributor &A, AAResults *&AAR,
3916 const AAMemoryBehavior &MemBehaviorAA,
3917 const CallBase &CB, unsigned OtherArgNo) {
3918 // We do not need to worry about aliasing with the underlying IRP.
3919 if (this->getCalleeArgNo() == (int)OtherArgNo)
3920 return false;
3921
3922 // If it is not a pointer or pointer vector we do not alias.
3923 const Value *ArgOp = CB.getArgOperand(OtherArgNo);
3924 if (!ArgOp->getType()->isPtrOrPtrVectorTy())
3925 return false;
3926
3927 auto *CBArgMemBehaviorAA = A.getAAFor<AAMemoryBehavior>(
3928 *this, IRPosition::callsite_argument(CB, OtherArgNo), DepClassTy::NONE);
3929
3930 // If the argument is readnone, there is no read-write aliasing.
3931 if (CBArgMemBehaviorAA && CBArgMemBehaviorAA->isAssumedReadNone()) {
3932 A.recordDependence(*CBArgMemBehaviorAA, *this, DepClassTy::OPTIONAL);
3933 return false;
3934 }
3935
3936 // If the argument is readonly and the underlying value is readonly, there
3937 // is no read-write aliasing.
3938 bool IsReadOnly = MemBehaviorAA.isAssumedReadOnly();
3939 if (CBArgMemBehaviorAA && CBArgMemBehaviorAA->isAssumedReadOnly() &&
3940 IsReadOnly) {
3941 A.recordDependence(MemBehaviorAA, *this, DepClassTy::OPTIONAL);
3942 A.recordDependence(*CBArgMemBehaviorAA, *this, DepClassTy::OPTIONAL);
3943 return false;
3944 }
3945
3946 // We have to utilize actual alias analysis queries so we need the object.
3947 if (!AAR)
3948 AAR = A.getInfoCache().getAnalysisResultForFunction<AAManager>(
3949 *getAnchorScope());
3950
3951 // Try to rule it out at the call site.
3952 bool IsAliasing = !AAR || !AAR->isNoAlias(&getAssociatedValue(), ArgOp);
3953 LLVM_DEBUG(dbgs() << "[NoAliasCSArg] Check alias between "
3954 "callsite arguments: "
3955 << getAssociatedValue() << " " << *ArgOp << " => "
3956 << (IsAliasing ? "" : "no-") << "alias \n");
3957
3958 return IsAliasing;
3959 }
3960
3961 bool isKnownNoAliasDueToNoAliasPreservation(
3962 Attributor &A, AAResults *&AAR, const AAMemoryBehavior &MemBehaviorAA) {
3963 // We can deduce "noalias" if the following conditions hold.
3964 // (i) Associated value is assumed to be noalias in the definition.
3965 // (ii) Associated value is assumed to be no-capture in all the uses
3966 // possibly executed before this callsite.
3967 // (iii) There is no other pointer argument which could alias with the
3968 // value.
3969
3970 const IRPosition &VIRP = IRPosition::value(getAssociatedValue());
3971 const Function *ScopeFn = VIRP.getAnchorScope();
3972 // Check whether the value is captured in the scope using AANoCapture.
3973 // Look at CFG and check only uses possibly executed before this
3974 // callsite.
3975 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
3976 Instruction *UserI = cast<Instruction>(U.getUser());
3977
3978 // If UserI is the curr instruction and there is a single potential use of
3979 // the value in UserI we allow the use.
3980 // TODO: We should inspect the operands and allow those that cannot alias
3981 // with the value.
3982 if (UserI == getCtxI() && UserI->getNumOperands() == 1)
3983 return true;
3984
3985 if (ScopeFn) {
3986 if (auto *CB = dyn_cast<CallBase>(UserI)) {
3987 if (CB->isArgOperand(&U)) {
3988
3989 unsigned ArgNo = CB->getArgOperandNo(&U);
3990
3991 bool IsKnownNoCapture;
3993 A, this, IRPosition::callsite_argument(*CB, ArgNo),
3994 DepClassTy::OPTIONAL, IsKnownNoCapture))
3995 return true;
3996 }
3997 }
3998
4000 A, *UserI, *getCtxI(), *this, /* ExclusionSet */ nullptr,
4001 [ScopeFn](const Function &Fn) { return &Fn != ScopeFn; }))
4002 return true;
4003 }
4004
4005 // TODO: We should track the capturing uses in AANoCapture but the problem
4006 // is CGSCC runs. For those we would need to "allow" AANoCapture for
4007 // a value in the module slice.
4008 // TODO(captures): Make this more precise.
4009 UseCaptureInfo CI = DetermineUseCaptureKind(U, /*Base=*/nullptr);
4010 if (capturesNothing(CI))
4011 return true;
4012 if (CI.isPassthrough()) {
4013 Follow = true;
4014 return true;
4015 }
4016 LLVM_DEBUG(dbgs() << "[AANoAliasCSArg] Unknown user: " << *UserI << "\n");
4017 return false;
4018 };
4019
4020 bool IsKnownNoCapture;
4021 const AANoCapture *NoCaptureAA = nullptr;
4022 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
4023 A, this, VIRP, DepClassTy::NONE, IsKnownNoCapture, false, &NoCaptureAA);
4024 if (!IsAssumedNoCapture &&
4025 (!NoCaptureAA || !NoCaptureAA->isAssumedNoCaptureMaybeReturned())) {
4026 if (!A.checkForAllUses(UsePred, *this, getAssociatedValue())) {
4027 LLVM_DEBUG(
4028 dbgs() << "[AANoAliasCSArg] " << getAssociatedValue()
4029 << " cannot be noalias as it is potentially captured\n");
4030 return false;
4031 }
4032 }
4033 if (NoCaptureAA)
4034 A.recordDependence(*NoCaptureAA, *this, DepClassTy::OPTIONAL);
4035
4036 // Check there is no other pointer argument which could alias with the
4037 // value passed at this call site.
4038 // TODO: AbstractCallSite
4039 const auto &CB = cast<CallBase>(getAnchorValue());
4040 for (unsigned OtherArgNo = 0; OtherArgNo < CB.arg_size(); OtherArgNo++)
4041 if (mayAliasWithArgument(A, AAR, MemBehaviorAA, CB, OtherArgNo))
4042 return false;
4043
4044 return true;
4045 }
4046
4047 /// See AbstractAttribute::updateImpl(...).
4048 ChangeStatus updateImpl(Attributor &A) override {
4049 // If the argument is readnone we are done as there are no accesses via the
4050 // argument.
4051 auto *MemBehaviorAA =
4052 A.getAAFor<AAMemoryBehavior>(*this, getIRPosition(), DepClassTy::NONE);
4053 if (MemBehaviorAA && MemBehaviorAA->isAssumedReadNone()) {
4054 A.recordDependence(*MemBehaviorAA, *this, DepClassTy::OPTIONAL);
4055 return ChangeStatus::UNCHANGED;
4056 }
4057
4058 bool IsKnownNoAlias;
4059 const IRPosition &VIRP = IRPosition::value(getAssociatedValue());
4061 A, this, VIRP, DepClassTy::REQUIRED, IsKnownNoAlias)) {
4062 LLVM_DEBUG(dbgs() << "[AANoAlias] " << getAssociatedValue()
4063 << " is not no-alias at the definition\n");
4064 return indicatePessimisticFixpoint();
4065 }
4066
4067 AAResults *AAR = nullptr;
4068 if (MemBehaviorAA &&
4069 isKnownNoAliasDueToNoAliasPreservation(A, AAR, *MemBehaviorAA)) {
4070 LLVM_DEBUG(
4071 dbgs() << "[AANoAlias] No-Alias deduced via no-alias preservation\n");
4072 return ChangeStatus::UNCHANGED;
4073 }
4074
4075 return indicatePessimisticFixpoint();
4076 }
4077
4078 /// See AbstractAttribute::trackStatistics()
4079 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(noalias) }
4080};
4081
4082/// NoAlias attribute for function return value.
4083struct AANoAliasReturned final : AANoAliasImpl {
4084 AANoAliasReturned(const IRPosition &IRP, Attributor &A)
4085 : AANoAliasImpl(IRP, A) {}
4086
4087 /// See AbstractAttribute::updateImpl(...).
4088 ChangeStatus updateImpl(Attributor &A) override {
4089
4090 auto CheckReturnValue = [&](Value &RV) -> bool {
4091 if (Constant *C = dyn_cast<Constant>(&RV))
4092 if (C->isNullValue() || isa<UndefValue>(C))
4093 return true;
4094
4095 /// For now, we can only deduce noalias if we have call sites.
4096 /// FIXME: add more support.
4097 if (!isa<CallBase>(&RV))
4098 return false;
4099
4100 const IRPosition &RVPos = IRPosition::value(RV);
4101 bool IsKnownNoAlias;
4103 A, this, RVPos, DepClassTy::REQUIRED, IsKnownNoAlias))
4104 return false;
4105
4106 bool IsKnownNoCapture;
4107 const AANoCapture *NoCaptureAA = nullptr;
4108 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
4109 A, this, RVPos, DepClassTy::REQUIRED, IsKnownNoCapture, false,
4110 &NoCaptureAA);
4111 return IsAssumedNoCapture ||
4112 (NoCaptureAA && NoCaptureAA->isAssumedNoCaptureMaybeReturned());
4113 };
4114
4115 if (!A.checkForAllReturnedValues(CheckReturnValue, *this))
4116 return indicatePessimisticFixpoint();
4117
4118 return ChangeStatus::UNCHANGED;
4119 }
4120
4121 /// See AbstractAttribute::trackStatistics()
4122 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noalias) }
4123};
4124
4125/// NoAlias attribute deduction for a call site return value.
4126struct AANoAliasCallSiteReturned final
4127 : AACalleeToCallSite<AANoAlias, AANoAliasImpl> {
4128 AANoAliasCallSiteReturned(const IRPosition &IRP, Attributor &A)
4129 : AACalleeToCallSite<AANoAlias, AANoAliasImpl>(IRP, A) {}
4130
4131 /// See AbstractAttribute::trackStatistics()
4132 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(noalias); }
4133};
4134} // namespace
4135
4136/// -------------------AAIsDead Function Attribute-----------------------
4137
4138namespace {
4139struct AAIsDeadValueImpl : public AAIsDead {
4140 AAIsDeadValueImpl(const IRPosition &IRP, Attributor &A) : AAIsDead(IRP, A) {}
4141
4142 /// See AAIsDead::isAssumedDead().
4143 bool isAssumedDead() const override { return isAssumed(IS_DEAD); }
4144
4145 /// See AAIsDead::isKnownDead().
4146 bool isKnownDead() const override { return isKnown(IS_DEAD); }
4147
4148 /// See AAIsDead::isAssumedDead(BasicBlock *).
4149 bool isAssumedDead(const BasicBlock *BB) const override { return false; }
4150
4151 /// See AAIsDead::isKnownDead(BasicBlock *).
4152 bool isKnownDead(const BasicBlock *BB) const override { return false; }
4153
4154 /// See AAIsDead::isAssumedDead(Instruction *I).
4155 bool isAssumedDead(const Instruction *I) const override {
4156 return I == getCtxI() && isAssumedDead();
4157 }
4158
4159 /// See AAIsDead::isKnownDead(Instruction *I).
4160 bool isKnownDead(const Instruction *I) const override {
4161 return isAssumedDead(I) && isKnownDead();
4162 }
4163
4164 /// See AbstractAttribute::getAsStr().
4165 const std::string getAsStr(Attributor *A) const override {
4166 return isAssumedDead() ? "assumed-dead" : "assumed-live";
4167 }
4168
4169 /// Check if all uses are assumed dead.
4170 bool areAllUsesAssumedDead(Attributor &A, Value &V) {
4171 // Callers might not check the type, void has no uses.
4172 if (V.getType()->isVoidTy() || V.use_empty())
4173 return true;
4174
4175 // If we replace a value with a constant there are no uses left afterwards.
4176 if (!isa<Constant>(V)) {
4177 if (auto *I = dyn_cast<Instruction>(&V))
4178 if (!A.isRunOn(*I->getFunction()))
4179 return false;
4180 bool UsedAssumedInformation = false;
4181 std::optional<Constant *> C =
4182 A.getAssumedConstant(V, *this, UsedAssumedInformation);
4183 if (!C || *C)
4184 return true;
4185 }
4186
4187 auto UsePred = [&](const Use &U, bool &Follow) { return false; };
4188 // Explicitly set the dependence class to required because we want a long
4189 // chain of N dependent instructions to be considered live as soon as one is
4190 // without going through N update cycles. This is not required for
4191 // correctness.
4192 return A.checkForAllUses(UsePred, *this, V, /* CheckBBLivenessOnly */ false,
4193 DepClassTy::REQUIRED,
4194 /* IgnoreDroppableUses */ false);
4195 }
4196
4197 /// Determine if \p I is assumed to be side-effect free.
4198 bool isAssumedSideEffectFree(Attributor &A, Instruction *I) {
4200 return true;
4201
4202 if (!I->isTerminator() && !I->mayHaveSideEffects())
4203 return true;
4204
4205 auto *CB = dyn_cast<CallBase>(I);
4206 if (!CB || isa<IntrinsicInst>(CB))
4207 return false;
4208
4209 const IRPosition &CallIRP = IRPosition::callsite_function(*CB);
4210
4211 bool IsKnownNoUnwind;
4213 A, this, CallIRP, DepClassTy::OPTIONAL, IsKnownNoUnwind))
4214 return false;
4215
4216 bool IsKnown;
4217 return AA::isAssumedReadOnly(A, CallIRP, *this, IsKnown);
4218 }
4219};
4220
4221struct AAIsDeadFloating : public AAIsDeadValueImpl {
4222 AAIsDeadFloating(const IRPosition &IRP, Attributor &A)
4223 : AAIsDeadValueImpl(IRP, A) {}
4224
4225 /// See AbstractAttribute::initialize(...).
4226 void initialize(Attributor &A) override {
4227 AAIsDeadValueImpl::initialize(A);
4228
4229 if (isa<UndefValue>(getAssociatedValue())) {
4230 indicatePessimisticFixpoint();
4231 return;
4232 }
4233
4234 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
4235 if (!isAssumedSideEffectFree(A, I)) {
4237 indicatePessimisticFixpoint();
4238 else
4239 removeAssumedBits(HAS_NO_EFFECT);
4240 }
4241 }
4242
4243 bool isDeadFence(Attributor &A, FenceInst &FI) {
4244 const auto *ExecDomainAA = A.lookupAAFor<AAExecutionDomain>(
4245 IRPosition::function(*FI.getFunction()), *this, DepClassTy::NONE);
4246 if (!ExecDomainAA || !ExecDomainAA->isNoOpFence(FI))
4247 return false;
4248 A.recordDependence(*ExecDomainAA, *this, DepClassTy::OPTIONAL);
4249 return true;
4250 }
4251
4252 bool isDeadStore(Attributor &A, StoreInst &SI,
4253 SmallSetVector<Instruction *, 8> *AssumeOnlyInst = nullptr) {
4254 // Lang ref now states volatile store is not UB/dead, let's skip them.
4255 if (SI.isVolatile())
4256 return false;
4257
4258 // If we are collecting assumes to be deleted we are in the manifest stage.
4259 // It's problematic to collect the potential copies again now so we use the
4260 // cached ones.
4261 bool UsedAssumedInformation = false;
4262 if (!AssumeOnlyInst) {
4263 PotentialCopies.clear();
4264 if (!AA::getPotentialCopiesOfStoredValue(A, SI, PotentialCopies, *this,
4265 UsedAssumedInformation)) {
4266 LLVM_DEBUG(
4267 dbgs()
4268 << "[AAIsDead] Could not determine potential copies of store!\n");
4269 return false;
4270 }
4271 }
4272 LLVM_DEBUG(dbgs() << "[AAIsDead] Store has " << PotentialCopies.size()
4273 << " potential copies.\n");
4274
4275 InformationCache &InfoCache = A.getInfoCache();
4276 return llvm::all_of(PotentialCopies, [&](Value *V) {
4277 if (A.isAssumedDead(IRPosition::value(*V), this, nullptr,
4278 UsedAssumedInformation))
4279 return true;
4280 if (auto *LI = dyn_cast<LoadInst>(V)) {
4281 if (llvm::all_of(LI->uses(), [&](const Use &U) {
4282 auto &UserI = cast<Instruction>(*U.getUser());
4283 if (InfoCache.isOnlyUsedByAssume(UserI)) {
4284 if (AssumeOnlyInst)
4285 AssumeOnlyInst->insert(&UserI);
4286 return true;
4287 }
4288 return A.isAssumedDead(U, this, nullptr, UsedAssumedInformation);
4289 })) {
4290 return true;
4291 }
4292 }
4293 LLVM_DEBUG(dbgs() << "[AAIsDead] Potential copy " << *V
4294 << " is assumed live!\n");
4295 return false;
4296 });
4297 }
4298
4299 /// See AbstractAttribute::getAsStr().
4300 const std::string getAsStr(Attributor *A) const override {
4301 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
4303 if (isValidState())
4304 return "assumed-dead-store";
4306 if (isValidState())
4307 return "assumed-dead-fence";
4308 return AAIsDeadValueImpl::getAsStr(A);
4309 }
4310
4311 /// See AbstractAttribute::updateImpl(...).
4312 ChangeStatus updateImpl(Attributor &A) override {
4313 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
4314 if (auto *SI = dyn_cast_or_null<StoreInst>(I)) {
4315 if (!isDeadStore(A, *SI))
4316 return indicatePessimisticFixpoint();
4317 } else if (auto *FI = dyn_cast_or_null<FenceInst>(I)) {
4318 if (!isDeadFence(A, *FI))
4319 return indicatePessimisticFixpoint();
4320 } else {
4321 if (!isAssumedSideEffectFree(A, I))
4322 return indicatePessimisticFixpoint();
4323 if (!areAllUsesAssumedDead(A, getAssociatedValue()))
4324 return indicatePessimisticFixpoint();
4325 }
4327 }
4328
4329 bool isRemovableStore() const override {
4330 return isAssumed(IS_REMOVABLE) && isa<StoreInst>(&getAssociatedValue());
4331 }
4332
4333 /// See AbstractAttribute::manifest(...).
4334 ChangeStatus manifest(Attributor &A) override {
4335 Value &V = getAssociatedValue();
4336 if (auto *I = dyn_cast<Instruction>(&V)) {
4337 // If we get here we basically know the users are all dead. We check if
4338 // isAssumedSideEffectFree returns true here again because it might not be
4339 // the case and only the users are dead but the instruction (=call) is
4340 // still needed.
4341 if (auto *SI = dyn_cast<StoreInst>(I)) {
4342 SmallSetVector<Instruction *, 8> AssumeOnlyInst;
4343 bool IsDead = isDeadStore(A, *SI, &AssumeOnlyInst);
4344 (void)IsDead;
4345 assert(IsDead && "Store was assumed to be dead!");
4346 A.deleteAfterManifest(*I);
4347 for (size_t i = 0; i < AssumeOnlyInst.size(); ++i) {
4348 Instruction *AOI = AssumeOnlyInst[i];
4349 for (auto *Usr : AOI->users())
4350 AssumeOnlyInst.insert(cast<Instruction>(Usr));
4351 A.deleteAfterManifest(*AOI);
4352 }
4353 return ChangeStatus::CHANGED;
4354 }
4355 if (auto *FI = dyn_cast<FenceInst>(I)) {
4356 assert(isDeadFence(A, *FI));
4357 A.deleteAfterManifest(*FI);
4358 return ChangeStatus::CHANGED;
4359 }
4360 if (isAssumedSideEffectFree(A, I) && !I->isTerminator()) {
4361 A.deleteAfterManifest(*I);
4362 return ChangeStatus::CHANGED;
4363 }
4364 }
4366 }
4367
4368 /// See AbstractAttribute::trackStatistics()
4369 void trackStatistics() const override {
4371 }
4372
4373private:
4374 // The potential copies of a dead store, used for deletion during manifest.
4375 SmallSetVector<Value *, 4> PotentialCopies;
4376};
4377
4378struct AAIsDeadArgument : public AAIsDeadFloating {
4379 AAIsDeadArgument(const IRPosition &IRP, Attributor &A)
4380 : AAIsDeadFloating(IRP, A) {}
4381
4382 /// See AbstractAttribute::manifest(...).
4383 ChangeStatus manifest(Attributor &A) override {
4384 Argument &Arg = *getAssociatedArgument();
4385 if (A.isValidFunctionSignatureRewrite(Arg, /* ReplacementTypes */ {}))
4386 if (A.registerFunctionSignatureRewrite(
4387 Arg, /* ReplacementTypes */ {},
4390 return ChangeStatus::CHANGED;
4391 }
4392 return ChangeStatus::UNCHANGED;
4393 }
4394
4395 /// See AbstractAttribute::trackStatistics()
4396 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(IsDead) }
4397};
4398
4399struct AAIsDeadCallSiteArgument : public AAIsDeadValueImpl {
4400 AAIsDeadCallSiteArgument(const IRPosition &IRP, Attributor &A)
4401 : AAIsDeadValueImpl(IRP, A) {}
4402
4403 /// See AbstractAttribute::initialize(...).
4404 void initialize(Attributor &A) override {
4405 AAIsDeadValueImpl::initialize(A);
4406 if (isa<UndefValue>(getAssociatedValue()))
4407 indicatePessimisticFixpoint();
4408 }
4409
4410 /// See AbstractAttribute::updateImpl(...).
4411 ChangeStatus updateImpl(Attributor &A) override {
4412 // TODO: Once we have call site specific value information we can provide
4413 // call site specific liveness information and then it makes
4414 // sense to specialize attributes for call sites arguments instead of
4415 // redirecting requests to the callee argument.
4416 Argument *Arg = getAssociatedArgument();
4417 if (!Arg)
4418 return indicatePessimisticFixpoint();
4419 const IRPosition &ArgPos = IRPosition::argument(*Arg);
4420 auto *ArgAA = A.getAAFor<AAIsDead>(*this, ArgPos, DepClassTy::REQUIRED);
4421 if (!ArgAA)
4422 return indicatePessimisticFixpoint();
4423 return clampStateAndIndicateChange(getState(), ArgAA->getState());
4424 }
4425
4426 /// See AbstractAttribute::manifest(...).
4427 ChangeStatus manifest(Attributor &A) override {
4428 CallBase &CB = cast<CallBase>(getAnchorValue());
4429 Use &U = CB.getArgOperandUse(getCallSiteArgNo());
4430 assert(!isa<UndefValue>(U.get()) &&
4431 "Expected undef values to be filtered out!");
4432 UndefValue &UV = *UndefValue::get(U->getType());
4433 if (A.changeUseAfterManifest(U, UV))
4434 return ChangeStatus::CHANGED;
4435 return ChangeStatus::UNCHANGED;
4436 }
4437
4438 /// See AbstractAttribute::trackStatistics()
4439 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(IsDead) }
4440};
4441
4442struct AAIsDeadCallSiteReturned : public AAIsDeadFloating {
4443 AAIsDeadCallSiteReturned(const IRPosition &IRP, Attributor &A)
4444 : AAIsDeadFloating(IRP, A) {}
4445
4446 /// See AAIsDead::isAssumedDead().
4447 bool isAssumedDead() const override {
4448 return AAIsDeadFloating::isAssumedDead() && IsAssumedSideEffectFree;
4449 }
4450
4451 /// See AbstractAttribute::initialize(...).
4452 void initialize(Attributor &A) override {
4453 AAIsDeadFloating::initialize(A);
4454 if (isa<UndefValue>(getAssociatedValue())) {
4455 indicatePessimisticFixpoint();
4456 return;
4457 }
4458
4459 // We track this separately as a secondary state.
4460 IsAssumedSideEffectFree = isAssumedSideEffectFree(A, getCtxI());
4461 }
4462
4463 /// See AbstractAttribute::updateImpl(...).
4464 ChangeStatus updateImpl(Attributor &A) override {
4465 ChangeStatus Changed = ChangeStatus::UNCHANGED;
4466 if (IsAssumedSideEffectFree && !isAssumedSideEffectFree(A, getCtxI())) {
4467 IsAssumedSideEffectFree = false;
4468 Changed = ChangeStatus::CHANGED;
4469 }
4470 if (!areAllUsesAssumedDead(A, getAssociatedValue()))
4471 return indicatePessimisticFixpoint();
4472 return Changed;
4473 }
4474
4475 /// See AbstractAttribute::trackStatistics()
4476 void trackStatistics() const override {
4477 if (IsAssumedSideEffectFree)
4479 else
4480 STATS_DECLTRACK_CSRET_ATTR(UnusedResult)
4481 }
4482
4483 /// See AbstractAttribute::getAsStr().
4484 const std::string getAsStr(Attributor *A) const override {
4485 return isAssumedDead()
4486 ? "assumed-dead"
4487 : (getAssumed() ? "assumed-dead-users" : "assumed-live");
4488 }
4489
4490private:
4491 bool IsAssumedSideEffectFree = true;
4492};
4493
4494struct AAIsDeadReturned : public AAIsDeadValueImpl {
4495 AAIsDeadReturned(const IRPosition &IRP, Attributor &A)
4496 : AAIsDeadValueImpl(IRP, A) {}
4497
4498 /// See AbstractAttribute::updateImpl(...).
4499 ChangeStatus updateImpl(Attributor &A) override {
4500
4501 bool UsedAssumedInformation = false;
4502 A.checkForAllInstructions([](Instruction &) { return true; }, *this,
4503 {Instruction::Ret}, UsedAssumedInformation);
4504
4505 auto PredForCallSite = [&](AbstractCallSite ACS) {
4506 if (ACS.isCallbackCall() || !ACS.getInstruction())
4507 return false;
4508 return areAllUsesAssumedDead(A, *ACS.getInstruction());
4509 };
4510
4511 if (!A.checkForAllCallSites(PredForCallSite, *this, true,
4512 UsedAssumedInformation))
4513 return indicatePessimisticFixpoint();
4514
4515 return ChangeStatus::UNCHANGED;
4516 }
4517
4518 /// See AbstractAttribute::manifest(...).
4519 ChangeStatus manifest(Attributor &A) override {
4520 // TODO: Rewrite the signature to return void?
4521 bool AnyChange = false;
4522 UndefValue &UV = *UndefValue::get(getAssociatedFunction()->getReturnType());
4523 auto RetInstPred = [&](Instruction &I) {
4524 ReturnInst &RI = cast<ReturnInst>(I);
4526 AnyChange |= A.changeUseAfterManifest(RI.getOperandUse(0), UV);
4527 return true;
4528 };
4529 bool UsedAssumedInformation = false;
4530 A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret},
4531 UsedAssumedInformation);
4532 return AnyChange ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
4533 }
4534
4535 /// See AbstractAttribute::trackStatistics()
4536 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(IsDead) }
4537};
4538
4539struct AAIsDeadFunction : public AAIsDead {
4540 AAIsDeadFunction(const IRPosition &IRP, Attributor &A) : AAIsDead(IRP, A) {}
4541
4542 /// See AbstractAttribute::initialize(...).
4543 void initialize(Attributor &A) override {
4544 Function *F = getAnchorScope();
4545 assert(F && "Did expect an anchor function");
4546 if (!isAssumedDeadInternalFunction(A)) {
4547 ToBeExploredFrom.insert(&F->getEntryBlock().front());
4548 assumeLive(A, F->getEntryBlock());
4549 }
4550 }
4551
4552 bool isAssumedDeadInternalFunction(Attributor &A) {
4553 if (!getAnchorScope()->hasLocalLinkage())
4554 return false;
4555 bool UsedAssumedInformation = false;
4556 return A.checkForAllCallSites([](AbstractCallSite) { return false; }, *this,
4557 true, UsedAssumedInformation);
4558 }
4559
4560 /// See AbstractAttribute::getAsStr().
4561 const std::string getAsStr(Attributor *A) const override {
4562 return "Live[#BB " + std::to_string(AssumedLiveBlocks.size()) + "/" +
4563 std::to_string(getAnchorScope()->size()) + "][#TBEP " +
4564 std::to_string(ToBeExploredFrom.size()) + "][#KDE " +
4565 std::to_string(KnownDeadEnds.size()) + "]";
4566 }
4567
4568 /// See AbstractAttribute::manifest(...).
4569 ChangeStatus manifest(Attributor &A) override {
4570 assert(getState().isValidState() &&
4571 "Attempted to manifest an invalid state!");
4572
4573 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
4574 Function &F = *getAnchorScope();
4575
4576 if (AssumedLiveBlocks.empty()) {
4577 A.deleteAfterManifest(F);
4578 return ChangeStatus::CHANGED;
4579 }
4580
4581 // Flag to determine if we can change an invoke to a call assuming the
4582 // callee is nounwind. This is not possible if the personality of the
4583 // function allows to catch asynchronous exceptions.
4584 bool Invoke2CallAllowed = !mayCatchAsynchronousExceptions(F);
4585
4586 KnownDeadEnds.set_union(ToBeExploredFrom);
4587 for (const Instruction *DeadEndI : KnownDeadEnds) {
4588 auto *CB = dyn_cast<CallBase>(DeadEndI);
4589 if (!CB)
4590 continue;
4591 bool IsKnownNoReturn;
4593 A, this, IRPosition::callsite_function(*CB), DepClassTy::OPTIONAL,
4594 IsKnownNoReturn);
4595 if (MayReturn && (!Invoke2CallAllowed || !isa<InvokeInst>(CB)))
4596 continue;
4597
4598 if (auto *II = dyn_cast<InvokeInst>(DeadEndI))
4599 A.registerInvokeWithDeadSuccessor(const_cast<InvokeInst &>(*II));
4600 else
4601 A.changeToUnreachableAfterManifest(
4602 const_cast<Instruction *>(DeadEndI->getNextNode()));
4603 HasChanged = ChangeStatus::CHANGED;
4604 }
4605
4606 STATS_DECL(AAIsDead, BasicBlock, "Number of dead basic blocks deleted.");
4607 for (BasicBlock &BB : F)
4608 if (!AssumedLiveBlocks.count(&BB)) {
4609 A.deleteAfterManifest(BB);
4610 ++BUILD_STAT_NAME(AAIsDead, BasicBlock);
4611 HasChanged = ChangeStatus::CHANGED;
4612 }
4613
4614 return HasChanged;
4615 }
4616
4617 /// See AbstractAttribute::updateImpl(...).
4618 ChangeStatus updateImpl(Attributor &A) override;
4619
4620 bool isEdgeDead(const BasicBlock *From, const BasicBlock *To) const override {
4621 assert(From->getParent() == getAnchorScope() &&
4622 To->getParent() == getAnchorScope() &&
4623 "Used AAIsDead of the wrong function");
4624 return isValidState() && !AssumedLiveEdges.count(std::make_pair(From, To));
4625 }
4626
4627 /// See AbstractAttribute::trackStatistics()
4628 void trackStatistics() const override {}
4629
4630 /// Returns true if the function is assumed dead.
4631 bool isAssumedDead() const override { return false; }
4632
4633 /// See AAIsDead::isKnownDead().
4634 bool isKnownDead() const override { return false; }
4635
4636 /// See AAIsDead::isAssumedDead(BasicBlock *).
4637 bool isAssumedDead(const BasicBlock *BB) const override {
4638 assert(BB->getParent() == getAnchorScope() &&
4639 "BB must be in the same anchor scope function.");
4640
4641 if (!getAssumed())
4642 return false;
4643 return !AssumedLiveBlocks.count(BB);
4644 }
4645
4646 /// See AAIsDead::isKnownDead(BasicBlock *).
4647 bool isKnownDead(const BasicBlock *BB) const override {
4648 return getKnown() && isAssumedDead(BB);
4649 }
4650
4651 /// See AAIsDead::isAssumed(Instruction *I).
4652 bool isAssumedDead(const Instruction *I) const override {
4653 assert(I->getParent()->getParent() == getAnchorScope() &&
4654 "Instruction must be in the same anchor scope function.");
4655
4656 if (!getAssumed())
4657 return false;
4658
4659 // If it is not in AssumedLiveBlocks then it for sure dead.
4660 // Otherwise, it can still be after noreturn call in a live block.
4661 if (!AssumedLiveBlocks.count(I->getParent()))
4662 return true;
4663
4664 // If it is not after a liveness barrier it is live.
4665 const Instruction *PrevI = I->getPrevNode();
4666 while (PrevI) {
4667 if (KnownDeadEnds.count(PrevI) || ToBeExploredFrom.count(PrevI))
4668 return true;
4669 PrevI = PrevI->getPrevNode();
4670 }
4671 return false;
4672 }
4673
4674 /// See AAIsDead::isKnownDead(Instruction *I).
4675 bool isKnownDead(const Instruction *I) const override {
4676 return getKnown() && isAssumedDead(I);
4677 }
4678
4679 /// Assume \p BB is (partially) live now and indicate to the Attributor \p A
4680 /// that internal function called from \p BB should now be looked at.
4681 bool assumeLive(Attributor &A, const BasicBlock &BB) {
4682 if (!AssumedLiveBlocks.insert(&BB).second)
4683 return false;
4684
4685 // We assume that all of BB is (probably) live now and if there are calls to
4686 // internal functions we will assume that those are now live as well. This
4687 // is a performance optimization for blocks with calls to a lot of internal
4688 // functions. It can however cause dead functions to be treated as live.
4689 for (const Instruction &I : BB)
4690 if (const auto *CB = dyn_cast<CallBase>(&I))
4692 if (F->hasLocalLinkage())
4693 A.markLiveInternalFunction(*F);
4694 return true;
4695 }
4696
4697 /// Collection of instructions that need to be explored again, e.g., we
4698 /// did assume they do not transfer control to (one of their) successors.
4699 SmallSetVector<const Instruction *, 8> ToBeExploredFrom;
4700
4701 /// Collection of instructions that are known to not transfer control.
4702 SmallSetVector<const Instruction *, 8> KnownDeadEnds;
4703
4704 /// Collection of all assumed live edges
4705 DenseSet<std::pair<const BasicBlock *, const BasicBlock *>> AssumedLiveEdges;
4706
4707 /// Collection of all assumed live BasicBlocks.
4708 DenseSet<const BasicBlock *> AssumedLiveBlocks;
4709};
4710
4711static bool
4712identifyAliveSuccessors(Attributor &A, const CallBase &CB,
4713 AbstractAttribute &AA,
4714 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4715 const IRPosition &IPos = IRPosition::callsite_function(CB);
4716
4717 bool IsKnownNoReturn;
4719 A, &AA, IPos, DepClassTy::OPTIONAL, IsKnownNoReturn))
4720 return !IsKnownNoReturn;
4721 if (CB.isTerminator())
4722 AliveSuccessors.push_back(&CB.getSuccessor(0)->front());
4723 else
4724 AliveSuccessors.push_back(CB.getNextNode());
4725 return false;
4726}
4727
4728static bool
4729identifyAliveSuccessors(Attributor &A, const InvokeInst &II,
4730 AbstractAttribute &AA,
4731 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4732 bool UsedAssumedInformation =
4733 identifyAliveSuccessors(A, cast<CallBase>(II), AA, AliveSuccessors);
4734
4735 // First, determine if we can change an invoke to a call assuming the
4736 // callee is nounwind. This is not possible if the personality of the
4737 // function allows to catch asynchronous exceptions.
4738 if (AAIsDeadFunction::mayCatchAsynchronousExceptions(*II.getFunction())) {
4739 AliveSuccessors.push_back(&II.getUnwindDest()->front());
4740 } else {
4741 const IRPosition &IPos = IRPosition::callsite_function(II);
4742
4743 bool IsKnownNoUnwind;
4745 A, &AA, IPos, DepClassTy::OPTIONAL, IsKnownNoUnwind)) {
4746 UsedAssumedInformation |= !IsKnownNoUnwind;
4747 } else {
4748 AliveSuccessors.push_back(&II.getUnwindDest()->front());
4749 }
4750 }
4751 return UsedAssumedInformation;
4752}
4753
4754static bool
4755identifyAliveSuccessors(Attributor &, const UncondBrInst &BI,
4756 AbstractAttribute &,
4757 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4758 AliveSuccessors.push_back(&BI.getSuccessor()->front());
4759 return false;
4760}
4761
4762static bool
4763identifyAliveSuccessors(Attributor &A, const CondBrInst &BI,
4764 AbstractAttribute &AA,
4765 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4766 bool UsedAssumedInformation = false;
4767 std::optional<Constant *> C =
4768 A.getAssumedConstant(*BI.getCondition(), AA, UsedAssumedInformation);
4769 if (!C || isa_and_nonnull<UndefValue>(*C)) {
4770 // No value yet, assume both edges are dead.
4771 } else if (isa_and_nonnull<ConstantInt>(*C)) {
4772 const BasicBlock *SuccBB =
4773 BI.getSuccessor(1 - cast<ConstantInt>(*C)->getValue().getZExtValue());
4774 AliveSuccessors.push_back(&SuccBB->front());
4775 } else {
4776 AliveSuccessors.push_back(&BI.getSuccessor(0)->front());
4777 AliveSuccessors.push_back(&BI.getSuccessor(1)->front());
4778 UsedAssumedInformation = false;
4779 }
4780 return UsedAssumedInformation;
4781}
4782
4783static bool
4784identifyAliveSuccessors(Attributor &A, const SwitchInst &SI,
4785 AbstractAttribute &AA,
4786 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4787 bool UsedAssumedInformation = false;
4789 if (!A.getAssumedSimplifiedValues(IRPosition::value(*SI.getCondition()), &AA,
4791 UsedAssumedInformation)) {
4792 // Something went wrong, assume all successors are live.
4793 for (const BasicBlock *SuccBB : successors(SI.getParent()))
4794 AliveSuccessors.push_back(&SuccBB->front());
4795 return false;
4796 }
4797
4798 if (Values.empty() ||
4799 (Values.size() == 1 &&
4800 isa_and_nonnull<UndefValue>(Values.front().getValue()))) {
4801 // No valid value yet, assume all edges are dead.
4802 return UsedAssumedInformation;
4803 }
4804
4805 Type &Ty = *SI.getCondition()->getType();
4806 SmallPtrSet<ConstantInt *, 8> Constants;
4807 auto CheckForConstantInt = [&](Value *V) {
4808 if (auto *CI = dyn_cast_if_present<ConstantInt>(AA::getWithType(*V, Ty))) {
4809 Constants.insert(CI);
4810 return true;
4811 }
4812 return false;
4813 };
4814
4815 if (!all_of(Values, [&](AA::ValueAndContext &VAC) {
4816 return CheckForConstantInt(VAC.getValue());
4817 })) {
4818 for (const BasicBlock *SuccBB : successors(SI.getParent()))
4819 AliveSuccessors.push_back(&SuccBB->front());
4820 return UsedAssumedInformation;
4821 }
4822
4823 unsigned MatchedCases = 0;
4824 for (const auto &CaseIt : SI.cases()) {
4825 if (Constants.count(CaseIt.getCaseValue())) {
4826 ++MatchedCases;
4827 AliveSuccessors.push_back(&CaseIt.getCaseSuccessor()->front());
4828 }
4829 }
4830
4831 // If all potential values have been matched, we will not visit the default
4832 // case.
4833 if (MatchedCases < Constants.size())
4834 AliveSuccessors.push_back(&SI.getDefaultDest()->front());
4835 return UsedAssumedInformation;
4836}
4837
4838ChangeStatus AAIsDeadFunction::updateImpl(Attributor &A) {
4840
4841 if (AssumedLiveBlocks.empty()) {
4842 if (isAssumedDeadInternalFunction(A))
4844
4845 Function *F = getAnchorScope();
4846 ToBeExploredFrom.insert(&F->getEntryBlock().front());
4847 assumeLive(A, F->getEntryBlock());
4848 Change = ChangeStatus::CHANGED;
4849 }
4850
4851 LLVM_DEBUG(dbgs() << "[AAIsDead] Live [" << AssumedLiveBlocks.size() << "/"
4852 << getAnchorScope()->size() << "] BBs and "
4853 << ToBeExploredFrom.size() << " exploration points and "
4854 << KnownDeadEnds.size() << " known dead ends\n");
4855
4856 // Copy and clear the list of instructions we need to explore from. It is
4857 // refilled with instructions the next update has to look at.
4858 SmallVector<const Instruction *, 8> Worklist(ToBeExploredFrom.begin(),
4859 ToBeExploredFrom.end());
4860 decltype(ToBeExploredFrom) NewToBeExploredFrom;
4861
4863 while (!Worklist.empty()) {
4864 const Instruction *I = Worklist.pop_back_val();
4865 LLVM_DEBUG(dbgs() << "[AAIsDead] Exploration inst: " << *I << "\n");
4866
4867 // Fast forward for uninteresting instructions. We could look for UB here
4868 // though.
4869 while (!I->isTerminator() && !isa<CallBase>(I))
4870 I = I->getNextNode();
4871
4872 AliveSuccessors.clear();
4873
4874 bool UsedAssumedInformation = false;
4875 switch (I->getOpcode()) {
4876 // TODO: look for (assumed) UB to backwards propagate "deadness".
4877 default:
4878 assert(I->isTerminator() &&
4879 "Expected non-terminators to be handled already!");
4880 for (const BasicBlock *SuccBB : successors(I->getParent()))
4881 AliveSuccessors.push_back(&SuccBB->front());
4882 break;
4883 case Instruction::Call:
4884 UsedAssumedInformation = identifyAliveSuccessors(A, cast<CallInst>(*I),
4885 *this, AliveSuccessors);
4886 break;
4887 case Instruction::Invoke:
4888 UsedAssumedInformation = identifyAliveSuccessors(A, cast<InvokeInst>(*I),
4889 *this, AliveSuccessors);
4890 break;
4891 case Instruction::UncondBr:
4892 UsedAssumedInformation = identifyAliveSuccessors(
4893 A, cast<UncondBrInst>(*I), *this, AliveSuccessors);
4894 break;
4895 case Instruction::CondBr:
4896 UsedAssumedInformation = identifyAliveSuccessors(A, cast<CondBrInst>(*I),
4897 *this, AliveSuccessors);
4898 break;
4899 case Instruction::Switch:
4900 UsedAssumedInformation = identifyAliveSuccessors(A, cast<SwitchInst>(*I),
4901 *this, AliveSuccessors);
4902 break;
4903 }
4904
4905 if (UsedAssumedInformation) {
4906 NewToBeExploredFrom.insert(I);
4907 } else if (AliveSuccessors.empty() ||
4908 (I->isTerminator() &&
4909 AliveSuccessors.size() < I->getNumSuccessors())) {
4910 if (KnownDeadEnds.insert(I))
4911 Change = ChangeStatus::CHANGED;
4912 }
4913
4914 LLVM_DEBUG(dbgs() << "[AAIsDead] #AliveSuccessors: "
4915 << AliveSuccessors.size() << " UsedAssumedInformation: "
4916 << UsedAssumedInformation << "\n");
4917
4918 for (const Instruction *AliveSuccessor : AliveSuccessors) {
4919 if (!I->isTerminator()) {
4920 assert(AliveSuccessors.size() == 1 &&
4921 "Non-terminator expected to have a single successor!");
4922 Worklist.push_back(AliveSuccessor);
4923 } else {
4924 // record the assumed live edge
4925 auto Edge = std::make_pair(I->getParent(), AliveSuccessor->getParent());
4926 if (AssumedLiveEdges.insert(Edge).second)
4927 Change = ChangeStatus::CHANGED;
4928 if (assumeLive(A, *AliveSuccessor->getParent()))
4929 Worklist.push_back(AliveSuccessor);
4930 }
4931 }
4932 }
4933
4934 // Check if the content of ToBeExploredFrom changed, ignore the order.
4935 if (NewToBeExploredFrom.size() != ToBeExploredFrom.size() ||
4936 llvm::any_of(NewToBeExploredFrom, [&](const Instruction *I) {
4937 return !ToBeExploredFrom.count(I);
4938 })) {
4939 Change = ChangeStatus::CHANGED;
4940 ToBeExploredFrom = std::move(NewToBeExploredFrom);
4941 }
4942
4943 // If we know everything is live there is no need to query for liveness.
4944 // Instead, indicating a pessimistic fixpoint will cause the state to be
4945 // "invalid" and all queries to be answered conservatively without lookups.
4946 // To be in this state we have to (1) finished the exploration and (3) not
4947 // discovered any non-trivial dead end and (2) not ruled unreachable code
4948 // dead.
4949 if (ToBeExploredFrom.empty() &&
4950 getAnchorScope()->size() == AssumedLiveBlocks.size() &&
4951 llvm::all_of(KnownDeadEnds, [](const Instruction *DeadEndI) {
4952 return DeadEndI->isTerminator() && DeadEndI->getNumSuccessors() == 0;
4953 }))
4954 return indicatePessimisticFixpoint();
4955 return Change;
4956}
4957
4958/// Liveness information for a call sites.
4959struct AAIsDeadCallSite final : AAIsDeadFunction {
4960 AAIsDeadCallSite(const IRPosition &IRP, Attributor &A)
4961 : AAIsDeadFunction(IRP, A) {}
4962
4963 /// See AbstractAttribute::initialize(...).
4964 void initialize(Attributor &A) override {
4965 // TODO: Once we have call site specific value information we can provide
4966 // call site specific liveness information and then it makes
4967 // sense to specialize attributes for call sites instead of
4968 // redirecting requests to the callee.
4969 llvm_unreachable("Abstract attributes for liveness are not "
4970 "supported for call sites yet!");
4971 }
4972
4973 /// See AbstractAttribute::updateImpl(...).
4974 ChangeStatus updateImpl(Attributor &A) override {
4975 return indicatePessimisticFixpoint();
4976 }
4977
4978 /// See AbstractAttribute::trackStatistics()
4979 void trackStatistics() const override {}
4980};
4981} // namespace
4982
4983/// -------------------- Dereferenceable Argument Attribute --------------------
4984
4985namespace {
4986struct AADereferenceableImpl : AADereferenceable {
4987 AADereferenceableImpl(const IRPosition &IRP, Attributor &A)
4988 : AADereferenceable(IRP, A) {}
4989 using StateType = DerefState;
4990
4991 /// See AbstractAttribute::initialize(...).
4992 void initialize(Attributor &A) override {
4993 Value &V = *getAssociatedValue().stripPointerCasts();
4995 A.getAttrs(getIRPosition(),
4996 {Attribute::Dereferenceable, Attribute::DereferenceableOrNull},
4997 Attrs, /* IgnoreSubsumingPositions */ false);
4998 for (const Attribute &Attr : Attrs)
4999 takeKnownDerefBytesMaximum(Attr.getValueAsInt());
5000
5001 // Ensure we initialize the non-null AA (if necessary).
5002 bool IsKnownNonNull;
5004 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNonNull);
5005
5006 bool CanBeNull;
5007 takeKnownDerefBytesMaximum(V.getPointerDereferenceableBytes(
5008 A.getDataLayout(), CanBeNull, /*CanBeFreed=*/nullptr));
5009
5010 if (Instruction *CtxI = getCtxI())
5011 followUsesInMBEC(*this, A, getState(), *CtxI);
5012 }
5013
5014 /// See AbstractAttribute::getState()
5015 /// {
5016 StateType &getState() override { return *this; }
5017 const StateType &getState() const override { return *this; }
5018 /// }
5019
5020 /// Helper function for collecting accessed bytes in must-be-executed-context
5021 void addAccessedBytesForUse(Attributor &A, const Use *U, const Instruction *I,
5022 DerefState &State) {
5023 const Value *UseV = U->get();
5024 if (!UseV->getType()->isPointerTy())
5025 return;
5026
5027 std::optional<MemoryLocation> Loc = MemoryLocation::getOrNone(I);
5028 if (!Loc || Loc->Ptr != UseV || !Loc->Size.isPrecise() || I->isVolatile())
5029 return;
5030
5031 int64_t Offset;
5033 Loc->Ptr, Offset, A.getDataLayout(), /*AllowNonInbounds*/ true);
5034 if (Base && Base == &getAssociatedValue())
5035 State.addAccessedBytes(Offset, Loc->Size.getValue());
5036 }
5037
5038 /// See followUsesInMBEC
5039 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
5040 AADereferenceable::StateType &State) {
5041 bool IsNonNull = false;
5042 bool TrackUse = false;
5043 int64_t DerefBytes = getKnownNonNullAndDerefBytesForUse(
5044 A, *this, getAssociatedValue(), U, I, IsNonNull, TrackUse);
5045 LLVM_DEBUG(dbgs() << "[AADereferenceable] Deref bytes: " << DerefBytes
5046 << " for instruction " << *I << "\n");
5047
5048 addAccessedBytesForUse(A, U, I, State);
5049 State.takeKnownDerefBytesMaximum(DerefBytes);
5050 return TrackUse;
5051 }
5052
5053 /// See AbstractAttribute::manifest(...).
5054 ChangeStatus manifest(Attributor &A) override {
5055 ChangeStatus Change = AADereferenceable::manifest(A);
5056 bool IsKnownNonNull;
5057 bool IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>(
5058 A, this, getIRPosition(), DepClassTy::NONE, IsKnownNonNull);
5059 if (IsAssumedNonNull &&
5060 A.hasAttr(getIRPosition(), Attribute::DereferenceableOrNull)) {
5061 A.removeAttrs(getIRPosition(), {Attribute::DereferenceableOrNull});
5062 return ChangeStatus::CHANGED;
5063 }
5064 return Change;
5065 }
5066
5067 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
5068 SmallVectorImpl<Attribute> &Attrs) const override {
5069 // TODO: Add *_globally support
5070 bool IsKnownNonNull;
5071 bool IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>(
5072 A, this, getIRPosition(), DepClassTy::NONE, IsKnownNonNull);
5073 if (IsAssumedNonNull)
5074 Attrs.emplace_back(Attribute::getWithDereferenceableBytes(
5075 Ctx, getAssumedDereferenceableBytes()));
5076 else
5077 Attrs.emplace_back(Attribute::getWithDereferenceableOrNullBytes(
5078 Ctx, getAssumedDereferenceableBytes()));
5079 }
5080
5081 /// See AbstractAttribute::getAsStr().
5082 const std::string getAsStr(Attributor *A) const override {
5083 if (!getAssumedDereferenceableBytes())
5084 return "unknown-dereferenceable";
5085 bool IsKnownNonNull;
5086 bool IsAssumedNonNull = false;
5087 if (A)
5089 *A, this, getIRPosition(), DepClassTy::NONE, IsKnownNonNull);
5090 return std::string("dereferenceable") +
5091 (IsAssumedNonNull ? "" : "_or_null") +
5092 (isAssumedGlobal() ? "_globally" : "") + "<" +
5093 std::to_string(getKnownDereferenceableBytes()) + "-" +
5094 std::to_string(getAssumedDereferenceableBytes()) + ">" +
5095 (!A ? " [non-null is unknown]" : "");
5096 }
5097};
5098
5099/// Dereferenceable attribute for a floating value.
5100struct AADereferenceableFloating : AADereferenceableImpl {
5101 AADereferenceableFloating(const IRPosition &IRP, Attributor &A)
5102 : AADereferenceableImpl(IRP, A) {}
5103
5104 /// See AbstractAttribute::updateImpl(...).
5105 ChangeStatus updateImpl(Attributor &A) override {
5106 bool Stripped;
5107 bool UsedAssumedInformation = false;
5109 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
5110 AA::AnyScope, UsedAssumedInformation)) {
5111 Values.push_back({getAssociatedValue(), getCtxI()});
5112 Stripped = false;
5113 } else {
5114 Stripped = Values.size() != 1 ||
5115 Values.front().getValue() != &getAssociatedValue();
5116 }
5117
5118 const DataLayout &DL = A.getDataLayout();
5119 DerefState T;
5120
5121 auto VisitValueCB = [&](const Value &V) -> bool {
5122 unsigned IdxWidth =
5123 DL.getIndexSizeInBits(V.getType()->getPointerAddressSpace());
5124 APInt Offset(IdxWidth, 0);
5126 A, *this, &V, DL, Offset, /* GetMinOffset */ false,
5127 /* AllowNonInbounds */ true);
5128
5129 const auto *AA = A.getAAFor<AADereferenceable>(
5130 *this, IRPosition::value(*Base), DepClassTy::REQUIRED);
5131 int64_t DerefBytes = 0;
5132 if (!AA || (!Stripped && this == AA)) {
5133 // Use IR information if we did not strip anything.
5134 // TODO: track globally.
5135 bool CanBeNull;
5136 DerefBytes = Base->getPointerDereferenceableBytes(
5137 DL, CanBeNull, /*CanBeFreed=*/nullptr);
5138 T.GlobalState.indicatePessimisticFixpoint();
5139 } else {
5140 const DerefState &DS = AA->getState();
5141 DerefBytes = DS.DerefBytesState.getAssumed();
5142 T.GlobalState &= DS.GlobalState;
5143 }
5144
5145 // For now we do not try to "increase" dereferenceability due to negative
5146 // indices as we first have to come up with code to deal with loops and
5147 // for overflows of the dereferenceable bytes.
5148 int64_t OffsetSExt = Offset.getSExtValue();
5149 if (OffsetSExt < 0)
5150 OffsetSExt = 0;
5151
5152 T.takeAssumedDerefBytesMinimum(
5153 std::max(int64_t(0), DerefBytes - OffsetSExt));
5154
5155 if (this == AA) {
5156 if (!Stripped) {
5157 // If nothing was stripped IR information is all we got.
5158 T.takeKnownDerefBytesMaximum(
5159 std::max(int64_t(0), DerefBytes - OffsetSExt));
5160 T.indicatePessimisticFixpoint();
5161 } else if (OffsetSExt > 0) {
5162 // If something was stripped but there is circular reasoning we look
5163 // for the offset. If it is positive we basically decrease the
5164 // dereferenceable bytes in a circular loop now, which will simply
5165 // drive them down to the known value in a very slow way which we
5166 // can accelerate.
5167 T.indicatePessimisticFixpoint();
5168 }
5169 }
5170
5171 return T.isValidState();
5172 };
5173
5174 for (const auto &VAC : Values)
5175 if (!VisitValueCB(*VAC.getValue()))
5176 return indicatePessimisticFixpoint();
5177
5178 return clampStateAndIndicateChange(getState(), T);
5179 }
5180
5181 /// See AbstractAttribute::trackStatistics()
5182 void trackStatistics() const override {
5183 STATS_DECLTRACK_FLOATING_ATTR(dereferenceable)
5184 }
5185};
5186
5187/// Dereferenceable attribute for a return value.
5188struct AADereferenceableReturned final
5189 : AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl> {
5190 using Base =
5191 AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl>;
5192 AADereferenceableReturned(const IRPosition &IRP, Attributor &A)
5193 : Base(IRP, A) {}
5194
5195 /// See AbstractAttribute::trackStatistics()
5196 void trackStatistics() const override {
5197 STATS_DECLTRACK_FNRET_ATTR(dereferenceable)
5198 }
5199};
5200
5201/// Dereferenceable attribute for an argument
5202struct AADereferenceableArgument final
5203 : AAArgumentFromCallSiteArguments<AADereferenceable,
5204 AADereferenceableImpl> {
5205 using Base =
5206 AAArgumentFromCallSiteArguments<AADereferenceable, AADereferenceableImpl>;
5207 AADereferenceableArgument(const IRPosition &IRP, Attributor &A)
5208 : Base(IRP, A) {}
5209
5210 /// See AbstractAttribute::trackStatistics()
5211 void trackStatistics() const override {
5212 STATS_DECLTRACK_ARG_ATTR(dereferenceable)
5213 }
5214};
5215
5216/// Dereferenceable attribute for a call site argument.
5217struct AADereferenceableCallSiteArgument final : AADereferenceableFloating {
5218 AADereferenceableCallSiteArgument(const IRPosition &IRP, Attributor &A)
5219 : AADereferenceableFloating(IRP, A) {}
5220
5221 /// See AbstractAttribute::trackStatistics()
5222 void trackStatistics() const override {
5223 STATS_DECLTRACK_CSARG_ATTR(dereferenceable)
5224 }
5225};
5226
5227/// Dereferenceable attribute deduction for a call site return value.
5228struct AADereferenceableCallSiteReturned final
5229 : AACalleeToCallSite<AADereferenceable, AADereferenceableImpl> {
5230 using Base = AACalleeToCallSite<AADereferenceable, AADereferenceableImpl>;
5231 AADereferenceableCallSiteReturned(const IRPosition &IRP, Attributor &A)
5232 : Base(IRP, A) {}
5233
5234 /// See AbstractAttribute::trackStatistics()
5235 void trackStatistics() const override {
5236 STATS_DECLTRACK_CS_ATTR(dereferenceable);
5237 }
5238};
5239} // namespace
5240
5241// ------------------------ Align Argument Attribute ------------------------
5242
5243namespace {
5244
5245static unsigned getKnownAlignForUse(Attributor &A, AAAlign &QueryingAA,
5246 Value &AssociatedValue, const Use *U,
5247 const Instruction *I, bool &TrackUse) {
5248 // We need to follow common pointer manipulation uses to the accesses they
5249 // feed into.
5250 if (isa<CastInst>(I)) {
5251 // Follow all but ptr2int casts.
5252 TrackUse = !isa<PtrToIntInst>(I);
5253 return 0;
5254 }
5255 if (auto *GEP = dyn_cast<GetElementPtrInst>(I)) {
5256 if (GEP->hasAllConstantIndices())
5257 TrackUse = true;
5258 return 0;
5259 }
5260 if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(I))
5261 switch (II->getIntrinsicID()) {
5262 case Intrinsic::ptrmask: {
5263 // Is it appropriate to pull attribute in initialization?
5264 const auto *ConstVals = A.getAAFor<AAPotentialConstantValues>(
5265 QueryingAA, IRPosition::value(*II->getOperand(1)), DepClassTy::NONE);
5266 const auto *AlignAA = A.getAAFor<AAAlign>(
5267 QueryingAA, IRPosition::value(*II), DepClassTy::NONE);
5268 if (ConstVals && ConstVals->isValidState() && ConstVals->isAtFixpoint()) {
5269 unsigned ShiftValue = std::min(ConstVals->getAssumedMinTrailingZeros(),
5271 Align ConstAlign(UINT64_C(1) << ShiftValue);
5272 if (ConstAlign >= AlignAA->getKnownAlign())
5273 return Align(1).value();
5274 }
5275 if (AlignAA)
5276 return AlignAA->getKnownAlign().value();
5277 break;
5278 }
5279 case Intrinsic::amdgcn_make_buffer_rsrc: {
5280 const auto *AlignAA = A.getAAFor<AAAlign>(
5281 QueryingAA, IRPosition::value(*II), DepClassTy::NONE);
5282 if (AlignAA)
5283 return AlignAA->getKnownAlign().value();
5284 break;
5285 }
5286 default:
5287 break;
5288 }
5289
5290 MaybeAlign MA;
5291 if (const auto *CB = dyn_cast<CallBase>(I)) {
5292 if (CB->isBundleOperand(U) || CB->isCallee(U))
5293 return 0;
5294
5295 unsigned ArgNo = CB->getArgOperandNo(U);
5296 IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo);
5297 // As long as we only use known information there is no need to track
5298 // dependences here.
5299 auto *AlignAA = A.getAAFor<AAAlign>(QueryingAA, IRP, DepClassTy::NONE);
5300 if (AlignAA)
5301 MA = MaybeAlign(AlignAA->getKnownAlign());
5302 }
5303
5304 const DataLayout &DL = A.getDataLayout();
5305 const Value *UseV = U->get();
5306 if (auto *SI = dyn_cast<StoreInst>(I)) {
5307 if (SI->getPointerOperand() == UseV)
5308 MA = SI->getAlign();
5309 } else if (auto *LI = dyn_cast<LoadInst>(I)) {
5310 if (LI->getPointerOperand() == UseV)
5311 MA = LI->getAlign();
5312 } else if (auto *AI = dyn_cast<AtomicRMWInst>(I)) {
5313 if (AI->getPointerOperand() == UseV)
5314 MA = AI->getAlign();
5315 } else if (auto *AI = dyn_cast<AtomicCmpXchgInst>(I)) {
5316 if (AI->getPointerOperand() == UseV)
5317 MA = AI->getAlign();
5318 }
5319
5320 if (!MA || *MA <= QueryingAA.getKnownAlign())
5321 return 0;
5322
5323 unsigned Alignment = MA->value();
5324 int64_t Offset;
5325
5326 if (const Value *Base = GetPointerBaseWithConstantOffset(UseV, Offset, DL)) {
5327 if (Base == &AssociatedValue) {
5328 // BasePointerAddr + Offset = Alignment * Q for some integer Q.
5329 // So we can say that the maximum power of two which is a divisor of
5330 // gcd(Offset, Alignment) is an alignment.
5331
5332 uint32_t gcd = std::gcd(uint32_t(abs((int32_t)Offset)), Alignment);
5333 Alignment = llvm::bit_floor(gcd);
5334 }
5335 }
5336
5337 return Alignment;
5338}
5339
5340struct AAAlignImpl : AAAlign {
5341 AAAlignImpl(const IRPosition &IRP, Attributor &A) : AAAlign(IRP, A) {}
5342
5343 /// See AbstractAttribute::initialize(...).
5344 void initialize(Attributor &A) override {
5346 A.getAttrs(getIRPosition(), {Attribute::Alignment}, Attrs);
5347 for (const Attribute &Attr : Attrs)
5348 takeKnownMaximum(Attr.getValueAsInt());
5349
5350 Value &V = *getAssociatedValue().stripPointerCasts();
5351 takeKnownMaximum(V.getPointerAlignment(A.getDataLayout()).value());
5352
5353 if (Instruction *CtxI = getCtxI())
5354 followUsesInMBEC(*this, A, getState(), *CtxI);
5355 }
5356
5357 /// See AbstractAttribute::manifest(...).
5358 ChangeStatus manifest(Attributor &A) override {
5359 ChangeStatus InstrChanged = ChangeStatus::UNCHANGED;
5360
5361 // Check for users that allow alignment annotations.
5362 Value &AssociatedValue = getAssociatedValue();
5363 if (isa<ConstantData>(AssociatedValue))
5364 return ChangeStatus::UNCHANGED;
5365
5366 for (const Use &U : AssociatedValue.uses()) {
5367 if (auto *SI = dyn_cast<StoreInst>(U.getUser())) {
5368 if (SI->getPointerOperand() == &AssociatedValue)
5369 if (SI->getAlign() < getAssumedAlign()) {
5370 STATS_DECLTRACK(AAAlign, Store,
5371 "Number of times alignment added to a store");
5372 SI->setAlignment(getAssumedAlign());
5373 InstrChanged = ChangeStatus::CHANGED;
5374 }
5375 } else if (auto *LI = dyn_cast<LoadInst>(U.getUser())) {
5376 if (LI->getPointerOperand() == &AssociatedValue)
5377 if (LI->getAlign() < getAssumedAlign()) {
5378 LI->setAlignment(getAssumedAlign());
5379 STATS_DECLTRACK(AAAlign, Load,
5380 "Number of times alignment added to a load");
5381 InstrChanged = ChangeStatus::CHANGED;
5382 }
5383 } else if (auto *RMW = dyn_cast<AtomicRMWInst>(U.getUser())) {
5384 if (RMW->getPointerOperand() == &AssociatedValue) {
5385 if (RMW->getAlign() < getAssumedAlign()) {
5386 STATS_DECLTRACK(AAAlign, AtomicRMW,
5387 "Number of times alignment added to atomicrmw");
5388
5389 RMW->setAlignment(getAssumedAlign());
5390 InstrChanged = ChangeStatus::CHANGED;
5391 }
5392 }
5393 } else if (auto *CAS = dyn_cast<AtomicCmpXchgInst>(U.getUser())) {
5394 if (CAS->getPointerOperand() == &AssociatedValue) {
5395 if (CAS->getAlign() < getAssumedAlign()) {
5396 STATS_DECLTRACK(AAAlign, AtomicCmpXchg,
5397 "Number of times alignment added to cmpxchg");
5398 CAS->setAlignment(getAssumedAlign());
5399 InstrChanged = ChangeStatus::CHANGED;
5400 }
5401 }
5402 }
5403 }
5404
5405 ChangeStatus Changed = AAAlign::manifest(A);
5406
5407 Align InheritAlign =
5408 getAssociatedValue().getPointerAlignment(A.getDataLayout());
5409 if (InheritAlign >= getAssumedAlign())
5410 return InstrChanged;
5411 return Changed | InstrChanged;
5412 }
5413
5414 // TODO: Provide a helper to determine the implied ABI alignment and check in
5415 // the existing manifest method and a new one for AAAlignImpl that value
5416 // to avoid making the alignment explicit if it did not improve.
5417
5418 /// See AbstractAttribute::getDeducedAttributes
5419 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
5420 SmallVectorImpl<Attribute> &Attrs) const override {
5421 if (getAssumedAlign() > 1)
5422 Attrs.emplace_back(
5423 Attribute::getWithAlignment(Ctx, Align(getAssumedAlign())));
5424 }
5425
5426 /// See followUsesInMBEC
5427 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
5428 AAAlign::StateType &State) {
5429 bool TrackUse = false;
5430
5431 unsigned int KnownAlign =
5432 getKnownAlignForUse(A, *this, getAssociatedValue(), U, I, TrackUse);
5433 State.takeKnownMaximum(KnownAlign);
5434
5435 return TrackUse;
5436 }
5437
5438 /// See AbstractAttribute::getAsStr().
5439 const std::string getAsStr(Attributor *A) const override {
5440 return "align<" + std::to_string(getKnownAlign().value()) + "-" +
5441 std::to_string(getAssumedAlign().value()) + ">";
5442 }
5443};
5444
5445/// Align attribute for a floating value.
5446struct AAAlignFloating : AAAlignImpl {
5447 AAAlignFloating(const IRPosition &IRP, Attributor &A) : AAAlignImpl(IRP, A) {}
5448
5449 /// See AbstractAttribute::updateImpl(...).
5450 ChangeStatus updateImpl(Attributor &A) override {
5451 const DataLayout &DL = A.getDataLayout();
5452
5453 bool Stripped;
5454 bool UsedAssumedInformation = false;
5456 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
5457 AA::AnyScope, UsedAssumedInformation)) {
5458 Values.push_back({getAssociatedValue(), getCtxI()});
5459 Stripped = false;
5460 } else {
5461 Stripped = Values.size() != 1 ||
5462 Values.front().getValue() != &getAssociatedValue();
5463 }
5464
5465 StateType T;
5466 auto VisitValueCB = [&](Value &V) -> bool {
5468 return true;
5469 const auto *AA = A.getAAFor<AAAlign>(*this, IRPosition::value(V),
5470 DepClassTy::REQUIRED);
5471 if (!AA || (!Stripped && this == AA)) {
5472 int64_t Offset;
5473 unsigned Alignment = 1;
5474 if (const Value *Base =
5476 // TODO: Use AAAlign for the base too.
5477 Align PA = Base->getPointerAlignment(DL);
5478 // BasePointerAddr + Offset = Alignment * Q for some integer Q.
5479 // So we can say that the maximum power of two which is a divisor of
5480 // gcd(Offset, Alignment) is an alignment.
5481
5482 uint32_t gcd =
5483 std::gcd(uint32_t(abs((int32_t)Offset)), uint32_t(PA.value()));
5484 Alignment = llvm::bit_floor(gcd);
5485 } else {
5486 Alignment = V.getPointerAlignment(DL).value();
5487 }
5488 // Use only IR information if we did not strip anything.
5489 T.takeKnownMaximum(Alignment);
5490 T.indicatePessimisticFixpoint();
5491 } else {
5492 // Use abstract attribute information.
5493 const AAAlign::StateType &DS = AA->getState();
5494 T ^= DS;
5495 }
5496 return T.isValidState();
5497 };
5498
5499 for (const auto &VAC : Values) {
5500 if (!VisitValueCB(*VAC.getValue()))
5501 return indicatePessimisticFixpoint();
5502 }
5503
5504 // TODO: If we know we visited all incoming values, thus no are assumed
5505 // dead, we can take the known information from the state T.
5506 return clampStateAndIndicateChange(getState(), T);
5507 }
5508
5509 /// See AbstractAttribute::trackStatistics()
5510 void trackStatistics() const override { STATS_DECLTRACK_FLOATING_ATTR(align) }
5511};
5512
5513/// Align attribute for function return value.
5514struct AAAlignReturned final
5515 : AAReturnedFromReturnedValues<AAAlign, AAAlignImpl> {
5516 using Base = AAReturnedFromReturnedValues<AAAlign, AAAlignImpl>;
5517 AAAlignReturned(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {}
5518
5519 /// See AbstractAttribute::trackStatistics()
5520 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(aligned) }
5521};
5522
5523/// Align attribute for function argument.
5524struct AAAlignArgument final
5525 : AAArgumentFromCallSiteArguments<AAAlign, AAAlignImpl> {
5526 using Base = AAArgumentFromCallSiteArguments<AAAlign, AAAlignImpl>;
5527 AAAlignArgument(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {}
5528
5529 /// See AbstractAttribute::manifest(...).
5530 ChangeStatus manifest(Attributor &A) override {
5531 // If the associated argument is involved in a must-tail call we give up
5532 // because we would need to keep the argument alignments of caller and
5533 // callee in-sync. Just does not seem worth the trouble right now.
5534 if (A.getInfoCache().isInvolvedInMustTailCall(*getAssociatedArgument()))
5535 return ChangeStatus::UNCHANGED;
5536 return Base::manifest(A);
5537 }
5538
5539 /// See AbstractAttribute::trackStatistics()
5540 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(aligned) }
5541};
5542
5543struct AAAlignCallSiteArgument final : AAAlignFloating {
5544 AAAlignCallSiteArgument(const IRPosition &IRP, Attributor &A)
5545 : AAAlignFloating(IRP, A) {}
5546
5547 /// See AbstractAttribute::manifest(...).
5548 ChangeStatus manifest(Attributor &A) override {
5549 // If the associated argument is involved in a must-tail call we give up
5550 // because we would need to keep the argument alignments of caller and
5551 // callee in-sync. Just does not seem worth the trouble right now.
5552 if (Argument *Arg = getAssociatedArgument())
5553 if (A.getInfoCache().isInvolvedInMustTailCall(*Arg))
5554 return ChangeStatus::UNCHANGED;
5555 ChangeStatus Changed = AAAlignImpl::manifest(A);
5556 Align InheritAlign =
5557 getAssociatedValue().getPointerAlignment(A.getDataLayout());
5558 if (InheritAlign >= getAssumedAlign())
5559 Changed = ChangeStatus::UNCHANGED;
5560 return Changed;
5561 }
5562
5563 /// See AbstractAttribute::updateImpl(Attributor &A).
5564 ChangeStatus updateImpl(Attributor &A) override {
5565 ChangeStatus Changed = AAAlignFloating::updateImpl(A);
5566 if (Argument *Arg = getAssociatedArgument()) {
5567 // We only take known information from the argument
5568 // so we do not need to track a dependence.
5569 const auto *ArgAlignAA = A.getAAFor<AAAlign>(
5570 *this, IRPosition::argument(*Arg), DepClassTy::NONE);
5571 if (ArgAlignAA)
5572 takeKnownMaximum(ArgAlignAA->getKnownAlign().value());
5573 }
5574 return Changed;
5575 }
5576
5577 /// See AbstractAttribute::trackStatistics()
5578 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(aligned) }
5579};
5580
5581/// Align attribute deduction for a call site return value.
5582struct AAAlignCallSiteReturned final
5583 : AACalleeToCallSite<AAAlign, AAAlignImpl> {
5584 using Base = AACalleeToCallSite<AAAlign, AAAlignImpl>;
5585 AAAlignCallSiteReturned(const IRPosition &IRP, Attributor &A)
5586 : Base(IRP, A) {}
5587
5588 ChangeStatus updateImpl(Attributor &A) override {
5589 Instruction *I = getIRPosition().getCtxI();
5590 if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) {
5591 switch (II->getIntrinsicID()) {
5592 case Intrinsic::ptrmask: {
5593 Align Alignment;
5594 bool Valid = false;
5595
5596 const auto *ConstVals = A.getAAFor<AAPotentialConstantValues>(
5597 *this, IRPosition::value(*II->getOperand(1)), DepClassTy::REQUIRED);
5598 if (ConstVals && ConstVals->isValidState()) {
5599 unsigned ShiftValue =
5600 std::min(ConstVals->getAssumedMinTrailingZeros(),
5601 Value::MaxAlignmentExponent);
5602 Alignment = Align(UINT64_C(1) << ShiftValue);
5603 Valid = true;
5604 }
5605
5606 const auto *AlignAA =
5607 A.getAAFor<AAAlign>(*this, IRPosition::value(*(II->getOperand(0))),
5608 DepClassTy::REQUIRED);
5609 if (AlignAA) {
5610 Alignment = std::max(AlignAA->getAssumedAlign(), Alignment);
5611 Valid = true;
5612 }
5613
5614 if (Valid)
5616 this->getState(),
5617 std::min(this->getAssumedAlign(), Alignment).value());
5618 break;
5619 }
5620 // FIXME: Should introduce target specific sub-attributes and letting
5621 // getAAfor<AAAlign> lead to create sub-attribute to handle target
5622 // specific intrinsics.
5623 case Intrinsic::amdgcn_make_buffer_rsrc: {
5624 const auto *AlignAA =
5625 A.getAAFor<AAAlign>(*this, IRPosition::value(*(II->getOperand(0))),
5626 DepClassTy::REQUIRED);
5627 if (AlignAA)
5629 this->getState(), AlignAA->getAssumedAlign().value());
5630 break;
5631 }
5632 default:
5633 break;
5634 }
5635 }
5636 return Base::updateImpl(A);
5637 };
5638 /// See AbstractAttribute::trackStatistics()
5639 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(align); }
5640};
5641} // namespace
5642
5643/// ------------------ Function No-Return Attribute ----------------------------
5644namespace {
5645struct AANoReturnImpl : public AANoReturn {
5646 AANoReturnImpl(const IRPosition &IRP, Attributor &A) : AANoReturn(IRP, A) {}
5647
5648 /// See AbstractAttribute::initialize(...).
5649 void initialize(Attributor &A) override {
5650 bool IsKnown;
5652 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
5653 (void)IsKnown;
5654 }
5655
5656 /// See AbstractAttribute::getAsStr().
5657 const std::string getAsStr(Attributor *A) const override {
5658 return getAssumed() ? "noreturn" : "may-return";
5659 }
5660
5661 /// See AbstractAttribute::updateImpl(Attributor &A).
5662 ChangeStatus updateImpl(Attributor &A) override {
5663 auto CheckForNoReturn = [](Instruction &) { return false; };
5664 bool UsedAssumedInformation = false;
5665 if (!A.checkForAllInstructions(CheckForNoReturn, *this,
5666 {(unsigned)Instruction::Ret},
5667 UsedAssumedInformation))
5668 return indicatePessimisticFixpoint();
5669 return ChangeStatus::UNCHANGED;
5670 }
5671};
5672
5673struct AANoReturnFunction final : AANoReturnImpl {
5674 AANoReturnFunction(const IRPosition &IRP, Attributor &A)
5675 : AANoReturnImpl(IRP, A) {}
5676
5677 /// See AbstractAttribute::trackStatistics()
5678 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(noreturn) }
5679};
5680
5681/// NoReturn attribute deduction for a call sites.
5682struct AANoReturnCallSite final
5683 : AACalleeToCallSite<AANoReturn, AANoReturnImpl> {
5684 AANoReturnCallSite(const IRPosition &IRP, Attributor &A)
5685 : AACalleeToCallSite<AANoReturn, AANoReturnImpl>(IRP, A) {}
5686
5687 /// See AbstractAttribute::trackStatistics()
5688 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(noreturn); }
5689};
5690} // namespace
5691
5692/// ----------------------- Instance Info ---------------------------------
5693
5694namespace {
5695/// A class to hold the state of for no-capture attributes.
5696struct AAInstanceInfoImpl : public AAInstanceInfo {
5697 AAInstanceInfoImpl(const IRPosition &IRP, Attributor &A)
5698 : AAInstanceInfo(IRP, A) {}
5699
5700 /// See AbstractAttribute::initialize(...).
5701 void initialize(Attributor &A) override {
5702 Value &V = getAssociatedValue();
5703 if (auto *C = dyn_cast<Constant>(&V)) {
5704 if (C->isThreadDependent())
5705 indicatePessimisticFixpoint();
5706 else
5707 indicateOptimisticFixpoint();
5708 return;
5709 }
5710 if (auto *CB = dyn_cast<CallBase>(&V))
5711 if (CB->arg_size() == 0 && !CB->mayHaveSideEffects() &&
5712 !CB->mayReadFromMemory()) {
5713 indicateOptimisticFixpoint();
5714 return;
5715 }
5716 if (auto *I = dyn_cast<Instruction>(&V)) {
5717 const auto *CI =
5718 A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>(
5719 *I->getFunction());
5720 if (mayBeInCycle(CI, I, /* HeaderOnly */ false)) {
5721 indicatePessimisticFixpoint();
5722 return;
5723 }
5724 }
5725 }
5726
5727 /// See AbstractAttribute::updateImpl(...).
5728 ChangeStatus updateImpl(Attributor &A) override {
5729 ChangeStatus Changed = ChangeStatus::UNCHANGED;
5730
5731 Value &V = getAssociatedValue();
5732 const Function *Scope = nullptr;
5733 if (auto *I = dyn_cast<Instruction>(&V))
5734 Scope = I->getFunction();
5735 if (auto *A = dyn_cast<Argument>(&V)) {
5736 Scope = A->getParent();
5737 if (!Scope->hasLocalLinkage())
5738 return Changed;
5739 }
5740 if (!Scope)
5741 return indicateOptimisticFixpoint();
5742
5743 bool IsKnownNoRecurse;
5745 A, this, IRPosition::function(*Scope), DepClassTy::OPTIONAL,
5746 IsKnownNoRecurse))
5747 return Changed;
5748
5749 auto UsePred = [&](const Use &U, bool &Follow) {
5750 const Instruction *UserI = dyn_cast<Instruction>(U.getUser());
5751 if (!UserI || isa<GetElementPtrInst>(UserI) || isa<CastInst>(UserI) ||
5752 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) {
5753 Follow = true;
5754 return true;
5755 }
5756 if (isa<LoadInst>(UserI) || isa<CmpInst>(UserI) ||
5757 (isa<StoreInst>(UserI) &&
5758 cast<StoreInst>(UserI)->getValueOperand() != U.get()))
5759 return true;
5760 if (auto *CB = dyn_cast<CallBase>(UserI)) {
5761 // This check is not guaranteeing uniqueness but for now that we cannot
5762 // end up with two versions of \p U thinking it was one.
5764 if (!Callee || !Callee->hasLocalLinkage())
5765 return true;
5766 if (!CB->isArgOperand(&U))
5767 return false;
5768 const auto *ArgInstanceInfoAA = A.getAAFor<AAInstanceInfo>(
5770 DepClassTy::OPTIONAL);
5771 if (!ArgInstanceInfoAA ||
5772 !ArgInstanceInfoAA->isAssumedUniqueForAnalysis())
5773 return false;
5774 // If this call base might reach the scope again we might forward the
5775 // argument back here. This is very conservative.
5777 A, *CB, *Scope, *this, /* ExclusionSet */ nullptr,
5778 [Scope](const Function &Fn) { return &Fn != Scope; }))
5779 return false;
5780 return true;
5781 }
5782 return false;
5783 };
5784
5785 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) {
5786 if (auto *SI = dyn_cast<StoreInst>(OldU.getUser())) {
5787 auto *Ptr = SI->getPointerOperand()->stripPointerCasts();
5788 if ((isa<AllocaInst>(Ptr) || isNoAliasCall(Ptr)) &&
5789 AA::isDynamicallyUnique(A, *this, *Ptr))
5790 return true;
5791 }
5792 return false;
5793 };
5794
5795 if (!A.checkForAllUses(UsePred, *this, V, /* CheckBBLivenessOnly */ true,
5796 DepClassTy::OPTIONAL,
5797 /* IgnoreDroppableUses */ true, EquivalentUseCB))
5798 return indicatePessimisticFixpoint();
5799
5800 return Changed;
5801 }
5802
5803 /// See AbstractState::getAsStr().
5804 const std::string getAsStr(Attributor *A) const override {
5805 return isAssumedUniqueForAnalysis() ? "<unique [fAa]>" : "<unknown>";
5806 }
5807
5808 /// See AbstractAttribute::trackStatistics()
5809 void trackStatistics() const override {}
5810};
5811
5812/// InstanceInfo attribute for floating values.
5813struct AAInstanceInfoFloating : AAInstanceInfoImpl {
5814 AAInstanceInfoFloating(const IRPosition &IRP, Attributor &A)
5815 : AAInstanceInfoImpl(IRP, A) {}
5816};
5817
5818/// NoCapture attribute for function arguments.
5819struct AAInstanceInfoArgument final : AAInstanceInfoFloating {
5820 AAInstanceInfoArgument(const IRPosition &IRP, Attributor &A)
5821 : AAInstanceInfoFloating(IRP, A) {}
5822};
5823
5824/// InstanceInfo attribute for call site arguments.
5825struct AAInstanceInfoCallSiteArgument final : AAInstanceInfoImpl {
5826 AAInstanceInfoCallSiteArgument(const IRPosition &IRP, Attributor &A)
5827 : AAInstanceInfoImpl(IRP, A) {}
5828
5829 /// See AbstractAttribute::updateImpl(...).
5830 ChangeStatus updateImpl(Attributor &A) override {
5831 // TODO: Once we have call site specific value information we can provide
5832 // call site specific liveness information and then it makes
5833 // sense to specialize attributes for call sites arguments instead of
5834 // redirecting requests to the callee argument.
5835 Argument *Arg = getAssociatedArgument();
5836 if (!Arg)
5837 return indicatePessimisticFixpoint();
5838 const IRPosition &ArgPos = IRPosition::argument(*Arg);
5839 auto *ArgAA =
5840 A.getAAFor<AAInstanceInfo>(*this, ArgPos, DepClassTy::REQUIRED);
5841 if (!ArgAA)
5842 return indicatePessimisticFixpoint();
5843 return clampStateAndIndicateChange(getState(), ArgAA->getState());
5844 }
5845};
5846
5847/// InstanceInfo attribute for function return value.
5848struct AAInstanceInfoReturned final : AAInstanceInfoImpl {
5849 AAInstanceInfoReturned(const IRPosition &IRP, Attributor &A)
5850 : AAInstanceInfoImpl(IRP, A) {
5851 llvm_unreachable("InstanceInfo is not applicable to function returns!");
5852 }
5853
5854 /// See AbstractAttribute::initialize(...).
5855 void initialize(Attributor &A) override {
5856 llvm_unreachable("InstanceInfo is not applicable to function returns!");
5857 }
5858
5859 /// See AbstractAttribute::updateImpl(...).
5860 ChangeStatus updateImpl(Attributor &A) override {
5861 llvm_unreachable("InstanceInfo is not applicable to function returns!");
5862 }
5863};
5864
5865/// InstanceInfo attribute deduction for a call site return value.
5866struct AAInstanceInfoCallSiteReturned final : AAInstanceInfoFloating {
5867 AAInstanceInfoCallSiteReturned(const IRPosition &IRP, Attributor &A)
5868 : AAInstanceInfoFloating(IRP, A) {}
5869};
5870} // namespace
5871
5872/// ----------------------- Variable Capturing ---------------------------------
5874 Attribute::AttrKind ImpliedAttributeKind,
5875 bool IgnoreSubsumingPositions) {
5876 assert(ImpliedAttributeKind == Attribute::Captures &&
5877 "Unexpected attribute kind");
5878 Value &V = IRP.getAssociatedValue();
5879 if (!isa<Constant>(V) && !IRP.isArgumentPosition())
5880 return V.use_empty();
5881
5882 // You cannot "capture" null in the default address space.
5883 //
5884 // FIXME: This should use NullPointerIsDefined to account for the function
5885 // attribute.
5887 V.getType()->getPointerAddressSpace() == 0)) {
5888 return true;
5889 }
5890
5892 A.getAttrs(IRP, {Attribute::Captures}, Attrs,
5893 /* IgnoreSubsumingPositions */ true);
5894 for (const Attribute &Attr : Attrs)
5895 if (capturesNothing(Attr.getCaptureInfo()))
5896 return true;
5897
5899 if (Argument *Arg = IRP.getAssociatedArgument()) {
5901 A.getAttrs(IRPosition::argument(*Arg),
5902 {Attribute::Captures, Attribute::ByVal}, Attrs,
5903 /* IgnoreSubsumingPositions */ true);
5904 bool ArgNoCapture = any_of(Attrs, [](Attribute Attr) {
5905 return Attr.getKindAsEnum() == Attribute::ByVal ||
5907 });
5908 if (ArgNoCapture) {
5909 A.manifestAttrs(IRP, Attribute::getWithCaptureInfo(
5910 V.getContext(), CaptureInfo::none()));
5911 return true;
5912 }
5913 }
5914
5915 if (const Function *F = IRP.getAssociatedFunction()) {
5916 // Check what state the associated function can actually capture.
5919 if (State.isKnown(NO_CAPTURE)) {
5920 A.manifestAttrs(IRP, Attribute::getWithCaptureInfo(V.getContext(),
5922 return true;
5923 }
5924 }
5925
5926 return false;
5927}
5928
5929/// Set the NOT_CAPTURED_IN_MEM and NOT_CAPTURED_IN_RET bits in \p Known
5930/// depending on the ability of the function associated with \p IRP to capture
5931/// state in memory and through "returning/throwing", respectively.
5933 const Function &F,
5934 BitIntegerState &State) {
5935 // TODO: Once we have memory behavior attributes we should use them here.
5936
5937 // If we know we cannot communicate or write to memory, we do not care about
5938 // ptr2int anymore.
5939 bool ReadOnly = F.onlyReadsMemory();
5940 bool NoThrow = F.doesNotThrow();
5941 bool IsVoidReturn = F.getReturnType()->isVoidTy();
5942 if (ReadOnly && NoThrow && IsVoidReturn) {
5943 State.addKnownBits(NO_CAPTURE);
5944 return;
5945 }
5946
5947 // A function cannot capture state in memory if it only reads memory, it can
5948 // however return/throw state and the state might be influenced by the
5949 // pointer value, e.g., loading from a returned pointer might reveal a bit.
5950 if (ReadOnly)
5951 State.addKnownBits(NOT_CAPTURED_IN_MEM);
5952
5953 // A function cannot communicate state back if it does not through
5954 // exceptions and doesn not return values.
5955 if (NoThrow && IsVoidReturn)
5956 State.addKnownBits(NOT_CAPTURED_IN_RET);
5957
5958 // Check existing "returned" attributes.
5959 int ArgNo = IRP.getCalleeArgNo();
5960 if (!NoThrow || ArgNo < 0 ||
5961 !F.getAttributes().hasAttrSomewhere(Attribute::Returned))
5962 return;
5963
5964 for (unsigned U = 0, E = F.arg_size(); U < E; ++U)
5965 if (F.hasParamAttribute(U, Attribute::Returned)) {
5966 if (U == unsigned(ArgNo))
5967 State.removeAssumedBits(NOT_CAPTURED_IN_RET);
5968 else if (ReadOnly)
5969 State.addKnownBits(NO_CAPTURE);
5970 else
5971 State.addKnownBits(NOT_CAPTURED_IN_RET);
5972 break;
5973 }
5974}
5975
5976namespace {
5977/// A class to hold the state of for no-capture attributes.
5978struct AANoCaptureImpl : public AANoCapture {
5979 AANoCaptureImpl(const IRPosition &IRP, Attributor &A) : AANoCapture(IRP, A) {}
5980
5981 /// See AbstractAttribute::initialize(...).
5982 void initialize(Attributor &A) override {
5983 bool IsKnown;
5985 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
5986 (void)IsKnown;
5987 }
5988
5989 /// See AbstractAttribute::updateImpl(...).
5990 ChangeStatus updateImpl(Attributor &A) override;
5991
5992 /// see AbstractAttribute::isAssumedNoCaptureMaybeReturned(...).
5993 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
5994 SmallVectorImpl<Attribute> &Attrs) const override {
5995 if (!isAssumedNoCaptureMaybeReturned())
5996 return;
5997
5998 if (isArgumentPosition()) {
5999 if (isAssumedNoCapture())
6000 Attrs.emplace_back(Attribute::get(Ctx, Attribute::Captures));
6001 else if (ManifestInternal)
6002 Attrs.emplace_back(Attribute::get(Ctx, "no-capture-maybe-returned"));
6003 }
6004 }
6005
6006 /// See AbstractState::getAsStr().
6007 const std::string getAsStr(Attributor *A) const override {
6008 if (isKnownNoCapture())
6009 return "known not-captured";
6010 if (isAssumedNoCapture())
6011 return "assumed not-captured";
6012 if (isKnownNoCaptureMaybeReturned())
6013 return "known not-captured-maybe-returned";
6014 if (isAssumedNoCaptureMaybeReturned())
6015 return "assumed not-captured-maybe-returned";
6016 return "assumed-captured";
6017 }
6018
6019 /// Check the use \p U and update \p State accordingly. Return true if we
6020 /// should continue to update the state.
6021 bool checkUse(Attributor &A, AANoCapture::StateType &State, const Use &U,
6022 bool &Follow) {
6023 Instruction *UInst = cast<Instruction>(U.getUser());
6024 LLVM_DEBUG(dbgs() << "[AANoCapture] Check use: " << *U.get() << " in "
6025 << *UInst << "\n");
6026
6027 // Deal with ptr2int by following uses.
6028 if (isa<PtrToIntInst>(UInst)) {
6029 LLVM_DEBUG(dbgs() << " - ptr2int assume the worst!\n");
6030 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
6031 /* Return */ true);
6032 }
6033
6034 // For stores we already checked if we can follow them, if they make it
6035 // here we give up.
6036 if (isa<StoreInst>(UInst))
6037 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
6038 /* Return */ true);
6039
6040 // Explicitly catch return instructions.
6041 if (isa<ReturnInst>(UInst)) {
6042 if (UInst->getFunction() == getAnchorScope())
6043 return isCapturedIn(State, /* Memory */ false, /* Integer */ false,
6044 /* Return */ true);
6045 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
6046 /* Return */ true);
6047 }
6048
6049 // For now we only use special logic for call sites. However, the tracker
6050 // itself knows about a lot of other non-capturing cases already.
6051 auto *CB = dyn_cast<CallBase>(UInst);
6052 if (!CB || !CB->isArgOperand(&U))
6053 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
6054 /* Return */ true);
6055
6056 unsigned ArgNo = CB->getArgOperandNo(&U);
6057 const IRPosition &CSArgPos = IRPosition::callsite_argument(*CB, ArgNo);
6058 // If we have a abstract no-capture attribute for the argument we can use
6059 // it to justify a non-capture attribute here. This allows recursion!
6060 bool IsKnownNoCapture;
6061 const AANoCapture *ArgNoCaptureAA = nullptr;
6062 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
6063 A, this, CSArgPos, DepClassTy::REQUIRED, IsKnownNoCapture, false,
6064 &ArgNoCaptureAA);
6065 if (IsAssumedNoCapture)
6066 return isCapturedIn(State, /* Memory */ false, /* Integer */ false,
6067 /* Return */ false);
6068 if (ArgNoCaptureAA && ArgNoCaptureAA->isAssumedNoCaptureMaybeReturned()) {
6069 Follow = true;
6070 return isCapturedIn(State, /* Memory */ false, /* Integer */ false,
6071 /* Return */ false);
6072 }
6073
6074 // Lastly, we could not find a reason no-capture can be assumed so we don't.
6075 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
6076 /* Return */ true);
6077 }
6078
6079 /// Update \p State according to \p CapturedInMem, \p CapturedInInt, and
6080 /// \p CapturedInRet, then return true if we should continue updating the
6081 /// state.
6082 static bool isCapturedIn(AANoCapture::StateType &State, bool CapturedInMem,
6083 bool CapturedInInt, bool CapturedInRet) {
6084 LLVM_DEBUG(dbgs() << " - captures [Mem " << CapturedInMem << "|Int "
6085 << CapturedInInt << "|Ret " << CapturedInRet << "]\n");
6086 if (CapturedInMem)
6087 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_MEM);
6088 if (CapturedInInt)
6089 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_INT);
6090 if (CapturedInRet)
6091 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_RET);
6092 return State.isAssumed(AANoCapture::NO_CAPTURE_MAYBE_RETURNED);
6093 }
6094};
6095
6096ChangeStatus AANoCaptureImpl::updateImpl(Attributor &A) {
6097 const IRPosition &IRP = getIRPosition();
6098 Value *V = isArgumentPosition() ? IRP.getAssociatedArgument()
6099 : &IRP.getAssociatedValue();
6100 if (!V)
6101 return indicatePessimisticFixpoint();
6102
6103 const Function *F =
6104 isArgumentPosition() ? IRP.getAssociatedFunction() : IRP.getAnchorScope();
6105
6106 // TODO: Is the checkForAllUses below useful for constants?
6107 if (!F)
6108 return indicatePessimisticFixpoint();
6109
6111 const IRPosition &FnPos = IRPosition::function(*F);
6112
6113 // Readonly means we cannot capture through memory.
6114 bool IsKnown;
6115 if (AA::isAssumedReadOnly(A, FnPos, *this, IsKnown)) {
6116 T.addKnownBits(NOT_CAPTURED_IN_MEM);
6117 if (IsKnown)
6118 addKnownBits(NOT_CAPTURED_IN_MEM);
6119 }
6120
6121 // Make sure all returned values are different than the underlying value.
6122 // TODO: we could do this in a more sophisticated way inside
6123 // AAReturnedValues, e.g., track all values that escape through returns
6124 // directly somehow.
6125 auto CheckReturnedArgs = [&](bool &UsedAssumedInformation) {
6127 if (!A.getAssumedSimplifiedValues(IRPosition::returned(*F), this, Values,
6129 UsedAssumedInformation))
6130 return false;
6131 bool SeenConstant = false;
6132 for (const AA::ValueAndContext &VAC : Values) {
6133 if (isa<Constant>(VAC.getValue())) {
6134 if (SeenConstant)
6135 return false;
6136 SeenConstant = true;
6137 } else if (!isa<Argument>(VAC.getValue()) ||
6138 VAC.getValue() == getAssociatedArgument())
6139 return false;
6140 }
6141 return true;
6142 };
6143
6144 bool IsKnownNoUnwind;
6146 A, this, FnPos, DepClassTy::OPTIONAL, IsKnownNoUnwind)) {
6147 bool IsVoidTy = F->getReturnType()->isVoidTy();
6148 bool UsedAssumedInformation = false;
6149 if (IsVoidTy || CheckReturnedArgs(UsedAssumedInformation)) {
6150 T.addKnownBits(NOT_CAPTURED_IN_RET);
6151 if (T.isKnown(NOT_CAPTURED_IN_MEM))
6153 if (IsKnownNoUnwind && (IsVoidTy || !UsedAssumedInformation)) {
6154 addKnownBits(NOT_CAPTURED_IN_RET);
6155 if (isKnown(NOT_CAPTURED_IN_MEM))
6156 return indicateOptimisticFixpoint();
6157 }
6158 }
6159 }
6160
6161 auto UseCheck = [&](const Use &U, bool &Follow) -> bool {
6162 // TODO(captures): Make this more precise.
6163 UseCaptureInfo CI = DetermineUseCaptureKind(U, /*Base=*/nullptr);
6164 if (capturesNothing(CI))
6165 return true;
6166 if (CI.isPassthrough()) {
6167 Follow = true;
6168 return true;
6169 }
6170 return checkUse(A, T, U, Follow);
6171 };
6172
6173 if (!A.checkForAllUses(UseCheck, *this, *V))
6174 return indicatePessimisticFixpoint();
6175
6176 AANoCapture::StateType &S = getState();
6177 auto Assumed = S.getAssumed();
6178 S.intersectAssumedBits(T.getAssumed());
6179 if (!isAssumedNoCaptureMaybeReturned())
6180 return indicatePessimisticFixpoint();
6181 return Assumed == S.getAssumed() ? ChangeStatus::UNCHANGED
6183}
6184
6185/// NoCapture attribute for function arguments.
6186struct AANoCaptureArgument final : AANoCaptureImpl {
6187 AANoCaptureArgument(const IRPosition &IRP, Attributor &A)
6188 : AANoCaptureImpl(IRP, A) {}
6189
6190 /// See AbstractAttribute::trackStatistics()
6191 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nocapture) }
6192};
6193
6194/// NoCapture attribute for call site arguments.
6195struct AANoCaptureCallSiteArgument final : AANoCaptureImpl {
6196 AANoCaptureCallSiteArgument(const IRPosition &IRP, Attributor &A)
6197 : AANoCaptureImpl(IRP, A) {}
6198
6199 /// See AbstractAttribute::updateImpl(...).
6200 ChangeStatus updateImpl(Attributor &A) override {
6201 // TODO: Once we have call site specific value information we can provide
6202 // call site specific liveness information and then it makes
6203 // sense to specialize attributes for call sites arguments instead of
6204 // redirecting requests to the callee argument.
6205 Argument *Arg = getAssociatedArgument();
6206 if (!Arg)
6207 return indicatePessimisticFixpoint();
6208 const IRPosition &ArgPos = IRPosition::argument(*Arg);
6209 bool IsKnownNoCapture;
6210 const AANoCapture *ArgAA = nullptr;
6212 A, this, ArgPos, DepClassTy::REQUIRED, IsKnownNoCapture, false,
6213 &ArgAA))
6214 return ChangeStatus::UNCHANGED;
6215 if (!ArgAA || !ArgAA->isAssumedNoCaptureMaybeReturned())
6216 return indicatePessimisticFixpoint();
6217 return clampStateAndIndicateChange(getState(), ArgAA->getState());
6218 }
6219
6220 /// See AbstractAttribute::trackStatistics()
6221 void trackStatistics() const override {
6223 };
6224};
6225
6226/// NoCapture attribute for floating values.
6227struct AANoCaptureFloating final : AANoCaptureImpl {
6228 AANoCaptureFloating(const IRPosition &IRP, Attributor &A)
6229 : AANoCaptureImpl(IRP, A) {}
6230
6231 /// See AbstractAttribute::trackStatistics()
6232 void trackStatistics() const override {
6234 }
6235};
6236
6237/// NoCapture attribute for function return value.
6238struct AANoCaptureReturned final : AANoCaptureImpl {
6239 AANoCaptureReturned(const IRPosition &IRP, Attributor &A)
6240 : AANoCaptureImpl(IRP, A) {
6241 llvm_unreachable("NoCapture is not applicable to function returns!");
6242 }
6243
6244 /// See AbstractAttribute::initialize(...).
6245 void initialize(Attributor &A) override {
6246 llvm_unreachable("NoCapture is not applicable to function returns!");
6247 }
6248
6249 /// See AbstractAttribute::updateImpl(...).
6250 ChangeStatus updateImpl(Attributor &A) override {
6251 llvm_unreachable("NoCapture is not applicable to function returns!");
6252 }
6253
6254 /// See AbstractAttribute::trackStatistics()
6255 void trackStatistics() const override {}
6256};
6257
6258/// NoCapture attribute deduction for a call site return value.
6259struct AANoCaptureCallSiteReturned final : AANoCaptureImpl {
6260 AANoCaptureCallSiteReturned(const IRPosition &IRP, Attributor &A)
6261 : AANoCaptureImpl(IRP, A) {}
6262
6263 /// See AbstractAttribute::initialize(...).
6264 void initialize(Attributor &A) override {
6265 const Function *F = getAnchorScope();
6266 // Check what state the associated function can actually capture.
6267 determineFunctionCaptureCapabilities(getIRPosition(), *F, *this);
6268 }
6269
6270 /// See AbstractAttribute::trackStatistics()
6271 void trackStatistics() const override {
6273 }
6274};
6275} // namespace
6276
6277/// ------------------ Value Simplify Attribute ----------------------------
6278
6279bool ValueSimplifyStateType::unionAssumed(std::optional<Value *> Other) {
6280 // FIXME: Add a typecast support.
6283 if (SimplifiedAssociatedValue == std::optional<Value *>(nullptr))
6284 return false;
6285
6286 LLVM_DEBUG({
6288 dbgs() << "[ValueSimplify] is assumed to be "
6289 << **SimplifiedAssociatedValue << "\n";
6290 else
6291 dbgs() << "[ValueSimplify] is assumed to be <none>\n";
6292 });
6293 return true;
6294}
6295
6296namespace {
6297struct AAValueSimplifyImpl : AAValueSimplify {
6298 AAValueSimplifyImpl(const IRPosition &IRP, Attributor &A)
6299 : AAValueSimplify(IRP, A) {}
6300
6301 /// See AbstractAttribute::initialize(...).
6302 void initialize(Attributor &A) override {
6303 if (getAssociatedValue().getType()->isVoidTy())
6304 indicatePessimisticFixpoint();
6305 if (A.hasSimplificationCallback(getIRPosition()))
6306 indicatePessimisticFixpoint();
6307 }
6308
6309 /// See AbstractAttribute::getAsStr().
6310 const std::string getAsStr(Attributor *A) const override {
6311 LLVM_DEBUG({
6312 dbgs() << "SAV: " << (bool)SimplifiedAssociatedValue << " ";
6313 if (SimplifiedAssociatedValue && *SimplifiedAssociatedValue)
6314 dbgs() << "SAV: " << **SimplifiedAssociatedValue << " ";
6315 });
6316 return isValidState() ? (isAtFixpoint() ? "simplified" : "maybe-simple")
6317 : "not-simple";
6318 }
6319
6320 /// See AbstractAttribute::trackStatistics()
6321 void trackStatistics() const override {}
6322
6323 /// See AAValueSimplify::getAssumedSimplifiedValue()
6324 std::optional<Value *>
6325 getAssumedSimplifiedValue(Attributor &A) const override {
6326 return SimplifiedAssociatedValue;
6327 }
6328
6329 /// Ensure the return value is \p V with type \p Ty, if not possible return
6330 /// nullptr. If \p Check is true we will only verify such an operation would
6331 /// suceed and return a non-nullptr value if that is the case. No IR is
6332 /// generated or modified.
6333 static Value *ensureType(Attributor &A, Value &V, Type &Ty, Instruction *CtxI,
6334 bool Check) {
6335 if (auto *TypedV = AA::getWithType(V, Ty))
6336 return TypedV;
6337 if (CtxI && V.getType()->canLosslesslyBitCastTo(&Ty))
6338 return Check ? &V
6339 : BitCastInst::CreatePointerBitCastOrAddrSpaceCast(
6340 &V, &Ty, "", CtxI->getIterator());
6341 return nullptr;
6342 }
6343
6344 /// Reproduce \p I with type \p Ty or return nullptr if that is not posisble.
6345 /// If \p Check is true we will only verify such an operation would suceed and
6346 /// return a non-nullptr value if that is the case. No IR is generated or
6347 /// modified.
6348 static Value *reproduceInst(Attributor &A,
6349 const AbstractAttribute &QueryingAA,
6350 Instruction &I, Type &Ty, Instruction *CtxI,
6351 bool Check, ValueToValueMapTy &VMap) {
6352 assert(CtxI && "Cannot reproduce an instruction without context!");
6353 if (Check && (I.mayReadFromMemory() ||
6354 !isSafeToSpeculativelyExecute(&I, CtxI, /* DT */ nullptr,
6355 /* TLI */ nullptr)))
6356 return nullptr;
6357 for (Value *Op : I.operands()) {
6358 Value *NewOp = reproduceValue(A, QueryingAA, *Op, Ty, CtxI, Check, VMap);
6359 if (!NewOp) {
6360 assert(Check && "Manifest of new value unexpectedly failed!");
6361 return nullptr;
6362 }
6363 if (!Check)
6364 VMap[Op] = NewOp;
6365 }
6366 if (Check)
6367 return &I;
6368
6369 Instruction *CloneI = I.clone();
6370 // TODO: Try to salvage debug information here.
6371 CloneI->setDebugLoc(DebugLoc());
6372 VMap[&I] = CloneI;
6373 CloneI->insertBefore(CtxI->getIterator());
6374 RemapInstruction(CloneI, VMap);
6375 return CloneI;
6376 }
6377
6378 /// Reproduce \p V with type \p Ty or return nullptr if that is not posisble.
6379 /// If \p Check is true we will only verify such an operation would suceed and
6380 /// return a non-nullptr value if that is the case. No IR is generated or
6381 /// modified.
6382 static Value *reproduceValue(Attributor &A,
6383 const AbstractAttribute &QueryingAA, Value &V,
6384 Type &Ty, Instruction *CtxI, bool Check,
6385 ValueToValueMapTy &VMap) {
6386 if (const auto &NewV = VMap.lookup(&V))
6387 return NewV;
6388 bool UsedAssumedInformation = false;
6389 std::optional<Value *> SimpleV = A.getAssumedSimplified(
6390 V, QueryingAA, UsedAssumedInformation, AA::Interprocedural);
6391 if (!SimpleV.has_value())
6392 return PoisonValue::get(&Ty);
6393 Value *EffectiveV = &V;
6394 if (*SimpleV)
6395 EffectiveV = *SimpleV;
6396 if (auto *C = dyn_cast<Constant>(EffectiveV))
6397 return C;
6398 if (CtxI && AA::isValidAtPosition(AA::ValueAndContext(*EffectiveV, *CtxI),
6399 A.getInfoCache()))
6400 return ensureType(A, *EffectiveV, Ty, CtxI, Check);
6401 if (auto *I = dyn_cast<Instruction>(EffectiveV))
6402 if (Value *NewV = reproduceInst(A, QueryingAA, *I, Ty, CtxI, Check, VMap))
6403 return ensureType(A, *NewV, Ty, CtxI, Check);
6404 return nullptr;
6405 }
6406
6407 /// Return a value we can use as replacement for the associated one, or
6408 /// nullptr if we don't have one that makes sense.
6409 Value *manifestReplacementValue(Attributor &A, Instruction *CtxI) const {
6410 Value *NewV = SimplifiedAssociatedValue
6411 ? *SimplifiedAssociatedValue
6412 : UndefValue::get(getAssociatedType());
6413 if (NewV && NewV != &getAssociatedValue()) {
6414 ValueToValueMapTy VMap;
6415 // First verify we can reprduce the value with the required type at the
6416 // context location before we actually start modifying the IR.
6417 if (reproduceValue(A, *this, *NewV, *getAssociatedType(), CtxI,
6418 /* CheckOnly */ true, VMap))
6419 return reproduceValue(A, *this, *NewV, *getAssociatedType(), CtxI,
6420 /* CheckOnly */ false, VMap);
6421 }
6422 return nullptr;
6423 }
6424
6425 /// Helper function for querying AAValueSimplify and updating candidate.
6426 /// \param IRP The value position we are trying to unify with SimplifiedValue
6427 bool checkAndUpdate(Attributor &A, const AbstractAttribute &QueryingAA,
6428 const IRPosition &IRP, bool Simplify = true) {
6429 bool UsedAssumedInformation = false;
6430 std::optional<Value *> QueryingValueSimplified = &IRP.getAssociatedValue();
6431 if (Simplify)
6432 QueryingValueSimplified = A.getAssumedSimplified(
6433 IRP, QueryingAA, UsedAssumedInformation, AA::Interprocedural);
6434 return unionAssumed(QueryingValueSimplified);
6435 }
6436
6437 /// Returns a candidate is found or not
6438 template <typename AAType> bool askSimplifiedValueFor(Attributor &A) {
6439 if (!getAssociatedValue().getType()->isIntegerTy())
6440 return false;
6441
6442 // This will also pass the call base context.
6443 const auto *AA =
6444 A.getAAFor<AAType>(*this, getIRPosition(), DepClassTy::NONE);
6445 if (!AA)
6446 return false;
6447
6448 std::optional<Constant *> COpt = AA->getAssumedConstant(A);
6449
6450 if (!COpt) {
6451 SimplifiedAssociatedValue = std::nullopt;
6452 A.recordDependence(*AA, *this, DepClassTy::OPTIONAL);
6453 return true;
6454 }
6455 if (auto *C = *COpt) {
6456 SimplifiedAssociatedValue = C;
6457 A.recordDependence(*AA, *this, DepClassTy::OPTIONAL);
6458 return true;
6459 }
6460 return false;
6461 }
6462
6463 bool askSimplifiedValueForOtherAAs(Attributor &A) {
6464 if (askSimplifiedValueFor<AAValueConstantRange>(A))
6465 return true;
6466 if (askSimplifiedValueFor<AAPotentialConstantValues>(A))
6467 return true;
6468 return false;
6469 }
6470
6471 /// See AbstractAttribute::manifest(...).
6472 ChangeStatus manifest(Attributor &A) override {
6473 ChangeStatus Changed = ChangeStatus::UNCHANGED;
6474 for (auto &U : getAssociatedValue().uses()) {
6475 // Check if we need to adjust the insertion point to make sure the IR is
6476 // valid.
6477 Instruction *IP = dyn_cast<Instruction>(U.getUser());
6478 if (auto *PHI = dyn_cast_or_null<PHINode>(IP))
6479 IP = PHI->getIncomingBlock(U)->getTerminator();
6480 if (auto *NewV = manifestReplacementValue(A, IP)) {
6481 LLVM_DEBUG(dbgs() << "[ValueSimplify] " << getAssociatedValue()
6482 << " -> " << *NewV << " :: " << *this << "\n");
6483 if (A.changeUseAfterManifest(U, *NewV))
6484 Changed = ChangeStatus::CHANGED;
6485 }
6486 }
6487
6488 return Changed | AAValueSimplify::manifest(A);
6489 }
6490
6491 /// See AbstractState::indicatePessimisticFixpoint(...).
6492 ChangeStatus indicatePessimisticFixpoint() override {
6493 SimplifiedAssociatedValue = &getAssociatedValue();
6494 return AAValueSimplify::indicatePessimisticFixpoint();
6495 }
6496};
6497
6498struct AAValueSimplifyArgument final : AAValueSimplifyImpl {
6499 AAValueSimplifyArgument(const IRPosition &IRP, Attributor &A)
6500 : AAValueSimplifyImpl(IRP, A) {}
6501
6502 void initialize(Attributor &A) override {
6503 AAValueSimplifyImpl::initialize(A);
6504 if (A.hasAttr(getIRPosition(),
6505 {Attribute::InAlloca, Attribute::Preallocated,
6506 Attribute::StructRet, Attribute::Nest, Attribute::ByVal},
6507 /* IgnoreSubsumingPositions */ true))
6508 indicatePessimisticFixpoint();
6509 }
6510
6511 /// See AbstractAttribute::updateImpl(...).
6512 ChangeStatus updateImpl(Attributor &A) override {
6513 // Byval is only replacable if it is readonly otherwise we would write into
6514 // the replaced value and not the copy that byval creates implicitly.
6515 Argument *Arg = getAssociatedArgument();
6516 if (Arg->hasByValAttr()) {
6517 // TODO: We probably need to verify synchronization is not an issue, e.g.,
6518 // there is no race by not copying a constant byval.
6519 bool IsKnown;
6520 if (!AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown))
6521 return indicatePessimisticFixpoint();
6522 }
6523
6524 auto Before = SimplifiedAssociatedValue;
6525
6526 auto PredForCallSite = [&](AbstractCallSite ACS) {
6527 const IRPosition &ACSArgPos =
6528 IRPosition::callsite_argument(ACS, getCallSiteArgNo());
6529 // Check if a coresponding argument was found or if it is on not
6530 // associated (which can happen for callback calls).
6531 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
6532 return false;
6533
6534 // Simplify the argument operand explicitly and check if the result is
6535 // valid in the current scope. This avoids refering to simplified values
6536 // in other functions, e.g., we don't want to say a an argument in a
6537 // static function is actually an argument in a different function.
6538 bool UsedAssumedInformation = false;
6539 std::optional<Constant *> SimpleArgOp =
6540 A.getAssumedConstant(ACSArgPos, *this, UsedAssumedInformation);
6541 if (!SimpleArgOp)
6542 return true;
6543 if (!*SimpleArgOp)
6544 return false;
6545 if (!AA::isDynamicallyUnique(A, *this, **SimpleArgOp))
6546 return false;
6547 return unionAssumed(*SimpleArgOp);
6548 };
6549
6550 // Generate a answer specific to a call site context.
6551 bool Success;
6552 bool UsedAssumedInformation = false;
6553 if (hasCallBaseContext() &&
6554 getCallBaseContext()->getCalledOperand() == Arg->getParent())
6555 Success = PredForCallSite(
6556 AbstractCallSite(&getCallBaseContext()->getCalledOperandUse()));
6557 else
6558 Success = A.checkForAllCallSites(PredForCallSite, *this, true,
6559 UsedAssumedInformation);
6560
6561 if (!Success)
6562 if (!askSimplifiedValueForOtherAAs(A))
6563 return indicatePessimisticFixpoint();
6564
6565 // If a candidate was found in this update, return CHANGED.
6566 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED
6567 : ChangeStatus ::CHANGED;
6568 }
6569
6570 /// See AbstractAttribute::trackStatistics()
6571 void trackStatistics() const override {
6572 STATS_DECLTRACK_ARG_ATTR(value_simplify)
6573 }
6574};
6575
6576struct AAValueSimplifyReturned : AAValueSimplifyImpl {
6577 AAValueSimplifyReturned(const IRPosition &IRP, Attributor &A)
6578 : AAValueSimplifyImpl(IRP, A) {}
6579
6580 /// See AAValueSimplify::getAssumedSimplifiedValue()
6581 std::optional<Value *>
6582 getAssumedSimplifiedValue(Attributor &A) const override {
6583 if (!isValidState())
6584 return nullptr;
6585 return SimplifiedAssociatedValue;
6586 }
6587
6588 /// See AbstractAttribute::updateImpl(...).
6589 ChangeStatus updateImpl(Attributor &A) override {
6590 auto Before = SimplifiedAssociatedValue;
6591
6592 auto ReturnInstCB = [&](Instruction &I) {
6593 auto &RI = cast<ReturnInst>(I);
6594 return checkAndUpdate(
6595 A, *this,
6596 IRPosition::value(*RI.getReturnValue(), getCallBaseContext()));
6597 };
6598
6599 bool UsedAssumedInformation = false;
6600 if (!A.checkForAllInstructions(ReturnInstCB, *this, {Instruction::Ret},
6601 UsedAssumedInformation))
6602 if (!askSimplifiedValueForOtherAAs(A))
6603 return indicatePessimisticFixpoint();
6604
6605 // If a candidate was found in this update, return CHANGED.
6606 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED
6607 : ChangeStatus ::CHANGED;
6608 }
6609
6610 ChangeStatus manifest(Attributor &A) override {
6611 // We queried AAValueSimplify for the returned values so they will be
6612 // replaced if a simplified form was found. Nothing to do here.
6613 return ChangeStatus::UNCHANGED;
6614 }
6615
6616 /// See AbstractAttribute::trackStatistics()
6617 void trackStatistics() const override {
6618 STATS_DECLTRACK_FNRET_ATTR(value_simplify)
6619 }
6620};
6621
6622struct AAValueSimplifyFloating : AAValueSimplifyImpl {
6623 AAValueSimplifyFloating(const IRPosition &IRP, Attributor &A)
6624 : AAValueSimplifyImpl(IRP, A) {}
6625
6626 /// See AbstractAttribute::initialize(...).
6627 void initialize(Attributor &A) override {
6628 AAValueSimplifyImpl::initialize(A);
6629 Value &V = getAnchorValue();
6630
6631 // TODO: add other stuffs
6632 if (isa<Constant>(V))
6633 indicatePessimisticFixpoint();
6634 }
6635
6636 /// See AbstractAttribute::updateImpl(...).
6637 ChangeStatus updateImpl(Attributor &A) override {
6638 auto Before = SimplifiedAssociatedValue;
6639 if (!askSimplifiedValueForOtherAAs(A))
6640 return indicatePessimisticFixpoint();
6641
6642 // If a candidate was found in this update, return CHANGED.
6643 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED
6644 : ChangeStatus ::CHANGED;
6645 }
6646
6647 /// See AbstractAttribute::trackStatistics()
6648 void trackStatistics() const override {
6649 STATS_DECLTRACK_FLOATING_ATTR(value_simplify)
6650 }
6651};
6652
6653struct AAValueSimplifyFunction : AAValueSimplifyImpl {
6654 AAValueSimplifyFunction(const IRPosition &IRP, Attributor &A)
6655 : AAValueSimplifyImpl(IRP, A) {}
6656
6657 /// See AbstractAttribute::initialize(...).
6658 void initialize(Attributor &A) override {
6659 SimplifiedAssociatedValue = nullptr;
6660 indicateOptimisticFixpoint();
6661 }
6662 /// See AbstractAttribute::initialize(...).
6663 ChangeStatus updateImpl(Attributor &A) override {
6665 "AAValueSimplify(Function|CallSite)::updateImpl will not be called");
6666 }
6667 /// See AbstractAttribute::trackStatistics()
6668 void trackStatistics() const override {
6669 STATS_DECLTRACK_FN_ATTR(value_simplify)
6670 }
6671};
6672
6673struct AAValueSimplifyCallSite : AAValueSimplifyFunction {
6674 AAValueSimplifyCallSite(const IRPosition &IRP, Attributor &A)
6675 : AAValueSimplifyFunction(IRP, A) {}
6676 /// See AbstractAttribute::trackStatistics()
6677 void trackStatistics() const override {
6678 STATS_DECLTRACK_CS_ATTR(value_simplify)
6679 }
6680};
6681
6682struct AAValueSimplifyCallSiteReturned : AAValueSimplifyImpl {
6683 AAValueSimplifyCallSiteReturned(const IRPosition &IRP, Attributor &A)
6684 : AAValueSimplifyImpl(IRP, A) {}
6685
6686 void initialize(Attributor &A) override {
6687 AAValueSimplifyImpl::initialize(A);
6688 Function *Fn = getAssociatedFunction();
6689 assert(Fn && "Did expect an associted function");
6690 for (Argument &Arg : Fn->args()) {
6691 if (Arg.hasReturnedAttr()) {
6692 auto IRP = IRPosition::callsite_argument(*cast<CallBase>(getCtxI()),
6693 Arg.getArgNo());
6695 checkAndUpdate(A, *this, IRP))
6696 indicateOptimisticFixpoint();
6697 else
6698 indicatePessimisticFixpoint();
6699 return;
6700 }
6701 }
6702 }
6703
6704 /// See AbstractAttribute::updateImpl(...).
6705 ChangeStatus updateImpl(Attributor &A) override {
6706 return indicatePessimisticFixpoint();
6707 }
6708
6709 void trackStatistics() const override {
6710 STATS_DECLTRACK_CSRET_ATTR(value_simplify)
6711 }
6712};
6713
6714struct AAValueSimplifyCallSiteArgument : AAValueSimplifyFloating {
6715 AAValueSimplifyCallSiteArgument(const IRPosition &IRP, Attributor &A)
6716 : AAValueSimplifyFloating(IRP, A) {}
6717
6718 /// See AbstractAttribute::manifest(...).
6719 ChangeStatus manifest(Attributor &A) override {
6720 ChangeStatus Changed = ChangeStatus::UNCHANGED;
6721 // TODO: We should avoid simplification duplication to begin with.
6722 auto *FloatAA = A.lookupAAFor<AAValueSimplify>(
6723 IRPosition::value(getAssociatedValue()), this, DepClassTy::NONE);
6724 if (FloatAA && FloatAA->getState().isValidState())
6725 return Changed;
6726
6727 if (auto *NewV = manifestReplacementValue(A, getCtxI())) {
6728 Use &U = cast<CallBase>(&getAnchorValue())
6729 ->getArgOperandUse(getCallSiteArgNo());
6730 if (A.changeUseAfterManifest(U, *NewV))
6731 Changed = ChangeStatus::CHANGED;
6732 }
6733
6734 return Changed | AAValueSimplify::manifest(A);
6735 }
6736
6737 void trackStatistics() const override {
6738 STATS_DECLTRACK_CSARG_ATTR(value_simplify)
6739 }
6740};
6741} // namespace
6742
6743/// ----------------------- Heap-To-Stack Conversion ---------------------------
6744namespace {
6745struct AAHeapToStackFunction final : public AAHeapToStack {
6746
6747 static bool isGlobalizedLocal(const CallBase &CB) {
6748 Attribute A = CB.getFnAttr("alloc-family");
6749 return A.isValid() && A.getValueAsString() == "__kmpc_alloc_shared";
6750 }
6751
6752 struct AllocationInfo {
6753 /// The call that allocates the memory.
6754 CallBase *const CB;
6755
6756 /// Whether this allocation is an OpenMP globalized local variable.
6757 bool IsGlobalizedLocal = false;
6758
6759 /// The status wrt. a rewrite.
6760 enum {
6761 STACK_DUE_TO_USE,
6762 STACK_DUE_TO_FREE,
6763 INVALID,
6764 } Status = STACK_DUE_TO_USE;
6765
6766 /// Flag to indicate if we encountered a use that might free this allocation
6767 /// but which is not in the deallocation infos.
6768 bool HasPotentiallyFreeingUnknownUses = false;
6769
6770 /// Flag to indicate that we should place the new alloca in the function
6771 /// entry block rather than where the call site (CB) is.
6772 bool MoveAllocaIntoEntry = true;
6773
6774 /// The set of free calls that use this allocation.
6775 SmallSetVector<CallBase *, 1> PotentialFreeCalls{};
6776 };
6777
6778 struct DeallocationInfo {
6779 /// The call that deallocates the memory.
6780 CallBase *const CB;
6781 /// The value freed by the call.
6782 Value *FreedOp;
6783
6784 /// Flag to indicate if we don't know all objects this deallocation might
6785 /// free.
6786 bool MightFreeUnknownObjects = false;
6787
6788 /// The set of allocation calls that are potentially freed.
6789 SmallSetVector<CallBase *, 1> PotentialAllocationCalls{};
6790 };
6791
6792 AAHeapToStackFunction(const IRPosition &IRP, Attributor &A)
6793 : AAHeapToStack(IRP, A) {}
6794
6795 ~AAHeapToStackFunction() override {
6796 // Ensure we call the destructor so we release any memory allocated in the
6797 // sets.
6798 for (auto &It : AllocationInfos)
6799 It.second->~AllocationInfo();
6800 for (auto &It : DeallocationInfos)
6801 It.second->~DeallocationInfo();
6802 }
6803
6804 void initialize(Attributor &A) override {
6805 AAHeapToStack::initialize(A);
6806
6807 const Function *F = getAnchorScope();
6808 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
6809
6810 auto AllocationIdentifierCB = [&](Instruction &I) {
6811 CallBase *CB = dyn_cast<CallBase>(&I);
6812 if (!CB)
6813 return true;
6814 if (Value *FreedOp = getFreedOperand(CB, TLI)) {
6815 DeallocationInfos[CB] = new (A.Allocator) DeallocationInfo{CB, FreedOp};
6816 return true;
6817 }
6818 // To do heap to stack, we need to know that the allocation itself is
6819 // removable once uses are rewritten, and that we can initialize the
6820 // alloca to the same pattern as the original allocation result.
6821 if (isRemovableAlloc(CB, TLI)) {
6822 auto *I8Ty = Type::getInt8Ty(CB->getParent()->getContext());
6823 if (nullptr != getInitialValueOfAllocation(CB, TLI, I8Ty)) {
6824 AllocationInfo *AI = new (A.Allocator) AllocationInfo{CB};
6825 AllocationInfos[CB] = AI;
6826 AI->IsGlobalizedLocal = isGlobalizedLocal(*CB);
6827 }
6828 }
6829 return true;
6830 };
6831
6832 bool UsedAssumedInformation = false;
6833 bool Success = A.checkForAllCallLikeInstructions(
6834 AllocationIdentifierCB, *this, UsedAssumedInformation,
6835 /* CheckBBLivenessOnly */ false,
6836 /* CheckPotentiallyDead */ true);
6837 (void)Success;
6838 assert(Success && "Did not expect the call base visit callback to fail!");
6839
6841 [](const IRPosition &, const AbstractAttribute *,
6842 bool &) -> std::optional<Value *> { return nullptr; };
6843 for (const auto &It : AllocationInfos)
6844 A.registerSimplificationCallback(IRPosition::callsite_returned(*It.first),
6845 SCB);
6846 for (const auto &It : DeallocationInfos)
6847 A.registerSimplificationCallback(IRPosition::callsite_returned(*It.first),
6848 SCB);
6849 }
6850
6851 const std::string getAsStr(Attributor *A) const override {
6852 unsigned NumH2SMallocs = 0, NumInvalidMallocs = 0;
6853 for (const auto &It : AllocationInfos) {
6854 if (It.second->Status == AllocationInfo::INVALID)
6855 ++NumInvalidMallocs;
6856 else
6857 ++NumH2SMallocs;
6858 }
6859 return "[H2S] Mallocs Good/Bad: " + std::to_string(NumH2SMallocs) + "/" +
6860 std::to_string(NumInvalidMallocs);
6861 }
6862
6863 /// See AbstractAttribute::trackStatistics().
6864 void trackStatistics() const override {
6865 STATS_DECL(
6866 MallocCalls, Function,
6867 "Number of malloc/calloc/aligned_alloc calls converted to allocas");
6868 for (const auto &It : AllocationInfos)
6869 if (It.second->Status != AllocationInfo::INVALID)
6870 ++BUILD_STAT_NAME(MallocCalls, Function);
6871 }
6872
6873 bool isAssumedHeapToStack(const CallBase &CB) const override {
6874 if (isValidState())
6875 if (AllocationInfo *AI =
6876 AllocationInfos.lookup(const_cast<CallBase *>(&CB)))
6877 return AI->Status != AllocationInfo::INVALID;
6878 return false;
6879 }
6880
6881 bool isAssumedHeapToStackRemovedFree(CallBase &CB) const override {
6882 if (!isValidState())
6883 return false;
6884
6885 for (const auto &It : AllocationInfos) {
6886 AllocationInfo &AI = *It.second;
6887 if (AI.Status == AllocationInfo::INVALID)
6888 continue;
6889
6890 if (AI.PotentialFreeCalls.count(&CB))
6891 return true;
6892 }
6893
6894 return false;
6895 }
6896
6897 ChangeStatus manifest(Attributor &A) override {
6898 assert(getState().isValidState() &&
6899 "Attempted to manifest an invalid state!");
6900
6901 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
6902 Function *F = getAnchorScope();
6903 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
6904
6905 for (auto &It : AllocationInfos) {
6906 AllocationInfo &AI = *It.second;
6907 if (AI.Status == AllocationInfo::INVALID)
6908 continue;
6909
6910 for (CallBase *FreeCall : AI.PotentialFreeCalls) {
6911 LLVM_DEBUG(dbgs() << "H2S: Removing free call: " << *FreeCall << "\n");
6912 A.deleteAfterManifest(*FreeCall);
6913 HasChanged = ChangeStatus::CHANGED;
6914 }
6915
6916 LLVM_DEBUG(dbgs() << "H2S: Removing malloc-like call: " << *AI.CB
6917 << "\n");
6918
6919 auto Remark = [&](OptimizationRemark OR) {
6920 if (AI.IsGlobalizedLocal)
6921 return OR << "Moving globalized variable to the stack.";
6922 return OR << "Moving memory allocation from the heap to the stack.";
6923 };
6924 if (AI.IsGlobalizedLocal)
6925 A.emitRemark<OptimizationRemark>(AI.CB, "OMP110", Remark);
6926 else
6927 A.emitRemark<OptimizationRemark>(AI.CB, "HeapToStack", Remark);
6928
6929 const DataLayout &DL = A.getInfoCache().getDL();
6930 Value *Size;
6931 std::optional<APInt> SizeAPI = getSize(A, *this, AI);
6932 if (SizeAPI) {
6933 Size = ConstantInt::get(AI.CB->getContext(), *SizeAPI);
6934 } else {
6935 LLVMContext &Ctx = AI.CB->getContext();
6936 ObjectSizeOpts Opts;
6937 ObjectSizeOffsetEvaluator Eval(DL, TLI, Ctx, Opts);
6938 SizeOffsetValue SizeOffsetPair = Eval.compute(AI.CB);
6939 assert(SizeOffsetPair != ObjectSizeOffsetEvaluator::unknown() &&
6940 cast<ConstantInt>(SizeOffsetPair.Offset)->isZero());
6941 Size = SizeOffsetPair.Size;
6942 }
6943
6944 BasicBlock::iterator IP = AI.MoveAllocaIntoEntry
6945 ? F->getEntryBlock().begin()
6946 : AI.CB->getIterator();
6947
6948 Align Alignment(1);
6949 if (MaybeAlign RetAlign = AI.CB->getRetAlign())
6950 Alignment = std::max(Alignment, *RetAlign);
6951 if (Value *Align = getAllocAlignment(AI.CB, TLI)) {
6952 std::optional<APInt> AlignmentAPI = getAPInt(A, *this, *Align);
6953 assert(AlignmentAPI && AlignmentAPI->getZExtValue() > 0 &&
6954 "Expected an alignment during manifest!");
6955 Alignment =
6956 std::max(Alignment, assumeAligned(AlignmentAPI->getZExtValue()));
6957 }
6958
6959 // TODO: Hoist the alloca towards the function entry.
6960 unsigned AS = DL.getAllocaAddrSpace();
6961 Instruction *Alloca =
6962 new AllocaInst(Type::getInt8Ty(F->getContext()), AS, Size, Alignment,
6963 AI.CB->getName() + ".h2s", IP);
6964
6965 if (Alloca->getType() != AI.CB->getType())
6966 Alloca = BitCastInst::CreatePointerBitCastOrAddrSpaceCast(
6967 Alloca, AI.CB->getType(), "malloc_cast", AI.CB->getIterator());
6968
6969 auto *I8Ty = Type::getInt8Ty(F->getContext());
6970 auto *InitVal = getInitialValueOfAllocation(AI.CB, TLI, I8Ty);
6971 assert(InitVal &&
6972 "Must be able to materialize initial memory state of allocation");
6973
6974 A.changeAfterManifest(IRPosition::inst(*AI.CB), *Alloca);
6975
6976 if (auto *II = dyn_cast<InvokeInst>(AI.CB)) {
6977 auto *NBB = II->getNormalDest();
6978 UncondBrInst::Create(NBB, AI.CB->getParent());
6979 A.deleteAfterManifest(*AI.CB);
6980 } else {
6981 A.deleteAfterManifest(*AI.CB);
6982 }
6983
6984 // Initialize the alloca with the same value as used by the allocation
6985 // function. We can skip undef as the initial value of an alloc is
6986 // undef, and the memset would simply end up being DSEd.
6987 if (!isa<UndefValue>(InitVal)) {
6988 IRBuilder<> Builder(Alloca->getNextNode());
6989 // TODO: Use alignment above if align!=1
6990 Builder.CreateMemSet(Alloca, InitVal, Size, std::nullopt);
6991 }
6992 HasChanged = ChangeStatus::CHANGED;
6993 }
6994
6995 return HasChanged;
6996 }
6997
6998 std::optional<APInt> getAPInt(Attributor &A, const AbstractAttribute &AA,
6999 Value &V) {
7000 bool UsedAssumedInformation = false;
7001 std::optional<Constant *> SimpleV =
7002 A.getAssumedConstant(V, AA, UsedAssumedInformation);
7003 if (!SimpleV)
7004 return APInt(64, 0);
7005 if (auto *CI = dyn_cast_or_null<ConstantInt>(*SimpleV))
7006 return CI->getValue();
7007 return std::nullopt;
7008 }
7009
7010 std::optional<APInt> getSize(Attributor &A, const AbstractAttribute &AA,
7011 AllocationInfo &AI) {
7012 auto Mapper = [&](const Value *V) -> const Value * {
7013 bool UsedAssumedInformation = false;
7014 if (std::optional<Constant *> SimpleV =
7015 A.getAssumedConstant(*V, AA, UsedAssumedInformation))
7016 if (*SimpleV)
7017 return *SimpleV;
7018 return V;
7019 };
7020
7021 const Function *F = getAnchorScope();
7022 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
7023 return getAllocSize(AI.CB, TLI, Mapper);
7024 }
7025
7026 /// Collection of all malloc-like calls in a function with associated
7027 /// information.
7028 MapVector<CallBase *, AllocationInfo *> AllocationInfos;
7029
7030 /// Collection of all free-like calls in a function with associated
7031 /// information.
7032 MapVector<CallBase *, DeallocationInfo *> DeallocationInfos;
7033
7034 ChangeStatus updateImpl(Attributor &A) override;
7035};
7036
7037ChangeStatus AAHeapToStackFunction::updateImpl(Attributor &A) {
7039 const Function *F = getAnchorScope();
7040 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
7041
7042 const auto *LivenessAA =
7043 A.getAAFor<AAIsDead>(*this, IRPosition::function(*F), DepClassTy::NONE);
7044
7045 MustBeExecutedContextExplorer *Explorer =
7046 A.getInfoCache().getMustBeExecutedContextExplorer();
7047
7048 bool StackIsAccessibleByOtherThreads =
7049 A.getInfoCache().stackIsAccessibleByOtherThreads();
7050
7051 LoopInfo *LI =
7052 A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(*F);
7053 std::optional<bool> MayContainIrreducibleControl;
7054 auto IsInLoop = [&](BasicBlock &BB) {
7055 if (&F->getEntryBlock() == &BB)
7056 return false;
7057 if (!MayContainIrreducibleControl.has_value())
7058 MayContainIrreducibleControl = mayContainIrreducibleControl(*F, LI);
7059 if (*MayContainIrreducibleControl)
7060 return true;
7061 if (!LI)
7062 return true;
7063 return LI->getLoopFor(&BB) != nullptr;
7064 };
7065
7066 // Flag to ensure we update our deallocation information at most once per
7067 // updateImpl call and only if we use the free check reasoning.
7068 bool HasUpdatedFrees = false;
7069
7070 auto UpdateFrees = [&]() {
7071 HasUpdatedFrees = true;
7072
7073 for (auto &It : DeallocationInfos) {
7074 DeallocationInfo &DI = *It.second;
7075 // For now we cannot use deallocations that have unknown inputs, skip
7076 // them.
7077 if (DI.MightFreeUnknownObjects)
7078 continue;
7079
7080 // No need to analyze dead calls, ignore them instead.
7081 bool UsedAssumedInformation = false;
7082 if (A.isAssumedDead(*DI.CB, this, LivenessAA, UsedAssumedInformation,
7083 /* CheckBBLivenessOnly */ true))
7084 continue;
7085
7086 // Use the non-optimistic version to get the freed object.
7087 Value *Obj = getUnderlyingObject(DI.FreedOp);
7088 if (!Obj) {
7089 LLVM_DEBUG(dbgs() << "[H2S] Unknown underlying object for free!\n");
7090 DI.MightFreeUnknownObjects = true;
7091 continue;
7092 }
7093
7094 // Free of null and undef can be ignored as no-ops (or UB in the latter
7095 // case).
7097 continue;
7098
7099 CallBase *ObjCB = dyn_cast<CallBase>(Obj);
7100 if (!ObjCB) {
7101 LLVM_DEBUG(dbgs() << "[H2S] Free of a non-call object: " << *Obj
7102 << "\n");
7103 DI.MightFreeUnknownObjects = true;
7104 continue;
7105 }
7106
7107 AllocationInfo *AI = AllocationInfos.lookup(ObjCB);
7108 if (!AI) {
7109 LLVM_DEBUG(dbgs() << "[H2S] Free of a non-allocation object: " << *Obj
7110 << "\n");
7111 DI.MightFreeUnknownObjects = true;
7112 continue;
7113 }
7114
7115 DI.PotentialAllocationCalls.insert(ObjCB);
7116 }
7117 };
7118
7119 auto FreeCheck = [&](AllocationInfo &AI) {
7120 // If the stack is not accessible by other threads, the "must-free" logic
7121 // doesn't apply as the pointer could be shared and needs to be places in
7122 // "shareable" memory.
7123 if (!StackIsAccessibleByOtherThreads) {
7124 bool IsKnownNoSycn;
7126 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNoSycn)) {
7127 LLVM_DEBUG(
7128 dbgs() << "[H2S] found an escaping use, stack is not accessible by "
7129 "other threads and function is not nosync:\n");
7130 return false;
7131 }
7132 }
7133 if (!HasUpdatedFrees)
7134 UpdateFrees();
7135
7136 // TODO: Allow multi exit functions that have different free calls.
7137 if (AI.PotentialFreeCalls.size() != 1) {
7138 LLVM_DEBUG(dbgs() << "[H2S] did not find one free call but "
7139 << AI.PotentialFreeCalls.size() << "\n");
7140 return false;
7141 }
7142 CallBase *UniqueFree = *AI.PotentialFreeCalls.begin();
7143 DeallocationInfo *DI = DeallocationInfos.lookup(UniqueFree);
7144 if (!DI) {
7145 LLVM_DEBUG(
7146 dbgs() << "[H2S] unique free call was not known as deallocation call "
7147 << *UniqueFree << "\n");
7148 return false;
7149 }
7150 if (DI->MightFreeUnknownObjects) {
7151 LLVM_DEBUG(
7152 dbgs() << "[H2S] unique free call might free unknown allocations\n");
7153 return false;
7154 }
7155 if (DI->PotentialAllocationCalls.empty())
7156 return true;
7157 if (DI->PotentialAllocationCalls.size() > 1) {
7158 LLVM_DEBUG(dbgs() << "[H2S] unique free call might free "
7159 << DI->PotentialAllocationCalls.size()
7160 << " different allocations\n");
7161 return false;
7162 }
7163 if (*DI->PotentialAllocationCalls.begin() != AI.CB) {
7164 LLVM_DEBUG(
7165 dbgs()
7166 << "[H2S] unique free call not known to free this allocation but "
7167 << **DI->PotentialAllocationCalls.begin() << "\n");
7168 return false;
7169 }
7170
7171 // __kmpc_alloc_shared and __kmpc_free_shared are by construction matched.
7172 if (!AI.IsGlobalizedLocal) {
7173 Instruction *CtxI = isa<InvokeInst>(AI.CB) ? AI.CB : AI.CB->getNextNode();
7174 if (!Explorer || !Explorer->findInContextOf(UniqueFree, CtxI)) {
7175 LLVM_DEBUG(dbgs() << "[H2S] unique free call might not be executed "
7176 "with the allocation "
7177 << *UniqueFree << "\n");
7178 return false;
7179 }
7180 }
7181 return true;
7182 };
7183
7184 auto UsesCheck = [&](AllocationInfo &AI) {
7185 bool ValidUsesOnly = true;
7186
7187 auto Pred = [&](const Use &U, bool &Follow) -> bool {
7188 Instruction *UserI = cast<Instruction>(U.getUser());
7189 if (isa<LoadInst>(UserI))
7190 return true;
7191 if (auto *SI = dyn_cast<StoreInst>(UserI)) {
7192 if (SI->getValueOperand() == U.get()) {
7194 << "[H2S] escaping store to memory: " << *UserI << "\n");
7195 ValidUsesOnly = false;
7196 } else {
7197 // A store into the malloc'ed memory is fine.
7198 }
7199 return true;
7200 }
7201 if (auto *CB = dyn_cast<CallBase>(UserI)) {
7202 if (!CB->isArgOperand(&U) || CB->isLifetimeStartOrEnd())
7203 return true;
7204 if (DeallocationInfos.count(CB)) {
7205 AI.PotentialFreeCalls.insert(CB);
7206 return true;
7207 }
7208
7209 unsigned ArgNo = CB->getArgOperandNo(&U);
7210 auto CBIRP = IRPosition::callsite_argument(*CB, ArgNo);
7211
7212 bool IsKnownNoCapture;
7213 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
7214 A, this, CBIRP, DepClassTy::OPTIONAL, IsKnownNoCapture);
7215
7216 // If a call site argument use is nofree, we are fine.
7217 bool IsKnownNoFree;
7218 bool IsAssumedNoFree = AA::hasAssumedIRAttr<Attribute::NoFree>(
7219 A, this, CBIRP, DepClassTy::OPTIONAL, IsKnownNoFree);
7220
7221 if (!IsAssumedNoCapture ||
7222 (!AI.IsGlobalizedLocal && !IsAssumedNoFree)) {
7223 AI.HasPotentiallyFreeingUnknownUses |= !IsAssumedNoFree;
7224
7225 // Emit a missed remark if this is missed OpenMP globalization.
7226 auto Remark = [&](OptimizationRemarkMissed ORM) {
7227 return ORM
7228 << "Could not move globalized variable to the stack. "
7229 "Variable is potentially captured in call. Mark "
7230 "parameter as `__attribute__((noescape))` to override.";
7231 };
7232
7233 if (ValidUsesOnly && AI.IsGlobalizedLocal)
7234 A.emitRemark<OptimizationRemarkMissed>(CB, "OMP113", Remark);
7235
7236 LLVM_DEBUG(dbgs() << "[H2S] Bad user: " << *UserI << "\n");
7237 ValidUsesOnly = false;
7238 }
7239 return true;
7240 }
7241
7242 if (isa<GetElementPtrInst>(UserI) || isa<BitCastInst>(UserI) ||
7243 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) {
7244 Follow = true;
7245 return true;
7246 }
7247 // Unknown user for which we can not track uses further (in a way that
7248 // makes sense).
7249 LLVM_DEBUG(dbgs() << "[H2S] Unknown user: " << *UserI << "\n");
7250 ValidUsesOnly = false;
7251 return true;
7252 };
7253 if (!A.checkForAllUses(Pred, *this, *AI.CB, /* CheckBBLivenessOnly */ false,
7254 DepClassTy::OPTIONAL, /* IgnoreDroppableUses */ true,
7255 [&](const Use &OldU, const Use &NewU) {
7256 auto *SI = dyn_cast<StoreInst>(OldU.getUser());
7257 return !SI || StackIsAccessibleByOtherThreads ||
7258 AA::isAssumedThreadLocalObject(
7259 A, *SI->getPointerOperand(), *this);
7260 }))
7261 return false;
7262 return ValidUsesOnly;
7263 };
7264
7265 // The actual update starts here. We look at all allocations and depending on
7266 // their status perform the appropriate check(s).
7267 for (auto &It : AllocationInfos) {
7268 AllocationInfo &AI = *It.second;
7269 if (AI.Status == AllocationInfo::INVALID)
7270 continue;
7271
7272 if (Value *Align = getAllocAlignment(AI.CB, TLI)) {
7273 std::optional<APInt> APAlign = getAPInt(A, *this, *Align);
7274 if (!APAlign) {
7275 // Can't generate an alloca which respects the required alignment
7276 // on the allocation.
7277 LLVM_DEBUG(dbgs() << "[H2S] Unknown allocation alignment: " << *AI.CB
7278 << "\n");
7279 AI.Status = AllocationInfo::INVALID;
7281 continue;
7282 }
7283 if (APAlign->ugt(llvm::Value::MaximumAlignment) ||
7284 !APAlign->isPowerOf2()) {
7285 LLVM_DEBUG(dbgs() << "[H2S] Invalid allocation alignment: " << APAlign
7286 << "\n");
7287 AI.Status = AllocationInfo::INVALID;
7289 continue;
7290 }
7291 }
7292
7293 std::optional<APInt> Size = getSize(A, *this, AI);
7294 if (!AI.IsGlobalizedLocal && MaxHeapToStackSize != -1) {
7295 if (!Size || Size->ugt(MaxHeapToStackSize)) {
7296 LLVM_DEBUG({
7297 if (!Size)
7298 dbgs() << "[H2S] Unknown allocation size: " << *AI.CB << "\n";
7299 else
7300 dbgs() << "[H2S] Allocation size too large: " << *AI.CB << " vs. "
7301 << MaxHeapToStackSize << "\n";
7302 });
7303
7304 AI.Status = AllocationInfo::INVALID;
7306 continue;
7307 }
7308 }
7309
7310 switch (AI.Status) {
7311 case AllocationInfo::STACK_DUE_TO_USE:
7312 if (UsesCheck(AI))
7313 break;
7314 AI.Status = AllocationInfo::STACK_DUE_TO_FREE;
7315 [[fallthrough]];
7316 case AllocationInfo::STACK_DUE_TO_FREE:
7317 if (FreeCheck(AI))
7318 break;
7319 AI.Status = AllocationInfo::INVALID;
7321 break;
7322 case AllocationInfo::INVALID:
7323 llvm_unreachable("Invalid allocations should never reach this point!");
7324 };
7325
7326 // Check if we still think we can move it into the entry block. If the
7327 // alloca comes from a converted __kmpc_alloc_shared then we can usually
7328 // ignore the potential complications associated with loops.
7329 bool IsGlobalizedLocal = AI.IsGlobalizedLocal;
7330 if (AI.MoveAllocaIntoEntry &&
7331 (!Size.has_value() ||
7332 (!IsGlobalizedLocal && IsInLoop(*AI.CB->getParent()))))
7333 AI.MoveAllocaIntoEntry = false;
7334 }
7335
7336 return Changed;
7337}
7338} // namespace
7339
7340/// ----------------------- Privatizable Pointers ------------------------------
7341namespace {
7342struct AAPrivatizablePtrImpl : public AAPrivatizablePtr {
7343 AAPrivatizablePtrImpl(const IRPosition &IRP, Attributor &A)
7344 : AAPrivatizablePtr(IRP, A), PrivatizableType(std::nullopt) {}
7345
7346 ChangeStatus indicatePessimisticFixpoint() override {
7347 AAPrivatizablePtr::indicatePessimisticFixpoint();
7348 PrivatizableType = nullptr;
7349 return ChangeStatus::CHANGED;
7350 }
7351
7352 /// Identify the type we can chose for a private copy of the underlying
7353 /// argument. std::nullopt means it is not clear yet, nullptr means there is
7354 /// none.
7355 virtual std::optional<Type *> identifyPrivatizableType(Attributor &A) = 0;
7356
7357 /// Return a privatizable type that encloses both T0 and T1.
7358 /// TODO: This is merely a stub for now as we should manage a mapping as well.
7359 std::optional<Type *> combineTypes(std::optional<Type *> T0,
7360 std::optional<Type *> T1) {
7361 if (!T0)
7362 return T1;
7363 if (!T1)
7364 return T0;
7365 if (T0 == T1)
7366 return T0;
7367 return nullptr;
7368 }
7369
7370 std::optional<Type *> getPrivatizableType() const override {
7371 return PrivatizableType;
7372 }
7373
7374 const std::string getAsStr(Attributor *A) const override {
7375 return isAssumedPrivatizablePtr() ? "[priv]" : "[no-priv]";
7376 }
7377
7378protected:
7379 std::optional<Type *> PrivatizableType;
7380};
7381
7382// TODO: Do this for call site arguments (probably also other values) as well.
7383
7384struct AAPrivatizablePtrArgument final : public AAPrivatizablePtrImpl {
7385 AAPrivatizablePtrArgument(const IRPosition &IRP, Attributor &A)
7386 : AAPrivatizablePtrImpl(IRP, A) {}
7387
7388 /// See AAPrivatizablePtrImpl::identifyPrivatizableType(...)
7389 std::optional<Type *> identifyPrivatizableType(Attributor &A) override {
7390 // If this is a byval argument and we know all the call sites (so we can
7391 // rewrite them), there is no need to check them explicitly.
7392 bool UsedAssumedInformation = false;
7394 A.getAttrs(getIRPosition(), {Attribute::ByVal}, Attrs,
7395 /* IgnoreSubsumingPositions */ true);
7396 if (!Attrs.empty() &&
7397 A.checkForAllCallSites([](AbstractCallSite ACS) { return true; }, *this,
7398 true, UsedAssumedInformation))
7399 return Attrs[0].getValueAsType();
7400
7401 std::optional<Type *> Ty;
7402 unsigned ArgNo = getIRPosition().getCallSiteArgNo();
7403
7404 // Make sure the associated call site argument has the same type at all call
7405 // sites and it is an allocation we know is safe to privatize, for now that
7406 // means we only allow alloca instructions.
7407 // TODO: We can additionally analyze the accesses in the callee to create
7408 // the type from that information instead. That is a little more
7409 // involved and will be done in a follow up patch.
7410 auto CallSiteCheck = [&](AbstractCallSite ACS) {
7411 IRPosition ACSArgPos = IRPosition::callsite_argument(ACS, ArgNo);
7412 // Check if a coresponding argument was found or if it is one not
7413 // associated (which can happen for callback calls).
7414 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
7415 return false;
7416
7417 // Check that all call sites agree on a type.
7418 auto *PrivCSArgAA =
7419 A.getAAFor<AAPrivatizablePtr>(*this, ACSArgPos, DepClassTy::REQUIRED);
7420 if (!PrivCSArgAA)
7421 return false;
7422 std::optional<Type *> CSTy = PrivCSArgAA->getPrivatizableType();
7423
7424 LLVM_DEBUG({
7425 dbgs() << "[AAPrivatizablePtr] ACSPos: " << ACSArgPos << ", CSTy: ";
7426 if (CSTy && *CSTy)
7427 (*CSTy)->print(dbgs());
7428 else if (CSTy)
7429 dbgs() << "<nullptr>";
7430 else
7431 dbgs() << "<none>";
7432 });
7433
7434 Ty = combineTypes(Ty, CSTy);
7435
7436 LLVM_DEBUG({
7437 dbgs() << " : New Type: ";
7438 if (Ty && *Ty)
7439 (*Ty)->print(dbgs());
7440 else if (Ty)
7441 dbgs() << "<nullptr>";
7442 else
7443 dbgs() << "<none>";
7444 dbgs() << "\n";
7445 });
7446
7447 return !Ty || *Ty;
7448 };
7449
7450 if (!A.checkForAllCallSites(CallSiteCheck, *this, true,
7451 UsedAssumedInformation))
7452 return nullptr;
7453 return Ty;
7454 }
7455
7456 /// See AbstractAttribute::updateImpl(...).
7457 ChangeStatus updateImpl(Attributor &A) override {
7458 PrivatizableType = identifyPrivatizableType(A);
7459 if (!PrivatizableType)
7460 return ChangeStatus::UNCHANGED;
7461 if (!*PrivatizableType)
7462 return indicatePessimisticFixpoint();
7463
7464 // The dependence is optional so we don't give up once we give up on the
7465 // alignment.
7466 A.getAAFor<AAAlign>(*this, IRPosition::value(getAssociatedValue()),
7467 DepClassTy::OPTIONAL);
7468
7469 // Avoid arguments with padding for now.
7470 if (!A.hasAttr(getIRPosition(), Attribute::ByVal) &&
7471 !isDenselyPacked(*PrivatizableType, A.getInfoCache().getDL())) {
7472 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Padding detected\n");
7473 return indicatePessimisticFixpoint();
7474 }
7475
7476 // Collect the types that will replace the privatizable type in the function
7477 // signature.
7478 SmallVector<Type *, 16> ReplacementTypes;
7479 identifyReplacementTypes(*PrivatizableType, ReplacementTypes);
7480
7481 // Verify callee and caller agree on how the promoted argument would be
7482 // passed.
7483 Function &Fn = *getIRPosition().getAnchorScope();
7484 const auto *TTI =
7485 A.getInfoCache().getAnalysisResultForFunction<TargetIRAnalysis>(Fn);
7486 if (!TTI) {
7487 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Missing TTI for function "
7488 << Fn.getName() << "\n");
7489 return indicatePessimisticFixpoint();
7490 }
7491
7492 auto CallSiteCheck = [&](AbstractCallSite ACS) {
7493 CallBase *CB = ACS.getInstruction();
7494 return TTI->areTypesABICompatible(
7495 CB->getCaller(),
7497 ReplacementTypes);
7498 };
7499 bool UsedAssumedInformation = false;
7500 if (!A.checkForAllCallSites(CallSiteCheck, *this, true,
7501 UsedAssumedInformation)) {
7502 LLVM_DEBUG(
7503 dbgs() << "[AAPrivatizablePtr] ABI incompatibility detected for "
7504 << Fn.getName() << "\n");
7505 return indicatePessimisticFixpoint();
7506 }
7507
7508 // Register a rewrite of the argument.
7509 Argument *Arg = getAssociatedArgument();
7510 if (!A.isValidFunctionSignatureRewrite(*Arg, ReplacementTypes)) {
7511 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Rewrite not valid\n");
7512 return indicatePessimisticFixpoint();
7513 }
7514
7515 unsigned ArgNo = Arg->getArgNo();
7516
7517 // Helper to check if for the given call site the associated argument is
7518 // passed to a callback where the privatization would be different.
7519 auto IsCompatiblePrivArgOfCallback = [&](CallBase &CB) {
7520 SmallVector<const Use *, 4> CallbackUses;
7521 AbstractCallSite::getCallbackUses(CB, CallbackUses);
7522 for (const Use *U : CallbackUses) {
7523 AbstractCallSite CBACS(U);
7524 assert(CBACS && CBACS.isCallbackCall());
7525 for (Argument &CBArg : CBACS.getCalledFunction()->args()) {
7526 int CBArgNo = CBACS.getCallArgOperandNo(CBArg);
7527
7528 LLVM_DEBUG({
7529 dbgs()
7530 << "[AAPrivatizablePtr] Argument " << *Arg
7531 << "check if can be privatized in the context of its parent ("
7532 << Arg->getParent()->getName()
7533 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7534 "callback ("
7535 << CBArgNo << "@" << CBACS.getCalledFunction()->getName()
7536 << ")\n[AAPrivatizablePtr] " << CBArg << " : "
7537 << CBACS.getCallArgOperand(CBArg) << " vs "
7538 << CB.getArgOperand(ArgNo) << "\n"
7539 << "[AAPrivatizablePtr] " << CBArg << " : "
7540 << CBACS.getCallArgOperandNo(CBArg) << " vs " << ArgNo << "\n";
7541 });
7542
7543 if (CBArgNo != int(ArgNo))
7544 continue;
7545 const auto *CBArgPrivAA = A.getAAFor<AAPrivatizablePtr>(
7546 *this, IRPosition::argument(CBArg), DepClassTy::REQUIRED);
7547 if (CBArgPrivAA && CBArgPrivAA->isValidState()) {
7548 auto CBArgPrivTy = CBArgPrivAA->getPrivatizableType();
7549 if (!CBArgPrivTy)
7550 continue;
7551 if (*CBArgPrivTy == PrivatizableType)
7552 continue;
7553 }
7554
7555 LLVM_DEBUG({
7556 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
7557 << " cannot be privatized in the context of its parent ("
7558 << Arg->getParent()->getName()
7559 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7560 "callback ("
7561 << CBArgNo << "@" << CBACS.getCalledFunction()->getName()
7562 << ").\n[AAPrivatizablePtr] for which the argument "
7563 "privatization is not compatible.\n";
7564 });
7565 return false;
7566 }
7567 }
7568 return true;
7569 };
7570
7571 // Helper to check if for the given call site the associated argument is
7572 // passed to a direct call where the privatization would be different.
7573 auto IsCompatiblePrivArgOfDirectCS = [&](AbstractCallSite ACS) {
7574 CallBase *DC = cast<CallBase>(ACS.getInstruction());
7575 int DCArgNo = ACS.getCallArgOperandNo(ArgNo);
7576 assert(DCArgNo >= 0 && unsigned(DCArgNo) < DC->arg_size() &&
7577 "Expected a direct call operand for callback call operand");
7578
7579 Function *DCCallee =
7581 LLVM_DEBUG({
7582 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
7583 << " check if be privatized in the context of its parent ("
7584 << Arg->getParent()->getName()
7585 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7586 "direct call of ("
7587 << DCArgNo << "@" << DCCallee->getName() << ").\n";
7588 });
7589
7590 if (unsigned(DCArgNo) < DCCallee->arg_size()) {
7591 const auto *DCArgPrivAA = A.getAAFor<AAPrivatizablePtr>(
7592 *this, IRPosition::argument(*DCCallee->getArg(DCArgNo)),
7593 DepClassTy::REQUIRED);
7594 if (DCArgPrivAA && DCArgPrivAA->isValidState()) {
7595 auto DCArgPrivTy = DCArgPrivAA->getPrivatizableType();
7596 if (!DCArgPrivTy)
7597 return true;
7598 if (*DCArgPrivTy == PrivatizableType)
7599 return true;
7600 }
7601 }
7602
7603 LLVM_DEBUG({
7604 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
7605 << " cannot be privatized in the context of its parent ("
7606 << Arg->getParent()->getName()
7607 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7608 "direct call of ("
7610 << ").\n[AAPrivatizablePtr] for which the argument "
7611 "privatization is not compatible.\n";
7612 });
7613 return false;
7614 };
7615
7616 // Helper to check if the associated argument is used at the given abstract
7617 // call site in a way that is incompatible with the privatization assumed
7618 // here.
7619 auto IsCompatiblePrivArgOfOtherCallSite = [&](AbstractCallSite ACS) {
7620 if (ACS.isDirectCall())
7621 return IsCompatiblePrivArgOfCallback(*ACS.getInstruction());
7622 if (ACS.isCallbackCall())
7623 return IsCompatiblePrivArgOfDirectCS(ACS);
7624 return false;
7625 };
7626
7627 if (!A.checkForAllCallSites(IsCompatiblePrivArgOfOtherCallSite, *this, true,
7628 UsedAssumedInformation))
7629 return indicatePessimisticFixpoint();
7630
7631 return ChangeStatus::UNCHANGED;
7632 }
7633
7634 /// Given a type to private \p PrivType, collect the constituates (which are
7635 /// used) in \p ReplacementTypes.
7636 static void
7637 identifyReplacementTypes(Type *PrivType,
7638 SmallVectorImpl<Type *> &ReplacementTypes) {
7639 // TODO: For now we expand the privatization type to the fullest which can
7640 // lead to dead arguments that need to be removed later.
7641 assert(PrivType && "Expected privatizable type!");
7642
7643 // Traverse the type, extract constituate types on the outermost level.
7644 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) {
7645 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++)
7646 ReplacementTypes.push_back(PrivStructType->getElementType(u));
7647 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) {
7648 ReplacementTypes.append(PrivArrayType->getNumElements(),
7649 PrivArrayType->getElementType());
7650 } else {
7651 ReplacementTypes.push_back(PrivType);
7652 }
7653 }
7654
7655 /// Initialize \p Base according to the type \p PrivType at position \p IP.
7656 /// The values needed are taken from the arguments of \p F starting at
7657 /// position \p ArgNo.
7658 static void createInitialization(Type *PrivType, Value &Base, Function &F,
7659 unsigned ArgNo, BasicBlock::iterator IP) {
7660 assert(PrivType && "Expected privatizable type!");
7661
7662 IRBuilder<NoFolder> IRB(IP->getParent(), IP);
7663 const DataLayout &DL = F.getDataLayout();
7664
7665 // Traverse the type, build GEPs and stores.
7666 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) {
7667 const StructLayout *PrivStructLayout = DL.getStructLayout(PrivStructType);
7668 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++) {
7669 Value *Ptr =
7670 constructPointer(&Base, PrivStructLayout->getElementOffset(u), IRB);
7671 new StoreInst(F.getArg(ArgNo + u), Ptr, IP);
7672 }
7673 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) {
7674 Type *PointeeTy = PrivArrayType->getElementType();
7675 uint64_t PointeeTySize = DL.getTypeStoreSize(PointeeTy);
7676 for (unsigned u = 0, e = PrivArrayType->getNumElements(); u < e; u++) {
7677 Value *Ptr = constructPointer(&Base, u * PointeeTySize, IRB);
7678 new StoreInst(F.getArg(ArgNo + u), Ptr, IP);
7679 }
7680 } else {
7681 new StoreInst(F.getArg(ArgNo), &Base, IP);
7682 }
7683 }
7684
7685 /// Extract values from \p Base according to the type \p PrivType at the
7686 /// call position \p ACS. The values are appended to \p ReplacementValues.
7687 void createReplacementValues(Align Alignment, Type *PrivType,
7688 AbstractCallSite ACS, Value *Base,
7689 SmallVectorImpl<Value *> &ReplacementValues) {
7690 assert(Base && "Expected base value!");
7691 assert(PrivType && "Expected privatizable type!");
7692 Instruction *IP = ACS.getInstruction();
7693
7694 IRBuilder<NoFolder> IRB(IP);
7695 const DataLayout &DL = IP->getDataLayout();
7696
7697 // Traverse the type, build GEPs and loads.
7698 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) {
7699 const StructLayout *PrivStructLayout = DL.getStructLayout(PrivStructType);
7700 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++) {
7701 Type *PointeeTy = PrivStructType->getElementType(u);
7702 Value *Ptr =
7703 constructPointer(Base, PrivStructLayout->getElementOffset(u), IRB);
7704 LoadInst *L = new LoadInst(PointeeTy, Ptr, "", IP->getIterator());
7705 L->setAlignment(Alignment);
7706 ReplacementValues.push_back(L);
7707 }
7708 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) {
7709 Type *PointeeTy = PrivArrayType->getElementType();
7710 uint64_t PointeeTySize = DL.getTypeStoreSize(PointeeTy);
7711 for (unsigned u = 0, e = PrivArrayType->getNumElements(); u < e; u++) {
7712 Value *Ptr = constructPointer(Base, u * PointeeTySize, IRB);
7713 LoadInst *L = new LoadInst(PointeeTy, Ptr, "", IP->getIterator());
7714 L->setAlignment(Alignment);
7715 ReplacementValues.push_back(L);
7716 }
7717 } else {
7718 LoadInst *L = new LoadInst(PrivType, Base, "", IP->getIterator());
7719 L->setAlignment(Alignment);
7720 ReplacementValues.push_back(L);
7721 }
7722 }
7723
7724 /// See AbstractAttribute::manifest(...)
7725 ChangeStatus manifest(Attributor &A) override {
7726 if (!PrivatizableType)
7727 return ChangeStatus::UNCHANGED;
7728 assert(*PrivatizableType && "Expected privatizable type!");
7729
7730 // Collect all tail calls in the function as we cannot allow new allocas to
7731 // escape into tail recursion.
7732 // TODO: Be smarter about new allocas escaping into tail calls.
7734 bool UsedAssumedInformation = false;
7735 if (!A.checkForAllInstructions(
7736 [&](Instruction &I) {
7737 CallInst &CI = cast<CallInst>(I);
7738 if (CI.isTailCall())
7739 TailCalls.push_back(&CI);
7740 return true;
7741 },
7742 *this, {Instruction::Call}, UsedAssumedInformation))
7743 return ChangeStatus::UNCHANGED;
7744
7745 Argument *Arg = getAssociatedArgument();
7746 // Query AAAlign attribute for alignment of associated argument to
7747 // determine the best alignment of loads.
7748 const auto *AlignAA =
7749 A.getAAFor<AAAlign>(*this, IRPosition::value(*Arg), DepClassTy::NONE);
7750
7751 // Callback to repair the associated function. A new alloca is placed at the
7752 // beginning and initialized with the values passed through arguments. The
7753 // new alloca replaces the use of the old pointer argument.
7755 [=](const Attributor::ArgumentReplacementInfo &ARI,
7756 Function &ReplacementFn, Function::arg_iterator ArgIt) {
7757 BasicBlock &EntryBB = ReplacementFn.getEntryBlock();
7759 const DataLayout &DL = IP->getDataLayout();
7760 unsigned AS = DL.getAllocaAddrSpace();
7761 Instruction *AI = new AllocaInst(*PrivatizableType, AS,
7762 Arg->getName() + ".priv", IP);
7763 createInitialization(*PrivatizableType, *AI, ReplacementFn,
7764 ArgIt->getArgNo(), IP);
7765
7766 if (AI->getType() != Arg->getType())
7767 AI = BitCastInst::CreatePointerBitCastOrAddrSpaceCast(
7768 AI, Arg->getType(), "", IP);
7769 Arg->replaceAllUsesWith(AI);
7770
7771 for (CallInst *CI : TailCalls)
7772 CI->setTailCall(false);
7773 };
7774
7775 // Callback to repair a call site of the associated function. The elements
7776 // of the privatizable type are loaded prior to the call and passed to the
7777 // new function version.
7779 [=](const Attributor::ArgumentReplacementInfo &ARI,
7780 AbstractCallSite ACS, SmallVectorImpl<Value *> &NewArgOperands) {
7781 // When no alignment is specified for the load instruction,
7782 // natural alignment is assumed.
7783 createReplacementValues(
7784 AlignAA ? AlignAA->getAssumedAlign() : Align(0),
7785 *PrivatizableType, ACS,
7786 ACS.getCallArgOperand(ARI.getReplacedArg().getArgNo()),
7787 NewArgOperands);
7788 };
7789
7790 // Collect the types that will replace the privatizable type in the function
7791 // signature.
7792 SmallVector<Type *, 16> ReplacementTypes;
7793 identifyReplacementTypes(*PrivatizableType, ReplacementTypes);
7794
7795 // Register a rewrite of the argument.
7796 if (A.registerFunctionSignatureRewrite(*Arg, ReplacementTypes,
7797 std::move(FnRepairCB),
7798 std::move(ACSRepairCB)))
7799 return ChangeStatus::CHANGED;
7800 return ChangeStatus::UNCHANGED;
7801 }
7802
7803 /// See AbstractAttribute::trackStatistics()
7804 void trackStatistics() const override {
7805 STATS_DECLTRACK_ARG_ATTR(privatizable_ptr);
7806 }
7807};
7808
7809struct AAPrivatizablePtrFloating : public AAPrivatizablePtrImpl {
7810 AAPrivatizablePtrFloating(const IRPosition &IRP, Attributor &A)
7811 : AAPrivatizablePtrImpl(IRP, A) {}
7812
7813 /// See AbstractAttribute::initialize(...).
7814 void initialize(Attributor &A) override {
7815 // TODO: We can privatize more than arguments.
7816 indicatePessimisticFixpoint();
7817 }
7818
7819 ChangeStatus updateImpl(Attributor &A) override {
7820 llvm_unreachable("AAPrivatizablePtr(Floating|Returned|CallSiteReturned)::"
7821 "updateImpl will not be called");
7822 }
7823
7824 /// See AAPrivatizablePtrImpl::identifyPrivatizableType(...)
7825 std::optional<Type *> identifyPrivatizableType(Attributor &A) override {
7826 Value *Obj = getUnderlyingObject(&getAssociatedValue());
7827 if (!Obj) {
7828 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] No underlying object found!\n");
7829 return nullptr;
7830 }
7831
7832 if (auto *AI = dyn_cast<AllocaInst>(Obj))
7833 if (auto *CI = dyn_cast<ConstantInt>(AI->getArraySize()))
7834 if (CI->isOne())
7835 return AI->getAllocatedType();
7836 if (auto *Arg = dyn_cast<Argument>(Obj)) {
7837 auto *PrivArgAA = A.getAAFor<AAPrivatizablePtr>(
7838 *this, IRPosition::argument(*Arg), DepClassTy::REQUIRED);
7839 if (PrivArgAA && PrivArgAA->isAssumedPrivatizablePtr())
7840 return PrivArgAA->getPrivatizableType();
7841 }
7842
7843 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Underlying object neither valid "
7844 "alloca nor privatizable argument: "
7845 << *Obj << "!\n");
7846 return nullptr;
7847 }
7848
7849 /// See AbstractAttribute::trackStatistics()
7850 void trackStatistics() const override {
7851 STATS_DECLTRACK_FLOATING_ATTR(privatizable_ptr);
7852 }
7853};
7854
7855struct AAPrivatizablePtrCallSiteArgument final
7856 : public AAPrivatizablePtrFloating {
7857 AAPrivatizablePtrCallSiteArgument(const IRPosition &IRP, Attributor &A)
7858 : AAPrivatizablePtrFloating(IRP, A) {}
7859
7860 /// See AbstractAttribute::initialize(...).
7861 void initialize(Attributor &A) override {
7862 if (A.hasAttr(getIRPosition(), Attribute::ByVal))
7863 indicateOptimisticFixpoint();
7864 }
7865
7866 /// See AbstractAttribute::updateImpl(...).
7867 ChangeStatus updateImpl(Attributor &A) override {
7868 PrivatizableType = identifyPrivatizableType(A);
7869 if (!PrivatizableType)
7870 return ChangeStatus::UNCHANGED;
7871 if (!*PrivatizableType)
7872 return indicatePessimisticFixpoint();
7873
7874 const IRPosition &IRP = getIRPosition();
7875 bool IsKnownNoCapture;
7876 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
7877 A, this, IRP, DepClassTy::REQUIRED, IsKnownNoCapture);
7878 if (!IsAssumedNoCapture) {
7879 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer might be captured!\n");
7880 return indicatePessimisticFixpoint();
7881 }
7882
7883 bool IsKnownNoAlias;
7885 A, this, IRP, DepClassTy::REQUIRED, IsKnownNoAlias)) {
7886 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer might alias!\n");
7887 return indicatePessimisticFixpoint();
7888 }
7889
7890 bool IsKnown;
7891 if (!AA::isAssumedReadOnly(A, IRP, *this, IsKnown)) {
7892 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer is written!\n");
7893 return indicatePessimisticFixpoint();
7894 }
7895
7896 return ChangeStatus::UNCHANGED;
7897 }
7898
7899 /// See AbstractAttribute::trackStatistics()
7900 void trackStatistics() const override {
7901 STATS_DECLTRACK_CSARG_ATTR(privatizable_ptr);
7902 }
7903};
7904
7905struct AAPrivatizablePtrCallSiteReturned final
7906 : public AAPrivatizablePtrFloating {
7907 AAPrivatizablePtrCallSiteReturned(const IRPosition &IRP, Attributor &A)
7908 : AAPrivatizablePtrFloating(IRP, A) {}
7909
7910 /// See AbstractAttribute::initialize(...).
7911 void initialize(Attributor &A) override {
7912 // TODO: We can privatize more than arguments.
7913 indicatePessimisticFixpoint();
7914 }
7915
7916 /// See AbstractAttribute::trackStatistics()
7917 void trackStatistics() const override {
7918 STATS_DECLTRACK_CSRET_ATTR(privatizable_ptr);
7919 }
7920};
7921
7922struct AAPrivatizablePtrReturned final : public AAPrivatizablePtrFloating {
7923 AAPrivatizablePtrReturned(const IRPosition &IRP, Attributor &A)
7924 : AAPrivatizablePtrFloating(IRP, A) {}
7925
7926 /// See AbstractAttribute::initialize(...).
7927 void initialize(Attributor &A) override {
7928 // TODO: We can privatize more than arguments.
7929 indicatePessimisticFixpoint();
7930 }
7931
7932 /// See AbstractAttribute::trackStatistics()
7933 void trackStatistics() const override {
7934 STATS_DECLTRACK_FNRET_ATTR(privatizable_ptr);
7935 }
7936};
7937} // namespace
7938
7939/// -------------------- Memory Behavior Attributes ----------------------------
7940/// Includes read-none, read-only, and write-only.
7941/// ----------------------------------------------------------------------------
7942namespace {
7943struct AAMemoryBehaviorImpl : public AAMemoryBehavior {
7944 AAMemoryBehaviorImpl(const IRPosition &IRP, Attributor &A)
7945 : AAMemoryBehavior(IRP, A) {}
7946
7947 /// See AbstractAttribute::initialize(...).
7948 void initialize(Attributor &A) override {
7949 intersectAssumedBits(BEST_STATE);
7950 getKnownStateFromValue(A, getIRPosition(), getState());
7951 AAMemoryBehavior::initialize(A);
7952 }
7953
7954 /// Return the memory behavior information encoded in the IR for \p IRP.
7955 static void getKnownStateFromValue(Attributor &A, const IRPosition &IRP,
7956 BitIntegerState &State,
7957 bool IgnoreSubsumingPositions = false) {
7959 A.getAttrs(IRP, AttrKinds, Attrs, IgnoreSubsumingPositions);
7960 for (const Attribute &Attr : Attrs) {
7961 switch (Attr.getKindAsEnum()) {
7962 case Attribute::ReadNone:
7963 State.addKnownBits(NO_ACCESSES);
7964 break;
7965 case Attribute::ReadOnly:
7966 State.addKnownBits(NO_WRITES);
7967 break;
7968 case Attribute::WriteOnly:
7969 State.addKnownBits(NO_READS);
7970 break;
7971 default:
7972 llvm_unreachable("Unexpected attribute!");
7973 }
7974 }
7975
7976 if (auto *I = dyn_cast<Instruction>(&IRP.getAnchorValue())) {
7977 if (!I->mayReadFromMemory())
7978 State.addKnownBits(NO_READS);
7979 if (!I->mayWriteToMemory())
7980 State.addKnownBits(NO_WRITES);
7981 }
7982 }
7983
7984 /// See AbstractAttribute::getDeducedAttributes(...).
7985 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
7986 SmallVectorImpl<Attribute> &Attrs) const override {
7987 assert(Attrs.size() == 0);
7988 if (isAssumedReadNone())
7989 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadNone));
7990 else if (isAssumedReadOnly())
7991 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadOnly));
7992 else if (isAssumedWriteOnly())
7993 Attrs.push_back(Attribute::get(Ctx, Attribute::WriteOnly));
7994 assert(Attrs.size() <= 1);
7995 }
7996
7997 /// See AbstractAttribute::manifest(...).
7998 ChangeStatus manifest(Attributor &A) override {
7999 const IRPosition &IRP = getIRPosition();
8000
8001 if (A.hasAttr(IRP, Attribute::ReadNone,
8002 /* IgnoreSubsumingPositions */ true))
8003 return ChangeStatus::UNCHANGED;
8004
8005 // Check if we would improve the existing attributes first.
8006 SmallVector<Attribute, 4> DeducedAttrs;
8007 getDeducedAttributes(A, IRP.getAnchorValue().getContext(), DeducedAttrs);
8008 if (llvm::all_of(DeducedAttrs, [&](const Attribute &Attr) {
8009 return A.hasAttr(IRP, Attr.getKindAsEnum(),
8010 /* IgnoreSubsumingPositions */ true);
8011 }))
8012 return ChangeStatus::UNCHANGED;
8013
8014 // Clear existing attributes.
8015 A.removeAttrs(IRP, AttrKinds);
8016 // Clear conflicting writable attribute.
8017 if (isAssumedReadOnly())
8018 A.removeAttrs(IRP, Attribute::Writable);
8019
8020 // Use the generic manifest method.
8021 return IRAttribute::manifest(A);
8022 }
8023
8024 /// See AbstractState::getAsStr().
8025 const std::string getAsStr(Attributor *A) const override {
8026 if (isAssumedReadNone())
8027 return "readnone";
8028 if (isAssumedReadOnly())
8029 return "readonly";
8030 if (isAssumedWriteOnly())
8031 return "writeonly";
8032 return "may-read/write";
8033 }
8034
8035 /// The set of IR attributes AAMemoryBehavior deals with.
8036 static const Attribute::AttrKind AttrKinds[3];
8037};
8038
8039const Attribute::AttrKind AAMemoryBehaviorImpl::AttrKinds[] = {
8040 Attribute::ReadNone, Attribute::ReadOnly, Attribute::WriteOnly};
8041
8042/// Memory behavior attribute for a floating value.
8043struct AAMemoryBehaviorFloating : AAMemoryBehaviorImpl {
8044 AAMemoryBehaviorFloating(const IRPosition &IRP, Attributor &A)
8045 : AAMemoryBehaviorImpl(IRP, A) {}
8046
8047 /// See AbstractAttribute::updateImpl(...).
8048 ChangeStatus updateImpl(Attributor &A) override;
8049
8050 /// See AbstractAttribute::trackStatistics()
8051 void trackStatistics() const override {
8052 if (isAssumedReadNone())
8054 else if (isAssumedReadOnly())
8056 else if (isAssumedWriteOnly())
8058 }
8059
8060private:
8061 /// Return true if users of \p UserI might access the underlying
8062 /// variable/location described by \p U and should therefore be analyzed.
8063 bool followUsersOfUseIn(Attributor &A, const Use &U,
8064 const Instruction *UserI);
8065
8066 /// Update the state according to the effect of use \p U in \p UserI.
8067 void analyzeUseIn(Attributor &A, const Use &U, const Instruction *UserI);
8068};
8069
8070/// Memory behavior attribute for function argument.
8071struct AAMemoryBehaviorArgument : AAMemoryBehaviorFloating {
8072 AAMemoryBehaviorArgument(const IRPosition &IRP, Attributor &A)
8073 : AAMemoryBehaviorFloating(IRP, A) {}
8074
8075 /// See AbstractAttribute::initialize(...).
8076 void initialize(Attributor &A) override {
8077 intersectAssumedBits(BEST_STATE);
8078 const IRPosition &IRP = getIRPosition();
8079 // TODO: Make IgnoreSubsumingPositions a property of an IRAttribute so we
8080 // can query it when we use has/getAttr. That would allow us to reuse the
8081 // initialize of the base class here.
8082 bool HasByVal = A.hasAttr(IRP, {Attribute::ByVal},
8083 /* IgnoreSubsumingPositions */ true);
8084 getKnownStateFromValue(A, IRP, getState(),
8085 /* IgnoreSubsumingPositions */ HasByVal);
8086 }
8087
8088 ChangeStatus manifest(Attributor &A) override {
8089 // TODO: Pointer arguments are not supported on vectors of pointers yet.
8090 if (!getAssociatedValue().getType()->isPointerTy())
8091 return ChangeStatus::UNCHANGED;
8092
8093 // TODO: From readattrs.ll: "inalloca parameters are always
8094 // considered written"
8095 if (A.hasAttr(getIRPosition(),
8096 {Attribute::InAlloca, Attribute::Preallocated})) {
8097 removeKnownBits(NO_WRITES);
8098 removeAssumedBits(NO_WRITES);
8099 }
8100 A.removeAttrs(getIRPosition(), AttrKinds);
8101 return AAMemoryBehaviorFloating::manifest(A);
8102 }
8103
8104 /// See AbstractAttribute::trackStatistics()
8105 void trackStatistics() const override {
8106 if (isAssumedReadNone())
8107 STATS_DECLTRACK_ARG_ATTR(readnone)
8108 else if (isAssumedReadOnly())
8109 STATS_DECLTRACK_ARG_ATTR(readonly)
8110 else if (isAssumedWriteOnly())
8111 STATS_DECLTRACK_ARG_ATTR(writeonly)
8112 }
8113};
8114
8115struct AAMemoryBehaviorCallSiteArgument final : AAMemoryBehaviorArgument {
8116 AAMemoryBehaviorCallSiteArgument(const IRPosition &IRP, Attributor &A)
8117 : AAMemoryBehaviorArgument(IRP, A) {}
8118
8119 /// See AbstractAttribute::initialize(...).
8120 void initialize(Attributor &A) override {
8121 // If we don't have an associated attribute this is either a variadic call
8122 // or an indirect call, either way, nothing to do here.
8123 Argument *Arg = getAssociatedArgument();
8124 if (!Arg) {
8125 indicatePessimisticFixpoint();
8126 return;
8127 }
8128 if (Arg->hasByValAttr()) {
8129 addKnownBits(NO_WRITES);
8130 removeKnownBits(NO_READS);
8131 removeAssumedBits(NO_READS);
8132 }
8133 AAMemoryBehaviorArgument::initialize(A);
8134 if (getAssociatedFunction()->isDeclaration())
8135 indicatePessimisticFixpoint();
8136 }
8137
8138 /// See AbstractAttribute::updateImpl(...).
8139 ChangeStatus updateImpl(Attributor &A) override {
8140 // TODO: Once we have call site specific value information we can provide
8141 // call site specific liveness liveness information and then it makes
8142 // sense to specialize attributes for call sites arguments instead of
8143 // redirecting requests to the callee argument.
8144 Argument *Arg = getAssociatedArgument();
8145 const IRPosition &ArgPos = IRPosition::argument(*Arg);
8146 auto *ArgAA =
8147 A.getAAFor<AAMemoryBehavior>(*this, ArgPos, DepClassTy::REQUIRED);
8148 if (!ArgAA)
8149 return indicatePessimisticFixpoint();
8150 return clampStateAndIndicateChange(getState(), ArgAA->getState());
8151 }
8152
8153 /// See AbstractAttribute::trackStatistics()
8154 void trackStatistics() const override {
8155 if (isAssumedReadNone())
8157 else if (isAssumedReadOnly())
8159 else if (isAssumedWriteOnly())
8161 }
8162};
8163
8164/// Memory behavior attribute for a call site return position.
8165struct AAMemoryBehaviorCallSiteReturned final : AAMemoryBehaviorFloating {
8166 AAMemoryBehaviorCallSiteReturned(const IRPosition &IRP, Attributor &A)
8167 : AAMemoryBehaviorFloating(IRP, A) {}
8168
8169 /// See AbstractAttribute::initialize(...).
8170 void initialize(Attributor &A) override {
8171 AAMemoryBehaviorImpl::initialize(A);
8172 }
8173 /// See AbstractAttribute::manifest(...).
8174 ChangeStatus manifest(Attributor &A) override {
8175 // We do not annotate returned values.
8176 return ChangeStatus::UNCHANGED;
8177 }
8178
8179 /// See AbstractAttribute::trackStatistics()
8180 void trackStatistics() const override {}
8181};
8182
8183/// An AA to represent the memory behavior function attributes.
8184struct AAMemoryBehaviorFunction final : public AAMemoryBehaviorImpl {
8185 AAMemoryBehaviorFunction(const IRPosition &IRP, Attributor &A)
8186 : AAMemoryBehaviorImpl(IRP, A) {}
8187
8188 /// See AbstractAttribute::updateImpl(Attributor &A).
8189 ChangeStatus updateImpl(Attributor &A) override;
8190
8191 /// See AbstractAttribute::manifest(...).
8192 ChangeStatus manifest(Attributor &A) override {
8193 // TODO: It would be better to merge this with AAMemoryLocation, so that
8194 // we could determine read/write per location. This would also have the
8195 // benefit of only one place trying to manifest the memory attribute.
8196 Function &F = cast<Function>(getAnchorValue());
8198 if (isAssumedReadNone())
8199 ME = MemoryEffects::none();
8200 else if (isAssumedReadOnly())
8202 else if (isAssumedWriteOnly())
8204
8205 A.removeAttrs(getIRPosition(), AttrKinds);
8206 // Clear conflicting writable attribute.
8207 if (ME.onlyReadsMemory())
8208 for (Argument &Arg : F.args())
8209 A.removeAttrs(IRPosition::argument(Arg), Attribute::Writable);
8210 return A.manifestAttrs(getIRPosition(),
8211 Attribute::getWithMemoryEffects(F.getContext(), ME));
8212 }
8213
8214 /// See AbstractAttribute::trackStatistics()
8215 void trackStatistics() const override {
8216 if (isAssumedReadNone())
8217 STATS_DECLTRACK_FN_ATTR(readnone)
8218 else if (isAssumedReadOnly())
8219 STATS_DECLTRACK_FN_ATTR(readonly)
8220 else if (isAssumedWriteOnly())
8221 STATS_DECLTRACK_FN_ATTR(writeonly)
8222 }
8223};
8224
8225/// AAMemoryBehavior attribute for call sites.
8226struct AAMemoryBehaviorCallSite final
8227 : AACalleeToCallSite<AAMemoryBehavior, AAMemoryBehaviorImpl> {
8228 AAMemoryBehaviorCallSite(const IRPosition &IRP, Attributor &A)
8229 : AACalleeToCallSite<AAMemoryBehavior, AAMemoryBehaviorImpl>(IRP, A) {}
8230
8231 /// See AbstractAttribute::manifest(...).
8232 ChangeStatus manifest(Attributor &A) override {
8233 // TODO: Deduplicate this with AAMemoryBehaviorFunction.
8234 CallBase &CB = cast<CallBase>(getAnchorValue());
8236 if (isAssumedReadNone())
8237 ME = MemoryEffects::none();
8238 else if (isAssumedReadOnly())
8240 else if (isAssumedWriteOnly())
8242
8243 A.removeAttrs(getIRPosition(), AttrKinds);
8244 // Clear conflicting writable attribute.
8245 if (ME.onlyReadsMemory())
8246 for (Use &U : CB.args())
8247 A.removeAttrs(IRPosition::callsite_argument(CB, U.getOperandNo()),
8248 Attribute::Writable);
8249 return A.manifestAttrs(
8250 getIRPosition(), Attribute::getWithMemoryEffects(CB.getContext(), ME));
8251 }
8252
8253 /// See AbstractAttribute::trackStatistics()
8254 void trackStatistics() const override {
8255 if (isAssumedReadNone())
8256 STATS_DECLTRACK_CS_ATTR(readnone)
8257 else if (isAssumedReadOnly())
8258 STATS_DECLTRACK_CS_ATTR(readonly)
8259 else if (isAssumedWriteOnly())
8260 STATS_DECLTRACK_CS_ATTR(writeonly)
8261 }
8262};
8263
8264ChangeStatus AAMemoryBehaviorFunction::updateImpl(Attributor &A) {
8265
8266 // The current assumed state used to determine a change.
8267 auto AssumedState = getAssumed();
8268
8269 auto CheckRWInst = [&](Instruction &I) {
8270 // If the instruction has an own memory behavior state, use it to restrict
8271 // the local state. No further analysis is required as the other memory
8272 // state is as optimistic as it gets.
8273 if (const auto *CB = dyn_cast<CallBase>(&I)) {
8274 const auto *MemBehaviorAA = A.getAAFor<AAMemoryBehavior>(
8276 if (MemBehaviorAA) {
8277 intersectAssumedBits(MemBehaviorAA->getAssumed());
8278 return !isAtFixpoint();
8279 }
8280 }
8281
8282 // Remove access kind modifiers if necessary.
8283 if (I.mayReadFromMemory())
8284 removeAssumedBits(NO_READS);
8285 if (I.mayWriteToMemory())
8286 removeAssumedBits(NO_WRITES);
8287 return !isAtFixpoint();
8288 };
8289
8290 bool UsedAssumedInformation = false;
8291 if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this,
8292 UsedAssumedInformation))
8293 return indicatePessimisticFixpoint();
8294
8295 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
8297}
8298
8299ChangeStatus AAMemoryBehaviorFloating::updateImpl(Attributor &A) {
8300
8301 const IRPosition &IRP = getIRPosition();
8302 const IRPosition &FnPos = IRPosition::function_scope(IRP);
8303 AAMemoryBehavior::StateType &S = getState();
8304
8305 // First, check the function scope. We take the known information and we avoid
8306 // work if the assumed information implies the current assumed information for
8307 // this attribute. This is a valid for all but byval arguments.
8308 Argument *Arg = IRP.getAssociatedArgument();
8309 AAMemoryBehavior::base_t FnMemAssumedState =
8311 if (!Arg || !Arg->hasByValAttr()) {
8312 const auto *FnMemAA =
8313 A.getAAFor<AAMemoryBehavior>(*this, FnPos, DepClassTy::OPTIONAL);
8314 if (FnMemAA) {
8315 FnMemAssumedState = FnMemAA->getAssumed();
8316 S.addKnownBits(FnMemAA->getKnown());
8317 if ((S.getAssumed() & FnMemAA->getAssumed()) == S.getAssumed())
8319 }
8320 }
8321
8322 // The current assumed state used to determine a change.
8323 auto AssumedState = S.getAssumed();
8324
8325 // Make sure the value is not captured (except through "return"), if
8326 // it is, any information derived would be irrelevant anyway as we cannot
8327 // check the potential aliases introduced by the capture. However, no need
8328 // to fall back to anythign less optimistic than the function state.
8329 bool IsKnownNoCapture;
8330 const AANoCapture *ArgNoCaptureAA = nullptr;
8331 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
8332 A, this, IRP, DepClassTy::OPTIONAL, IsKnownNoCapture, false,
8333 &ArgNoCaptureAA);
8334
8335 if (!IsAssumedNoCapture &&
8336 (!ArgNoCaptureAA || !ArgNoCaptureAA->isAssumedNoCaptureMaybeReturned())) {
8337 S.intersectAssumedBits(FnMemAssumedState);
8338 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
8340 }
8341
8342 // Visit and expand uses until all are analyzed or a fixpoint is reached.
8343 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
8344 Instruction *UserI = cast<Instruction>(U.getUser());
8345 LLVM_DEBUG(dbgs() << "[AAMemoryBehavior] Use: " << *U << " in " << *UserI
8346 << " \n");
8347
8348 // Droppable users, e.g., llvm::assume does not actually perform any action.
8349 if (UserI->isDroppable())
8350 return true;
8351
8352 // Check if the users of UserI should also be visited.
8353 Follow = followUsersOfUseIn(A, U, UserI);
8354
8355 // If UserI might touch memory we analyze the use in detail.
8356 if (UserI->mayReadOrWriteMemory())
8357 analyzeUseIn(A, U, UserI);
8358
8359 return !isAtFixpoint();
8360 };
8361
8362 if (!A.checkForAllUses(UsePred, *this, getAssociatedValue()))
8363 return indicatePessimisticFixpoint();
8364
8365 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
8367}
8368
8369bool AAMemoryBehaviorFloating::followUsersOfUseIn(Attributor &A, const Use &U,
8370 const Instruction *UserI) {
8371 // The loaded value is unrelated to the pointer argument, no need to
8372 // follow the users of the load.
8373 if (isa<LoadInst>(UserI) || isa<ReturnInst>(UserI))
8374 return false;
8375
8376 // By default we follow all uses assuming UserI might leak information on U,
8377 // we have special handling for call sites operands though.
8378 const auto *CB = dyn_cast<CallBase>(UserI);
8379 if (!CB || !CB->isArgOperand(&U))
8380 return true;
8381
8382 // If the use is a call argument known not to be captured, the users of
8383 // the call do not need to be visited because they have to be unrelated to
8384 // the input. Note that this check is not trivial even though we disallow
8385 // general capturing of the underlying argument. The reason is that the
8386 // call might the argument "through return", which we allow and for which we
8387 // need to check call users.
8388 if (U.get()->getType()->isPointerTy()) {
8389 unsigned ArgNo = CB->getArgOperandNo(&U);
8390 bool IsKnownNoCapture;
8392 A, this, IRPosition::callsite_argument(*CB, ArgNo),
8393 DepClassTy::OPTIONAL, IsKnownNoCapture);
8394 }
8395
8396 return true;
8397}
8398
8399void AAMemoryBehaviorFloating::analyzeUseIn(Attributor &A, const Use &U,
8400 const Instruction *UserI) {
8401 assert(UserI->mayReadOrWriteMemory());
8402
8403 switch (UserI->getOpcode()) {
8404 default:
8405 // TODO: Handle all atomics and other side-effect operations we know of.
8406 break;
8407 case Instruction::Load:
8408 // Loads cause the NO_READS property to disappear.
8409 removeAssumedBits(NO_READS);
8410 return;
8411
8412 case Instruction::Store:
8413 // Stores cause the NO_WRITES property to disappear if the use is the
8414 // pointer operand. Note that while capturing was taken care of somewhere
8415 // else we need to deal with stores of the value that is not looked through.
8416 if (cast<StoreInst>(UserI)->getPointerOperand() == U.get())
8417 removeAssumedBits(NO_WRITES);
8418 else
8419 indicatePessimisticFixpoint();
8420 return;
8421
8422 case Instruction::Call:
8423 case Instruction::CallBr:
8424 case Instruction::Invoke: {
8425 // For call sites we look at the argument memory behavior attribute (this
8426 // could be recursive!) in order to restrict our own state.
8427 const auto *CB = cast<CallBase>(UserI);
8428
8429 // Give up on operand bundles.
8430 if (CB->isBundleOperand(&U)) {
8431 indicatePessimisticFixpoint();
8432 return;
8433 }
8434
8435 // Calling a function does read the function pointer, maybe write it if the
8436 // function is self-modifying.
8437 if (CB->isCallee(&U)) {
8438 removeAssumedBits(NO_READS);
8439 break;
8440 }
8441
8442 // Adjust the possible access behavior based on the information on the
8443 // argument.
8444 IRPosition Pos;
8445 if (U.get()->getType()->isPointerTy())
8447 else
8449 const auto *MemBehaviorAA =
8450 A.getAAFor<AAMemoryBehavior>(*this, Pos, DepClassTy::OPTIONAL);
8451 if (!MemBehaviorAA)
8452 break;
8453 // "assumed" has at most the same bits as the MemBehaviorAA assumed
8454 // and at least "known".
8455 intersectAssumedBits(MemBehaviorAA->getAssumed());
8456 return;
8457 }
8458 };
8459
8460 // Generally, look at the "may-properties" and adjust the assumed state if we
8461 // did not trigger special handling before.
8462 if (UserI->mayReadFromMemory())
8463 removeAssumedBits(NO_READS);
8464 if (UserI->mayWriteToMemory())
8465 removeAssumedBits(NO_WRITES);
8466}
8467} // namespace
8468
8469/// -------------------- Memory Locations Attributes ---------------------------
8470/// Includes read-none, argmemonly, inaccessiblememonly,
8471/// inaccessiblememorargmemonly
8472/// ----------------------------------------------------------------------------
8473
8476 if (0 == (MLK & AAMemoryLocation::NO_LOCATIONS))
8477 return "all memory";
8479 return "no memory";
8480 std::string S = "memory:";
8481 if (0 == (MLK & AAMemoryLocation::NO_LOCAL_MEM))
8482 S += "stack,";
8483 if (0 == (MLK & AAMemoryLocation::NO_CONST_MEM))
8484 S += "constant,";
8486 S += "internal global,";
8488 S += "external global,";
8489 if (0 == (MLK & AAMemoryLocation::NO_ARGUMENT_MEM))
8490 S += "argument,";
8492 S += "inaccessible,";
8493 if (0 == (MLK & AAMemoryLocation::NO_MALLOCED_MEM))
8494 S += "malloced,";
8495 if (0 == (MLK & AAMemoryLocation::NO_UNKOWN_MEM))
8496 S += "unknown,";
8497 S.pop_back();
8498 return S;
8499}
8500
8501namespace {
8502struct AAMemoryLocationImpl : public AAMemoryLocation {
8503
8504 AAMemoryLocationImpl(const IRPosition &IRP, Attributor &A)
8505 : AAMemoryLocation(IRP, A), Allocator(A.Allocator) {
8506 AccessKind2Accesses.fill(nullptr);
8507 }
8508
8509 ~AAMemoryLocationImpl() override {
8510 // The AccessSets are allocated via a BumpPtrAllocator, we call
8511 // the destructor manually.
8512 for (AccessSet *AS : AccessKind2Accesses)
8513 if (AS)
8514 AS->~AccessSet();
8515 }
8516
8517 /// See AbstractAttribute::initialize(...).
8518 void initialize(Attributor &A) override {
8519 intersectAssumedBits(BEST_STATE);
8520 getKnownStateFromValue(A, getIRPosition(), getState());
8521 AAMemoryLocation::initialize(A);
8522 }
8523
8524 /// Return the memory behavior information encoded in the IR for \p IRP.
8525 static void getKnownStateFromValue(Attributor &A, const IRPosition &IRP,
8526 BitIntegerState &State,
8527 bool IgnoreSubsumingPositions = false) {
8528 // For internal functions we ignore `argmemonly` and
8529 // `inaccessiblememorargmemonly` as we might break it via interprocedural
8530 // constant propagation. It is unclear if this is the best way but it is
8531 // unlikely this will cause real performance problems. If we are deriving
8532 // attributes for the anchor function we even remove the attribute in
8533 // addition to ignoring it.
8534 // TODO: A better way to handle this would be to add ~NO_GLOBAL_MEM /
8535 // MemoryEffects::Other as a possible location.
8536 bool UseArgMemOnly = true;
8537 Function *AnchorFn = IRP.getAnchorScope();
8538 if (AnchorFn && A.isRunOn(*AnchorFn))
8539 UseArgMemOnly = !AnchorFn->hasLocalLinkage();
8540
8542 A.getAttrs(IRP, {Attribute::Memory}, Attrs, IgnoreSubsumingPositions);
8543 for (const Attribute &Attr : Attrs) {
8544 // TODO: We can map MemoryEffects to Attributor locations more precisely.
8545 MemoryEffects ME = Attr.getMemoryEffects();
8546 if (ME.doesNotAccessMemory()) {
8547 State.addKnownBits(NO_LOCAL_MEM | NO_CONST_MEM);
8548 continue;
8549 }
8550 if (ME.onlyAccessesInaccessibleMem()) {
8551 State.addKnownBits(inverseLocation(NO_INACCESSIBLE_MEM, true, true));
8552 continue;
8553 }
8554 if (ME.onlyAccessesArgPointees()) {
8555 if (UseArgMemOnly)
8556 State.addKnownBits(inverseLocation(NO_ARGUMENT_MEM, true, true));
8557 else {
8558 // Remove location information, only keep read/write info.
8559 ME = MemoryEffects(ME.getModRef());
8560 A.manifestAttrs(IRP,
8561 Attribute::getWithMemoryEffects(
8562 IRP.getAnchorValue().getContext(), ME),
8563 /*ForceReplace*/ true);
8564 }
8565 continue;
8566 }
8568 if (UseArgMemOnly)
8569 State.addKnownBits(inverseLocation(
8570 NO_INACCESSIBLE_MEM | NO_ARGUMENT_MEM, true, true));
8571 else {
8572 // Remove location information, only keep read/write info.
8573 ME = MemoryEffects(ME.getModRef());
8574 A.manifestAttrs(IRP,
8575 Attribute::getWithMemoryEffects(
8576 IRP.getAnchorValue().getContext(), ME),
8577 /*ForceReplace*/ true);
8578 }
8579 continue;
8580 }
8581 }
8582 }
8583
8584 /// See AbstractAttribute::getDeducedAttributes(...).
8585 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
8586 SmallVectorImpl<Attribute> &Attrs) const override {
8587 // TODO: We can map Attributor locations to MemoryEffects more precisely.
8588 assert(Attrs.size() == 0);
8589 if (getIRPosition().getPositionKind() == IRPosition::IRP_FUNCTION) {
8590 if (isAssumedReadNone())
8591 Attrs.push_back(
8592 Attribute::getWithMemoryEffects(Ctx, MemoryEffects::none()));
8593 else if (isAssumedInaccessibleMemOnly())
8594 Attrs.push_back(Attribute::getWithMemoryEffects(
8596 else if (isAssumedArgMemOnly())
8597 Attrs.push_back(
8598 Attribute::getWithMemoryEffects(Ctx, MemoryEffects::argMemOnly()));
8599 else if (isAssumedInaccessibleOrArgMemOnly())
8600 Attrs.push_back(Attribute::getWithMemoryEffects(
8602 }
8603 assert(Attrs.size() <= 1);
8604 }
8605
8606 /// See AbstractAttribute::manifest(...).
8607 ChangeStatus manifest(Attributor &A) override {
8608 // TODO: If AAMemoryLocation and AAMemoryBehavior are merged, we could
8609 // provide per-location modref information here.
8610 const IRPosition &IRP = getIRPosition();
8611
8612 SmallVector<Attribute, 1> DeducedAttrs;
8613 getDeducedAttributes(A, IRP.getAnchorValue().getContext(), DeducedAttrs);
8614 if (DeducedAttrs.size() != 1)
8615 return ChangeStatus::UNCHANGED;
8616 MemoryEffects ME = DeducedAttrs[0].getMemoryEffects();
8617
8618 return A.manifestAttrs(IRP, Attribute::getWithMemoryEffects(
8619 IRP.getAnchorValue().getContext(), ME));
8620 }
8621
8622 /// See AAMemoryLocation::checkForAllAccessesToMemoryKind(...).
8623 bool checkForAllAccessesToMemoryKind(
8624 function_ref<bool(const Instruction *, const Value *, AccessKind,
8625 MemoryLocationsKind)>
8626 Pred,
8627 MemoryLocationsKind RequestedMLK) const override {
8628 if (!isValidState())
8629 return false;
8630
8631 MemoryLocationsKind AssumedMLK = getAssumedNotAccessedLocation();
8632 if (AssumedMLK == NO_LOCATIONS)
8633 return true;
8634
8635 unsigned Idx = 0;
8636 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS;
8637 CurMLK *= 2, ++Idx) {
8638 if (CurMLK & RequestedMLK)
8639 continue;
8640
8641 if (const AccessSet *Accesses = AccessKind2Accesses[Idx])
8642 for (const AccessInfo &AI : *Accesses)
8643 if (!Pred(AI.I, AI.Ptr, AI.Kind, CurMLK))
8644 return false;
8645 }
8646
8647 return true;
8648 }
8649
8650 ChangeStatus indicatePessimisticFixpoint() override {
8651 // If we give up and indicate a pessimistic fixpoint this instruction will
8652 // become an access for all potential access kinds:
8653 // TODO: Add pointers for argmemonly and globals to improve the results of
8654 // checkForAllAccessesToMemoryKind.
8655 bool Changed = false;
8656 MemoryLocationsKind KnownMLK = getKnown();
8657 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
8658 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS; CurMLK *= 2)
8659 if (!(CurMLK & KnownMLK))
8660 updateStateAndAccessesMap(getState(), CurMLK, I, nullptr, Changed,
8661 getAccessKindFromInst(I));
8662 return AAMemoryLocation::indicatePessimisticFixpoint();
8663 }
8664
8665protected:
8666 /// Helper struct to tie together an instruction that has a read or write
8667 /// effect with the pointer it accesses (if any).
8668 struct AccessInfo {
8669
8670 /// The instruction that caused the access.
8671 const Instruction *I;
8672
8673 /// The base pointer that is accessed, or null if unknown.
8674 const Value *Ptr;
8675
8676 /// The kind of access (read/write/read+write).
8678
8679 bool operator==(const AccessInfo &RHS) const {
8680 return I == RHS.I && Ptr == RHS.Ptr && Kind == RHS.Kind;
8681 }
8682 bool operator()(const AccessInfo &LHS, const AccessInfo &RHS) const {
8683 if (LHS.I != RHS.I)
8684 return LHS.I < RHS.I;
8685 if (LHS.Ptr != RHS.Ptr)
8686 return LHS.Ptr < RHS.Ptr;
8687 if (LHS.Kind != RHS.Kind)
8688 return LHS.Kind < RHS.Kind;
8689 return false;
8690 }
8691 };
8692
8693 /// Mapping from *single* memory location kinds, e.g., LOCAL_MEM with the
8694 /// value of NO_LOCAL_MEM, to the accesses encountered for this memory kind.
8695 using AccessSet = SmallSet<AccessInfo, 2, AccessInfo>;
8696 std::array<AccessSet *, llvm::ConstantLog2<VALID_STATE>()>
8697 AccessKind2Accesses;
8698
8699 /// Categorize the pointer arguments of CB that might access memory in
8700 /// AccessedLoc and update the state and access map accordingly.
8701 void
8702 categorizeArgumentPointerLocations(Attributor &A, CallBase &CB,
8703 AAMemoryLocation::StateType &AccessedLocs,
8704 bool &Changed);
8705
8706 /// Return the kind(s) of location that may be accessed by \p V.
8708 categorizeAccessedLocations(Attributor &A, Instruction &I, bool &Changed);
8709
8710 /// Return the access kind as determined by \p I.
8711 AccessKind getAccessKindFromInst(const Instruction *I) {
8712 AccessKind AK = READ_WRITE;
8713 if (I) {
8714 AK = I->mayReadFromMemory() ? READ : NONE;
8715 AK = AccessKind(AK | (I->mayWriteToMemory() ? WRITE : NONE));
8716 }
8717 return AK;
8718 }
8719
8720 /// Update the state \p State and the AccessKind2Accesses given that \p I is
8721 /// an access of kind \p AK to a \p MLK memory location with the access
8722 /// pointer \p Ptr.
8723 void updateStateAndAccessesMap(AAMemoryLocation::StateType &State,
8724 MemoryLocationsKind MLK, const Instruction *I,
8725 const Value *Ptr, bool &Changed,
8726 AccessKind AK = READ_WRITE) {
8727
8728 assert(isPowerOf2_32(MLK) && "Expected a single location set!");
8729 auto *&Accesses = AccessKind2Accesses[llvm::Log2_32(MLK)];
8730 if (!Accesses)
8731 Accesses = new (Allocator) AccessSet();
8732 Changed |= Accesses->insert(AccessInfo{I, Ptr, AK}).second;
8733 if (MLK == NO_UNKOWN_MEM)
8734 MLK = NO_LOCATIONS;
8735 State.removeAssumedBits(MLK);
8736 }
8737
8738 /// Determine the underlying locations kinds for \p Ptr, e.g., globals or
8739 /// arguments, and update the state and access map accordingly.
8740 void categorizePtrValue(Attributor &A, const Instruction &I, const Value &Ptr,
8741 AAMemoryLocation::StateType &State, bool &Changed,
8742 unsigned AccessAS = 0);
8743
8744 /// Used to allocate access sets.
8746};
8747
8748void AAMemoryLocationImpl::categorizePtrValue(
8749 Attributor &A, const Instruction &I, const Value &Ptr,
8750 AAMemoryLocation::StateType &State, bool &Changed, unsigned AccessAS) {
8751 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize pointer locations for "
8752 << Ptr << " ["
8753 << getMemoryLocationsAsStr(State.getAssumed()) << "]\n");
8754
8755 auto Pred = [&](Value &Obj) {
8756 unsigned ObjectAS = Obj.getType()->getPointerAddressSpace();
8757 // TODO: recognize the TBAA used for constant accesses.
8758 MemoryLocationsKind MLK = NO_LOCATIONS;
8759
8760 // Filter accesses to constant (GPU) memory if we have an AS at the access
8761 // site or the object is known to actually have the associated AS.
8762 if (AA::isGPU(A.getModule())) {
8763 if (AA::isGPUConstantAddressSpace(A.getModule(), AccessAS) ||
8764 (AA::isGPUConstantAddressSpace(A.getModule(), ObjectAS) &&
8765 isIdentifiedObject(&Obj)))
8766 return true;
8767 }
8768
8769 if (isa<UndefValue>(&Obj))
8770 return true;
8771 if (isa<Argument>(&Obj)) {
8772 // TODO: For now we do not treat byval arguments as local copies performed
8773 // on the call edge, though, we should. To make that happen we need to
8774 // teach various passes, e.g., DSE, about the copy effect of a byval. That
8775 // would also allow us to mark functions only accessing byval arguments as
8776 // readnone again, arguably their accesses have no effect outside of the
8777 // function, like accesses to allocas.
8778 MLK = NO_ARGUMENT_MEM;
8779 } else if (auto *GV = dyn_cast<GlobalValue>(&Obj)) {
8780 // Reading constant memory is not treated as a read "effect" by the
8781 // function attr pass so we won't neither. Constants defined by TBAA are
8782 // similar. (We know we do not write it because it is constant.)
8783 if (auto *GVar = dyn_cast<GlobalVariable>(GV))
8784 if (GVar->isConstant())
8785 return true;
8786
8787 if (GV->hasLocalLinkage())
8788 MLK = NO_GLOBAL_INTERNAL_MEM;
8789 else
8790 MLK = NO_GLOBAL_EXTERNAL_MEM;
8791 } else if (isa<ConstantPointerNull>(&Obj) &&
8792 (!NullPointerIsDefined(getAssociatedFunction(), AccessAS) ||
8793 !NullPointerIsDefined(getAssociatedFunction(), ObjectAS))) {
8794 return true;
8795 } else if (isa<AllocaInst>(&Obj)) {
8796 MLK = NO_LOCAL_MEM;
8797 } else if (const auto *CB = dyn_cast<CallBase>(&Obj)) {
8798 bool IsKnownNoAlias;
8801 IsKnownNoAlias))
8802 MLK = NO_MALLOCED_MEM;
8803 else
8804 MLK = NO_UNKOWN_MEM;
8805 } else {
8806 MLK = NO_UNKOWN_MEM;
8807 }
8808
8809 assert(MLK != NO_LOCATIONS && "No location specified!");
8810 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Ptr value can be categorized: "
8811 << Obj << " -> " << getMemoryLocationsAsStr(MLK) << "\n");
8812 updateStateAndAccessesMap(State, MLK, &I, &Obj, Changed,
8813 getAccessKindFromInst(&I));
8814
8815 return true;
8816 };
8817
8818 const auto *AA = A.getAAFor<AAUnderlyingObjects>(
8820 if (!AA || !AA->forallUnderlyingObjects(Pred, AA::Intraprocedural)) {
8821 LLVM_DEBUG(
8822 dbgs() << "[AAMemoryLocation] Pointer locations not categorized\n");
8823 updateStateAndAccessesMap(State, NO_UNKOWN_MEM, &I, nullptr, Changed,
8824 getAccessKindFromInst(&I));
8825 return;
8826 }
8827
8828 LLVM_DEBUG(
8829 dbgs() << "[AAMemoryLocation] Accessed locations with pointer locations: "
8830 << getMemoryLocationsAsStr(State.getAssumed()) << "\n");
8831}
8832
8833void AAMemoryLocationImpl::categorizeArgumentPointerLocations(
8834 Attributor &A, CallBase &CB, AAMemoryLocation::StateType &AccessedLocs,
8835 bool &Changed) {
8836 for (unsigned ArgNo = 0, E = CB.arg_size(); ArgNo < E; ++ArgNo) {
8837
8838 // Skip non-pointer arguments.
8839 const Value *ArgOp = CB.getArgOperand(ArgNo);
8840 if (!ArgOp->getType()->isPtrOrPtrVectorTy())
8841 continue;
8842
8843 // Skip readnone arguments.
8844 const IRPosition &ArgOpIRP = IRPosition::callsite_argument(CB, ArgNo);
8845 const auto *ArgOpMemLocationAA =
8846 A.getAAFor<AAMemoryBehavior>(*this, ArgOpIRP, DepClassTy::OPTIONAL);
8847
8848 if (ArgOpMemLocationAA && ArgOpMemLocationAA->isAssumedReadNone())
8849 continue;
8850
8851 // Categorize potentially accessed pointer arguments as if there was an
8852 // access instruction with them as pointer.
8853 categorizePtrValue(A, CB, *ArgOp, AccessedLocs, Changed);
8854 }
8855}
8856
8858AAMemoryLocationImpl::categorizeAccessedLocations(Attributor &A, Instruction &I,
8859 bool &Changed) {
8860 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize accessed locations for "
8861 << I << "\n");
8862
8863 AAMemoryLocation::StateType AccessedLocs;
8864 AccessedLocs.intersectAssumedBits(NO_LOCATIONS);
8865
8866 if (auto *CB = dyn_cast<CallBase>(&I)) {
8867
8868 // First check if we assume any memory is access is visible.
8869 const auto *CBMemLocationAA = A.getAAFor<AAMemoryLocation>(
8871 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize call site: " << I
8872 << " [" << CBMemLocationAA << "]\n");
8873 if (!CBMemLocationAA) {
8874 updateStateAndAccessesMap(AccessedLocs, NO_UNKOWN_MEM, &I, nullptr,
8875 Changed, getAccessKindFromInst(&I));
8876 return NO_UNKOWN_MEM;
8877 }
8878
8879 if (CBMemLocationAA->isAssumedReadNone())
8880 return NO_LOCATIONS;
8881
8882 if (CBMemLocationAA->isAssumedInaccessibleMemOnly()) {
8883 updateStateAndAccessesMap(AccessedLocs, NO_INACCESSIBLE_MEM, &I, nullptr,
8884 Changed, getAccessKindFromInst(&I));
8885 return AccessedLocs.getAssumed();
8886 }
8887
8888 uint32_t CBAssumedNotAccessedLocs =
8889 CBMemLocationAA->getAssumedNotAccessedLocation();
8890
8891 // Set the argmemonly and global bit as we handle them separately below.
8892 uint32_t CBAssumedNotAccessedLocsNoArgMem =
8893 CBAssumedNotAccessedLocs | NO_ARGUMENT_MEM | NO_GLOBAL_MEM;
8894
8895 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS; CurMLK *= 2) {
8896 if (CBAssumedNotAccessedLocsNoArgMem & CurMLK)
8897 continue;
8898 updateStateAndAccessesMap(AccessedLocs, CurMLK, &I, nullptr, Changed,
8899 getAccessKindFromInst(&I));
8900 }
8901
8902 // Now handle global memory if it might be accessed. This is slightly tricky
8903 // as NO_GLOBAL_MEM has multiple bits set.
8904 bool HasGlobalAccesses = ((~CBAssumedNotAccessedLocs) & NO_GLOBAL_MEM);
8905 if (HasGlobalAccesses) {
8906 auto AccessPred = [&](const Instruction *, const Value *Ptr,
8907 AccessKind Kind, MemoryLocationsKind MLK) {
8908 updateStateAndAccessesMap(AccessedLocs, MLK, &I, Ptr, Changed,
8909 getAccessKindFromInst(&I));
8910 return true;
8911 };
8912 if (!CBMemLocationAA->checkForAllAccessesToMemoryKind(
8913 AccessPred, inverseLocation(NO_GLOBAL_MEM, false, false)))
8914 return AccessedLocs.getWorstState();
8915 }
8916
8917 LLVM_DEBUG(
8918 dbgs() << "[AAMemoryLocation] Accessed state before argument handling: "
8919 << getMemoryLocationsAsStr(AccessedLocs.getAssumed()) << "\n");
8920
8921 // Now handle argument memory if it might be accessed.
8922 bool HasArgAccesses = ((~CBAssumedNotAccessedLocs) & NO_ARGUMENT_MEM);
8923 if (HasArgAccesses)
8924 categorizeArgumentPointerLocations(A, *CB, AccessedLocs, Changed);
8925
8926 LLVM_DEBUG(
8927 dbgs() << "[AAMemoryLocation] Accessed state after argument handling: "
8928 << getMemoryLocationsAsStr(AccessedLocs.getAssumed()) << "\n");
8929
8930 return AccessedLocs.getAssumed();
8931 }
8932
8933 if (const Value *Ptr = getPointerOperand(&I, /* AllowVolatile */ true)) {
8934 LLVM_DEBUG(
8935 dbgs() << "[AAMemoryLocation] Categorize memory access with pointer: "
8936 << I << " [" << *Ptr << "]\n");
8937 categorizePtrValue(A, I, *Ptr, AccessedLocs, Changed,
8938 Ptr->getType()->getPointerAddressSpace());
8939 return AccessedLocs.getAssumed();
8940 }
8941
8942 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Failed to categorize instruction: "
8943 << I << "\n");
8944 updateStateAndAccessesMap(AccessedLocs, NO_UNKOWN_MEM, &I, nullptr, Changed,
8945 getAccessKindFromInst(&I));
8946 return AccessedLocs.getAssumed();
8947}
8948
8949/// An AA to represent the memory behavior function attributes.
8950struct AAMemoryLocationFunction final : public AAMemoryLocationImpl {
8951 AAMemoryLocationFunction(const IRPosition &IRP, Attributor &A)
8952 : AAMemoryLocationImpl(IRP, A) {}
8953
8954 /// See AbstractAttribute::updateImpl(Attributor &A).
8955 ChangeStatus updateImpl(Attributor &A) override {
8956
8957 const auto *MemBehaviorAA =
8958 A.getAAFor<AAMemoryBehavior>(*this, getIRPosition(), DepClassTy::NONE);
8959 if (MemBehaviorAA && MemBehaviorAA->isAssumedReadNone()) {
8960 if (MemBehaviorAA->isKnownReadNone())
8961 return indicateOptimisticFixpoint();
8963 "AAMemoryLocation was not read-none but AAMemoryBehavior was!");
8964 A.recordDependence(*MemBehaviorAA, *this, DepClassTy::OPTIONAL);
8965 return ChangeStatus::UNCHANGED;
8966 }
8967
8968 // The current assumed state used to determine a change.
8969 auto AssumedState = getAssumed();
8970 bool Changed = false;
8971
8972 auto CheckRWInst = [&](Instruction &I) {
8973 MemoryLocationsKind MLK = categorizeAccessedLocations(A, I, Changed);
8974 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Accessed locations for " << I
8975 << ": " << getMemoryLocationsAsStr(MLK) << "\n");
8976 removeAssumedBits(inverseLocation(MLK, false, false));
8977 // Stop once only the valid bit set in the *not assumed location*, thus
8978 // once we don't actually exclude any memory locations in the state.
8979 return getAssumedNotAccessedLocation() != VALID_STATE;
8980 };
8981
8982 bool UsedAssumedInformation = false;
8983 if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this,
8984 UsedAssumedInformation))
8985 return indicatePessimisticFixpoint();
8986
8987 Changed |= AssumedState != getAssumed();
8988 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
8989 }
8990
8991 /// See AbstractAttribute::trackStatistics()
8992 void trackStatistics() const override {
8993 if (isAssumedReadNone())
8994 STATS_DECLTRACK_FN_ATTR(readnone)
8995 else if (isAssumedArgMemOnly())
8996 STATS_DECLTRACK_FN_ATTR(argmemonly)
8997 else if (isAssumedInaccessibleMemOnly())
8998 STATS_DECLTRACK_FN_ATTR(inaccessiblememonly)
8999 else if (isAssumedInaccessibleOrArgMemOnly())
9000 STATS_DECLTRACK_FN_ATTR(inaccessiblememorargmemonly)
9001 }
9002};
9003
9004/// AAMemoryLocation attribute for call sites.
9005struct AAMemoryLocationCallSite final : AAMemoryLocationImpl {
9006 AAMemoryLocationCallSite(const IRPosition &IRP, Attributor &A)
9007 : AAMemoryLocationImpl(IRP, A) {}
9008
9009 /// See AbstractAttribute::updateImpl(...).
9010 ChangeStatus updateImpl(Attributor &A) override {
9011 // TODO: Once we have call site specific value information we can provide
9012 // call site specific liveness liveness information and then it makes
9013 // sense to specialize attributes for call sites arguments instead of
9014 // redirecting requests to the callee argument.
9015 Function *F = getAssociatedFunction();
9016 const IRPosition &FnPos = IRPosition::function(*F);
9017 auto *FnAA =
9018 A.getAAFor<AAMemoryLocation>(*this, FnPos, DepClassTy::REQUIRED);
9019 if (!FnAA)
9020 return indicatePessimisticFixpoint();
9021 bool Changed = false;
9022 auto AccessPred = [&](const Instruction *I, const Value *Ptr,
9023 AccessKind Kind, MemoryLocationsKind MLK) {
9024 updateStateAndAccessesMap(getState(), MLK, I, Ptr, Changed,
9025 getAccessKindFromInst(I));
9026 return true;
9027 };
9028 if (!FnAA->checkForAllAccessesToMemoryKind(AccessPred, ALL_LOCATIONS))
9029 return indicatePessimisticFixpoint();
9030 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
9031 }
9032
9033 /// See AbstractAttribute::trackStatistics()
9034 void trackStatistics() const override {
9035 if (isAssumedReadNone())
9036 STATS_DECLTRACK_CS_ATTR(readnone)
9037 }
9038};
9039} // namespace
9040
9041/// ------------------ denormal-fp-math Attribute -------------------------
9042
9043namespace {
9044struct AADenormalFPMathImpl : public AADenormalFPMath {
9045 AADenormalFPMathImpl(const IRPosition &IRP, Attributor &A)
9046 : AADenormalFPMath(IRP, A) {}
9047
9048 const std::string getAsStr(Attributor *A) const override {
9049 std::string Str("AADenormalFPMath[");
9050 raw_string_ostream OS(Str);
9051
9052 DenormalState Known = getKnown();
9053 if (Known.Mode.isValid())
9054 OS << "denormal-fp-math=" << Known.Mode;
9055 else
9056 OS << "invalid";
9057
9058 if (Known.ModeF32.isValid())
9059 OS << " denormal-fp-math-f32=" << Known.ModeF32;
9060 OS << ']';
9061 return Str;
9062 }
9063};
9064
9065struct AADenormalFPMathFunction final : AADenormalFPMathImpl {
9066 AADenormalFPMathFunction(const IRPosition &IRP, Attributor &A)
9067 : AADenormalFPMathImpl(IRP, A) {}
9068
9069 void initialize(Attributor &A) override {
9070 const Function *F = getAnchorScope();
9071 DenormalFPEnv DenormEnv = F->getDenormalFPEnv();
9072
9073 Known = DenormalState{DenormEnv.DefaultMode, DenormEnv.F32Mode};
9074 if (isModeFixed())
9075 indicateFixpoint();
9076 }
9077
9078 ChangeStatus updateImpl(Attributor &A) override {
9079 ChangeStatus Change = ChangeStatus::UNCHANGED;
9080
9081 auto CheckCallSite = [=, &Change, &A](AbstractCallSite CS) {
9082 Function *Caller = CS.getInstruction()->getFunction();
9083 LLVM_DEBUG(dbgs() << "[AADenormalFPMath] Call " << Caller->getName()
9084 << "->" << getAssociatedFunction()->getName() << '\n');
9085
9086 const auto *CallerInfo = A.getAAFor<AADenormalFPMath>(
9087 *this, IRPosition::function(*Caller), DepClassTy::REQUIRED);
9088 if (!CallerInfo)
9089 return false;
9090
9091 Change = Change | clampStateAndIndicateChange(this->getState(),
9092 CallerInfo->getState());
9093 return true;
9094 };
9095
9096 bool AllCallSitesKnown = true;
9097 if (!A.checkForAllCallSites(CheckCallSite, *this, true, AllCallSitesKnown))
9098 return indicatePessimisticFixpoint();
9099
9100 if (Change == ChangeStatus::CHANGED && isModeFixed())
9101 indicateFixpoint();
9102 return Change;
9103 }
9104
9105 ChangeStatus manifest(Attributor &A) override {
9106 LLVMContext &Ctx = getAssociatedFunction()->getContext();
9107
9108 SmallVector<Attribute, 2> AttrToAdd;
9110
9111 // TODO: Change to use DenormalFPEnv everywhere.
9112 DenormalFPEnv KnownEnv(Known.Mode, Known.ModeF32);
9113
9114 if (KnownEnv == DenormalFPEnv::getDefault()) {
9115 AttrToRemove.push_back(Attribute::DenormalFPEnv);
9116 } else {
9117 AttrToAdd.push_back(Attribute::get(
9118 Ctx, Attribute::DenormalFPEnv,
9119 DenormalFPEnv(Known.Mode, Known.ModeF32).toIntValue()));
9120 }
9121
9122 auto &IRP = getIRPosition();
9123
9124 // TODO: There should be a combined add and remove API.
9125 return A.removeAttrs(IRP, AttrToRemove) |
9126 A.manifestAttrs(IRP, AttrToAdd, /*ForceReplace=*/true);
9127 }
9128
9129 void trackStatistics() const override {
9130 STATS_DECLTRACK_FN_ATTR(denormal_fpenv)
9131 }
9132};
9133} // namespace
9134
9135/// ------------------ Value Constant Range Attribute -------------------------
9136
9137namespace {
9138struct AAValueConstantRangeImpl : AAValueConstantRange {
9139 using StateType = IntegerRangeState;
9140 AAValueConstantRangeImpl(const IRPosition &IRP, Attributor &A)
9141 : AAValueConstantRange(IRP, A) {}
9142
9143 /// See AbstractAttribute::initialize(..).
9144 void initialize(Attributor &A) override {
9145 if (A.hasSimplificationCallback(getIRPosition())) {
9146 indicatePessimisticFixpoint();
9147 return;
9148 }
9149
9150 // Intersect a range given by SCEV.
9151 intersectKnown(getConstantRangeFromSCEV(A, getCtxI()));
9152
9153 // Intersect a range given by LVI.
9154 intersectKnown(getConstantRangeFromLVI(A, getCtxI()));
9155 }
9156
9157 /// See AbstractAttribute::getAsStr().
9158 const std::string getAsStr(Attributor *A) const override {
9159 std::string Str;
9160 llvm::raw_string_ostream OS(Str);
9161 OS << "range(" << getBitWidth() << ")<";
9162 getKnown().print(OS);
9163 OS << " / ";
9164 getAssumed().print(OS);
9165 OS << ">";
9166 return Str;
9167 }
9168
9169 /// Helper function to get a SCEV expr for the associated value at program
9170 /// point \p I.
9171 const SCEV *getSCEV(Attributor &A, const Instruction *I = nullptr) const {
9172 if (!getAnchorScope())
9173 return nullptr;
9174
9175 ScalarEvolution *SE =
9176 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(
9177 *getAnchorScope());
9178
9179 LoopInfo *LI = A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(
9180 *getAnchorScope());
9181
9182 if (!SE || !LI)
9183 return nullptr;
9184
9185 const SCEV *S = SE->getSCEV(&getAssociatedValue());
9186 if (!I)
9187 return S;
9188
9189 return SE->getSCEVAtScope(S, LI->getLoopFor(I->getParent()));
9190 }
9191
9192 /// Helper function to get a range from SCEV for the associated value at
9193 /// program point \p I.
9194 ConstantRange getConstantRangeFromSCEV(Attributor &A,
9195 const Instruction *I = nullptr) const {
9196 if (!getAnchorScope())
9197 return getWorstState(getBitWidth());
9198
9199 ScalarEvolution *SE =
9200 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(
9201 *getAnchorScope());
9202
9203 const SCEV *S = getSCEV(A, I);
9204 if (!SE || !S)
9205 return getWorstState(getBitWidth());
9206
9207 return SE->getUnsignedRange(S);
9208 }
9209
9210 /// Helper function to get a range from LVI for the associated value at
9211 /// program point \p I.
9212 ConstantRange
9213 getConstantRangeFromLVI(Attributor &A,
9214 const Instruction *CtxI = nullptr) const {
9215 if (!getAnchorScope())
9216 return getWorstState(getBitWidth());
9217
9218 LazyValueInfo *LVI =
9219 A.getInfoCache().getAnalysisResultForFunction<LazyValueAnalysis>(
9220 *getAnchorScope());
9221
9222 if (!LVI || !CtxI)
9223 return getWorstState(getBitWidth());
9224 return LVI->getConstantRange(&getAssociatedValue(),
9225 const_cast<Instruction *>(CtxI),
9226 /*UndefAllowed*/ false);
9227 }
9228
9229 /// Return true if \p CtxI is valid for querying outside analyses.
9230 /// This basically makes sure we do not ask intra-procedural analysis
9231 /// about a context in the wrong function or a context that violates
9232 /// dominance assumptions they might have. The \p AllowAACtxI flag indicates
9233 /// if the original context of this AA is OK or should be considered invalid.
9234 bool isValidCtxInstructionForOutsideAnalysis(Attributor &A,
9235 const Instruction *CtxI,
9236 bool AllowAACtxI) const {
9237 if (!CtxI || (!AllowAACtxI && CtxI == getCtxI()))
9238 return false;
9239
9240 // Our context might be in a different function, neither intra-procedural
9241 // analysis (ScalarEvolution nor LazyValueInfo) can handle that.
9242 if (!AA::isValidInScope(getAssociatedValue(), CtxI->getFunction()))
9243 return false;
9244
9245 // If the context is not dominated by the value there are paths to the
9246 // context that do not define the value. This cannot be handled by
9247 // LazyValueInfo so we need to bail.
9248 if (auto *I = dyn_cast<Instruction>(&getAssociatedValue())) {
9249 InformationCache &InfoCache = A.getInfoCache();
9250 const DominatorTree *DT =
9251 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(
9252 *I->getFunction());
9253 return DT && DT->dominates(I, CtxI);
9254 }
9255
9256 return true;
9257 }
9258
9259 /// See AAValueConstantRange::getKnownConstantRange(..).
9260 ConstantRange
9261 getKnownConstantRange(Attributor &A,
9262 const Instruction *CtxI = nullptr) const override {
9263 if (!isValidCtxInstructionForOutsideAnalysis(A, CtxI,
9264 /* AllowAACtxI */ false))
9265 return getKnown();
9266
9267 ConstantRange LVIR = getConstantRangeFromLVI(A, CtxI);
9268 ConstantRange SCEVR = getConstantRangeFromSCEV(A, CtxI);
9269 return getKnown().intersectWith(SCEVR).intersectWith(LVIR);
9270 }
9271
9272 /// See AAValueConstantRange::getAssumedConstantRange(..).
9273 ConstantRange
9274 getAssumedConstantRange(Attributor &A,
9275 const Instruction *CtxI = nullptr) const override {
9276 // TODO: Make SCEV use Attributor assumption.
9277 // We may be able to bound a variable range via assumptions in
9278 // Attributor. ex.) If x is assumed to be in [1, 3] and y is known to
9279 // evolve to x^2 + x, then we can say that y is in [2, 12].
9280 if (!isValidCtxInstructionForOutsideAnalysis(A, CtxI,
9281 /* AllowAACtxI */ false))
9282 return getAssumed();
9283
9284 ConstantRange LVIR = getConstantRangeFromLVI(A, CtxI);
9285 ConstantRange SCEVR = getConstantRangeFromSCEV(A, CtxI);
9286 return getAssumed().intersectWith(SCEVR).intersectWith(LVIR);
9287 }
9288
9289 /// Helper function to create MDNode for range metadata.
9290 static MDNode *
9291 getMDNodeForConstantRange(Type *Ty, LLVMContext &Ctx,
9292 const ConstantRange &AssumedConstantRange) {
9293 Metadata *LowAndHigh[] = {ConstantAsMetadata::get(ConstantInt::get(
9294 Ty, AssumedConstantRange.getLower())),
9295 ConstantAsMetadata::get(ConstantInt::get(
9296 Ty, AssumedConstantRange.getUpper()))};
9297 return MDNode::get(Ctx, LowAndHigh);
9298 }
9299
9300 /// Return true if \p Assumed is included in ranges from instruction \p I.
9301 static bool isBetterRange(const ConstantRange &Assumed,
9302 const Instruction &I) {
9303 if (Assumed.isFullSet())
9304 return false;
9305
9306 std::optional<ConstantRange> Known;
9307
9308 if (const auto *CB = dyn_cast<CallBase>(&I)) {
9309 Known = CB->getRange();
9310 } else if (MDNode *KnownRanges = I.getMetadata(LLVMContext::MD_range)) {
9311 // If multiple ranges are annotated in IR, we give up to annotate assumed
9312 // range for now.
9313
9314 // TODO: If there exists a known range which containts assumed range, we
9315 // can say assumed range is better.
9316 if (KnownRanges->getNumOperands() > 2)
9317 return false;
9318
9319 ConstantInt *Lower =
9320 mdconst::extract<ConstantInt>(KnownRanges->getOperand(0));
9321 ConstantInt *Upper =
9322 mdconst::extract<ConstantInt>(KnownRanges->getOperand(1));
9323
9324 Known.emplace(Lower->getValue(), Upper->getValue());
9325 }
9326 return !Known || (*Known != Assumed && Known->contains(Assumed));
9327 }
9328
9329 /// Helper function to set range metadata.
9330 static bool
9331 setRangeMetadataIfisBetterRange(Instruction *I,
9332 const ConstantRange &AssumedConstantRange) {
9333 if (isBetterRange(AssumedConstantRange, *I)) {
9334 I->setMetadata(LLVMContext::MD_range,
9335 getMDNodeForConstantRange(I->getType(), I->getContext(),
9336 AssumedConstantRange));
9337 return true;
9338 }
9339 return false;
9340 }
9341 /// Helper function to set range return attribute.
9342 static bool
9343 setRangeRetAttrIfisBetterRange(Attributor &A, const IRPosition &IRP,
9344 Instruction *I,
9345 const ConstantRange &AssumedConstantRange) {
9346 if (isBetterRange(AssumedConstantRange, *I)) {
9347 A.manifestAttrs(IRP,
9348 Attribute::get(I->getContext(), Attribute::Range,
9349 AssumedConstantRange),
9350 /*ForceReplace*/ true);
9351 return true;
9352 }
9353 return false;
9354 }
9355
9356 /// See AbstractAttribute::manifest()
9357 ChangeStatus manifest(Attributor &A) override {
9358 ChangeStatus Changed = ChangeStatus::UNCHANGED;
9359 ConstantRange AssumedConstantRange = getAssumedConstantRange(A);
9360 assert(!AssumedConstantRange.isFullSet() && "Invalid state");
9361
9362 auto &V = getAssociatedValue();
9363 if (!AssumedConstantRange.isEmptySet() &&
9364 !AssumedConstantRange.isSingleElement()) {
9365 if (Instruction *I = dyn_cast<Instruction>(&V)) {
9366 assert(I == getCtxI() && "Should not annotate an instruction which is "
9367 "not the context instruction");
9368 if (isa<LoadInst>(I))
9369 if (setRangeMetadataIfisBetterRange(I, AssumedConstantRange))
9370 Changed = ChangeStatus::CHANGED;
9371 if (isa<CallInst>(I))
9372 if (setRangeRetAttrIfisBetterRange(A, getIRPosition(), I,
9373 AssumedConstantRange))
9374 Changed = ChangeStatus::CHANGED;
9375 }
9376 }
9377
9378 return Changed;
9379 }
9380};
9381
9382struct AAValueConstantRangeArgument final
9383 : AAArgumentFromCallSiteArguments<
9384 AAValueConstantRange, AAValueConstantRangeImpl, IntegerRangeState,
9385 true /* BridgeCallBaseContext */> {
9386 using Base = AAArgumentFromCallSiteArguments<
9387 AAValueConstantRange, AAValueConstantRangeImpl, IntegerRangeState,
9388 true /* BridgeCallBaseContext */>;
9389 AAValueConstantRangeArgument(const IRPosition &IRP, Attributor &A)
9390 : Base(IRP, A) {}
9391
9392 /// See AbstractAttribute::trackStatistics()
9393 void trackStatistics() const override {
9394 STATS_DECLTRACK_ARG_ATTR(value_range)
9395 }
9396};
9397
9398struct AAValueConstantRangeReturned
9399 : AAReturnedFromReturnedValues<AAValueConstantRange,
9400 AAValueConstantRangeImpl,
9401 AAValueConstantRangeImpl::StateType,
9402 /* PropagateCallBaseContext */ true> {
9403 using Base =
9404 AAReturnedFromReturnedValues<AAValueConstantRange,
9405 AAValueConstantRangeImpl,
9406 AAValueConstantRangeImpl::StateType,
9407 /* PropagateCallBaseContext */ true>;
9408 AAValueConstantRangeReturned(const IRPosition &IRP, Attributor &A)
9409 : Base(IRP, A) {}
9410
9411 /// See AbstractAttribute::initialize(...).
9412 void initialize(Attributor &A) override {
9413 if (!A.isFunctionIPOAmendable(*getAssociatedFunction()))
9414 indicatePessimisticFixpoint();
9415 }
9416
9417 /// See AbstractAttribute::trackStatistics()
9418 void trackStatistics() const override {
9419 STATS_DECLTRACK_FNRET_ATTR(value_range)
9420 }
9421};
9422
9423struct AAValueConstantRangeFloating : AAValueConstantRangeImpl {
9424 AAValueConstantRangeFloating(const IRPosition &IRP, Attributor &A)
9425 : AAValueConstantRangeImpl(IRP, A) {}
9426
9427 /// See AbstractAttribute::initialize(...).
9428 void initialize(Attributor &A) override {
9429 AAValueConstantRangeImpl::initialize(A);
9430 if (isAtFixpoint())
9431 return;
9432
9433 Value &V = getAssociatedValue();
9434
9435 if (auto *C = dyn_cast<ConstantInt>(&V)) {
9436 unionAssumed(ConstantRange(C->getValue()));
9437 indicateOptimisticFixpoint();
9438 return;
9439 }
9440
9441 if (isa<UndefValue>(&V)) {
9442 // Collapse the undef state to 0.
9443 unionAssumed(ConstantRange(APInt(getBitWidth(), 0)));
9444 indicateOptimisticFixpoint();
9445 return;
9446 }
9447
9448 if (isa<CallBase>(&V))
9449 return;
9450
9451 if (isa<BinaryOperator>(&V) || isa<CmpInst>(&V) || isa<CastInst>(&V))
9452 return;
9453
9454 // If it is a load instruction with range metadata, use it.
9455 if (LoadInst *LI = dyn_cast<LoadInst>(&V))
9456 if (auto *RangeMD = LI->getMetadata(LLVMContext::MD_range)) {
9457 intersectKnown(getConstantRangeFromMetadata(*RangeMD));
9458 return;
9459 }
9460
9461 // We can work with PHI and select instruction as we traverse their operands
9462 // during update.
9463 if (isa<SelectInst>(V) || isa<PHINode>(V))
9464 return;
9465
9466 // Otherwise we give up.
9467 indicatePessimisticFixpoint();
9468
9469 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] We give up: "
9470 << getAssociatedValue() << "\n");
9471 }
9472
9473 bool calculateBinaryOperator(
9474 Attributor &A, BinaryOperator *BinOp, IntegerRangeState &T,
9475 const Instruction *CtxI,
9476 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) {
9477 Value *LHS = BinOp->getOperand(0);
9478 Value *RHS = BinOp->getOperand(1);
9479
9480 // Simplify the operands first.
9481 bool UsedAssumedInformation = false;
9482 const auto &SimplifiedLHS = A.getAssumedSimplified(
9483 IRPosition::value(*LHS, getCallBaseContext()), *this,
9484 UsedAssumedInformation, AA::Interprocedural);
9485 if (!SimplifiedLHS.has_value())
9486 return true;
9487 if (!*SimplifiedLHS)
9488 return false;
9489 LHS = *SimplifiedLHS;
9490
9491 const auto &SimplifiedRHS = A.getAssumedSimplified(
9492 IRPosition::value(*RHS, getCallBaseContext()), *this,
9493 UsedAssumedInformation, AA::Interprocedural);
9494 if (!SimplifiedRHS.has_value())
9495 return true;
9496 if (!*SimplifiedRHS)
9497 return false;
9498 RHS = *SimplifiedRHS;
9499
9500 // TODO: Allow non integers as well.
9501 if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy())
9502 return false;
9503
9504 auto *LHSAA = A.getAAFor<AAValueConstantRange>(
9505 *this, IRPosition::value(*LHS, getCallBaseContext()),
9506 DepClassTy::REQUIRED);
9507 if (!LHSAA)
9508 return false;
9509 QuerriedAAs.push_back(LHSAA);
9510 auto LHSAARange = LHSAA->getAssumedConstantRange(A, CtxI);
9511
9512 auto *RHSAA = A.getAAFor<AAValueConstantRange>(
9513 *this, IRPosition::value(*RHS, getCallBaseContext()),
9514 DepClassTy::REQUIRED);
9515 if (!RHSAA)
9516 return false;
9517 QuerriedAAs.push_back(RHSAA);
9518 auto RHSAARange = RHSAA->getAssumedConstantRange(A, CtxI);
9519
9520 auto AssumedRange = LHSAARange.binaryOp(BinOp->getOpcode(), RHSAARange);
9521
9522 T.unionAssumed(AssumedRange);
9523
9524 // TODO: Track a known state too.
9525
9526 return T.isValidState();
9527 }
9528
9529 bool calculateCastInst(
9530 Attributor &A, CastInst *CastI, IntegerRangeState &T,
9531 const Instruction *CtxI,
9532 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) {
9533 assert(CastI->getNumOperands() == 1 && "Expected cast to be unary!");
9534 // TODO: Allow non integers as well.
9535 Value *OpV = CastI->getOperand(0);
9536
9537 // Simplify the operand first.
9538 bool UsedAssumedInformation = false;
9539 const auto &SimplifiedOpV = A.getAssumedSimplified(
9540 IRPosition::value(*OpV, getCallBaseContext()), *this,
9541 UsedAssumedInformation, AA::Interprocedural);
9542 if (!SimplifiedOpV.has_value())
9543 return true;
9544 if (!*SimplifiedOpV)
9545 return false;
9546 OpV = *SimplifiedOpV;
9547
9548 if (!OpV->getType()->isIntegerTy())
9549 return false;
9550
9551 auto *OpAA = A.getAAFor<AAValueConstantRange>(
9552 *this, IRPosition::value(*OpV, getCallBaseContext()),
9553 DepClassTy::REQUIRED);
9554 if (!OpAA)
9555 return false;
9556 QuerriedAAs.push_back(OpAA);
9557 T.unionAssumed(OpAA->getAssumed().castOp(CastI->getOpcode(),
9558 getState().getBitWidth()));
9559 return T.isValidState();
9560 }
9561
9562 bool
9563 calculateCmpInst(Attributor &A, CmpInst *CmpI, IntegerRangeState &T,
9564 const Instruction *CtxI,
9565 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) {
9566 Value *LHS = CmpI->getOperand(0);
9567 Value *RHS = CmpI->getOperand(1);
9568
9569 // Simplify the operands first.
9570 bool UsedAssumedInformation = false;
9571 const auto &SimplifiedLHS = A.getAssumedSimplified(
9572 IRPosition::value(*LHS, getCallBaseContext()), *this,
9573 UsedAssumedInformation, AA::Interprocedural);
9574 if (!SimplifiedLHS.has_value())
9575 return true;
9576 if (!*SimplifiedLHS)
9577 return false;
9578 LHS = *SimplifiedLHS;
9579
9580 const auto &SimplifiedRHS = A.getAssumedSimplified(
9581 IRPosition::value(*RHS, getCallBaseContext()), *this,
9582 UsedAssumedInformation, AA::Interprocedural);
9583 if (!SimplifiedRHS.has_value())
9584 return true;
9585 if (!*SimplifiedRHS)
9586 return false;
9587 RHS = *SimplifiedRHS;
9588
9589 // TODO: Allow non integers as well.
9590 if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy())
9591 return false;
9592
9593 auto *LHSAA = A.getAAFor<AAValueConstantRange>(
9594 *this, IRPosition::value(*LHS, getCallBaseContext()),
9595 DepClassTy::REQUIRED);
9596 if (!LHSAA)
9597 return false;
9598 QuerriedAAs.push_back(LHSAA);
9599 auto *RHSAA = A.getAAFor<AAValueConstantRange>(
9600 *this, IRPosition::value(*RHS, getCallBaseContext()),
9601 DepClassTy::REQUIRED);
9602 if (!RHSAA)
9603 return false;
9604 QuerriedAAs.push_back(RHSAA);
9605 auto LHSAARange = LHSAA->getAssumedConstantRange(A, CtxI);
9606 auto RHSAARange = RHSAA->getAssumedConstantRange(A, CtxI);
9607
9608 // If one of them is empty set, we can't decide.
9609 if (LHSAARange.isEmptySet() || RHSAARange.isEmptySet())
9610 return true;
9611
9612 bool MustTrue = false, MustFalse = false;
9613
9614 auto AllowedRegion =
9616
9617 if (AllowedRegion.intersectWith(LHSAARange).isEmptySet())
9618 MustFalse = true;
9619
9620 if (LHSAARange.icmp(CmpI->getPredicate(), RHSAARange))
9621 MustTrue = true;
9622
9623 assert((!MustTrue || !MustFalse) &&
9624 "Either MustTrue or MustFalse should be false!");
9625
9626 if (MustTrue)
9627 T.unionAssumed(ConstantRange(APInt(/* numBits */ 1, /* val */ 1)));
9628 else if (MustFalse)
9629 T.unionAssumed(ConstantRange(APInt(/* numBits */ 1, /* val */ 0)));
9630 else
9631 T.unionAssumed(ConstantRange(/* BitWidth */ 1, /* isFullSet */ true));
9632
9633 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] " << *CmpI << " after "
9634 << (MustTrue ? "true" : (MustFalse ? "false" : "unknown"))
9635 << ": " << T << "\n\t" << *LHSAA << "\t<op>\n\t"
9636 << *RHSAA);
9637
9638 // TODO: Track a known state too.
9639 return T.isValidState();
9640 }
9641
9642 /// See AbstractAttribute::updateImpl(...).
9643 ChangeStatus updateImpl(Attributor &A) override {
9644
9645 IntegerRangeState T(getBitWidth());
9646 auto VisitValueCB = [&](Value &V, const Instruction *CtxI) -> bool {
9648 if (!I || isa<CallBase>(I)) {
9649
9650 // Simplify the operand first.
9651 bool UsedAssumedInformation = false;
9652 const auto &SimplifiedOpV = A.getAssumedSimplified(
9653 IRPosition::value(V, getCallBaseContext()), *this,
9654 UsedAssumedInformation, AA::Interprocedural);
9655 if (!SimplifiedOpV.has_value())
9656 return true;
9657 if (!*SimplifiedOpV)
9658 return false;
9659 Value *VPtr = *SimplifiedOpV;
9660
9661 // If the value is not instruction, we query AA to Attributor.
9662 const auto *AA = A.getAAFor<AAValueConstantRange>(
9663 *this, IRPosition::value(*VPtr, getCallBaseContext()),
9664 DepClassTy::REQUIRED);
9665
9666 // Clamp operator is not used to utilize a program point CtxI.
9667 if (AA)
9668 T.unionAssumed(AA->getAssumedConstantRange(A, CtxI));
9669 else
9670 return false;
9671
9672 return T.isValidState();
9673 }
9674
9676 if (auto *BinOp = dyn_cast<BinaryOperator>(I)) {
9677 if (!calculateBinaryOperator(A, BinOp, T, CtxI, QuerriedAAs))
9678 return false;
9679 } else if (auto *CmpI = dyn_cast<CmpInst>(I)) {
9680 if (!calculateCmpInst(A, CmpI, T, CtxI, QuerriedAAs))
9681 return false;
9682 } else if (auto *CastI = dyn_cast<CastInst>(I)) {
9683 if (!calculateCastInst(A, CastI, T, CtxI, QuerriedAAs))
9684 return false;
9685 } else {
9686 // Give up with other instructions.
9687 // TODO: Add other instructions
9688
9689 T.indicatePessimisticFixpoint();
9690 return false;
9691 }
9692
9693 // Catch circular reasoning in a pessimistic way for now.
9694 // TODO: Check how the range evolves and if we stripped anything, see also
9695 // AADereferenceable or AAAlign for similar situations.
9696 for (const AAValueConstantRange *QueriedAA : QuerriedAAs) {
9697 if (QueriedAA != this)
9698 continue;
9699 // If we are in a stady state we do not need to worry.
9700 if (T.getAssumed() == getState().getAssumed())
9701 continue;
9702 T.indicatePessimisticFixpoint();
9703 }
9704
9705 return T.isValidState();
9706 };
9707
9708 if (!VisitValueCB(getAssociatedValue(), getCtxI()))
9709 return indicatePessimisticFixpoint();
9710
9711 // Ensure that long def-use chains can't cause circular reasoning either by
9712 // introducing a cutoff below.
9713 if (clampStateAndIndicateChange(getState(), T) == ChangeStatus::UNCHANGED)
9714 return ChangeStatus::UNCHANGED;
9715 if (++NumChanges > MaxNumChanges) {
9716 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] performed " << NumChanges
9717 << " but only " << MaxNumChanges
9718 << " are allowed to avoid cyclic reasoning.");
9719 return indicatePessimisticFixpoint();
9720 }
9721 return ChangeStatus::CHANGED;
9722 }
9723
9724 /// See AbstractAttribute::trackStatistics()
9725 void trackStatistics() const override {
9727 }
9728
9729 /// Tracker to bail after too many widening steps of the constant range.
9730 int NumChanges = 0;
9731
9732 /// Upper bound for the number of allowed changes (=widening steps) for the
9733 /// constant range before we give up.
9734 static constexpr int MaxNumChanges = 5;
9735};
9736
9737struct AAValueConstantRangeFunction : AAValueConstantRangeImpl {
9738 AAValueConstantRangeFunction(const IRPosition &IRP, Attributor &A)
9739 : AAValueConstantRangeImpl(IRP, A) {}
9740
9741 /// See AbstractAttribute::initialize(...).
9742 ChangeStatus updateImpl(Attributor &A) override {
9743 llvm_unreachable("AAValueConstantRange(Function|CallSite)::updateImpl will "
9744 "not be called");
9745 }
9746
9747 /// See AbstractAttribute::trackStatistics()
9748 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(value_range) }
9749};
9750
9751struct AAValueConstantRangeCallSite : AAValueConstantRangeFunction {
9752 AAValueConstantRangeCallSite(const IRPosition &IRP, Attributor &A)
9753 : AAValueConstantRangeFunction(IRP, A) {}
9754
9755 /// See AbstractAttribute::trackStatistics()
9756 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(value_range) }
9757};
9758
9759struct AAValueConstantRangeCallSiteReturned
9760 : AACalleeToCallSite<AAValueConstantRange, AAValueConstantRangeImpl,
9761 AAValueConstantRangeImpl::StateType,
9762 /* IntroduceCallBaseContext */ true> {
9763 AAValueConstantRangeCallSiteReturned(const IRPosition &IRP, Attributor &A)
9764 : AACalleeToCallSite<AAValueConstantRange, AAValueConstantRangeImpl,
9765 AAValueConstantRangeImpl::StateType,
9766 /* IntroduceCallBaseContext */ true>(IRP, A) {}
9767
9768 /// See AbstractAttribute::initialize(...).
9769 void initialize(Attributor &A) override {
9770 // If it is a call instruction with range attribute, use the range.
9771 if (CallInst *CI = dyn_cast<CallInst>(&getAssociatedValue())) {
9772 if (std::optional<ConstantRange> Range = CI->getRange())
9773 intersectKnown(*Range);
9774 }
9775
9776 AAValueConstantRangeImpl::initialize(A);
9777 }
9778
9779 /// See AbstractAttribute::trackStatistics()
9780 void trackStatistics() const override {
9781 STATS_DECLTRACK_CSRET_ATTR(value_range)
9782 }
9783};
9784struct AAValueConstantRangeCallSiteArgument : AAValueConstantRangeFloating {
9785 AAValueConstantRangeCallSiteArgument(const IRPosition &IRP, Attributor &A)
9786 : AAValueConstantRangeFloating(IRP, A) {}
9787
9788 /// See AbstractAttribute::manifest()
9789 ChangeStatus manifest(Attributor &A) override {
9790 return ChangeStatus::UNCHANGED;
9791 }
9792
9793 /// See AbstractAttribute::trackStatistics()
9794 void trackStatistics() const override {
9795 STATS_DECLTRACK_CSARG_ATTR(value_range)
9796 }
9797};
9798} // namespace
9799
9800/// ------------------ Potential Values Attribute -------------------------
9801
9802namespace {
9803struct AAPotentialConstantValuesImpl : AAPotentialConstantValues {
9804 using StateType = PotentialConstantIntValuesState;
9805
9806 AAPotentialConstantValuesImpl(const IRPosition &IRP, Attributor &A)
9807 : AAPotentialConstantValues(IRP, A) {}
9808
9809 /// See AbstractAttribute::initialize(..).
9810 void initialize(Attributor &A) override {
9811 if (A.hasSimplificationCallback(getIRPosition()))
9812 indicatePessimisticFixpoint();
9813 else
9814 AAPotentialConstantValues::initialize(A);
9815 }
9816
9817 bool fillSetWithConstantValues(Attributor &A, const IRPosition &IRP, SetTy &S,
9818 bool &ContainsUndef, bool ForSelf) {
9820 bool UsedAssumedInformation = false;
9821 if (!A.getAssumedSimplifiedValues(IRP, *this, Values, AA::Interprocedural,
9822 UsedAssumedInformation)) {
9823 // Avoid recursion when the caller is computing constant values for this
9824 // IRP itself.
9825 if (ForSelf)
9826 return false;
9827 if (!IRP.getAssociatedType()->isIntegerTy())
9828 return false;
9829 auto *PotentialValuesAA = A.getAAFor<AAPotentialConstantValues>(
9830 *this, IRP, DepClassTy::REQUIRED);
9831 if (!PotentialValuesAA || !PotentialValuesAA->getState().isValidState())
9832 return false;
9833 ContainsUndef = PotentialValuesAA->getState().undefIsContained();
9834 S = PotentialValuesAA->getState().getAssumedSet();
9835 return true;
9836 }
9837
9838 // Copy all the constant values, except UndefValue. ContainsUndef is true
9839 // iff Values contains only UndefValue instances. If there are other known
9840 // constants, then UndefValue is dropped.
9841 ContainsUndef = false;
9842 for (auto &It : Values) {
9843 if (isa<UndefValue>(It.getValue())) {
9844 ContainsUndef = true;
9845 continue;
9846 }
9847 auto *CI = dyn_cast<ConstantInt>(It.getValue());
9848 if (!CI)
9849 return false;
9850 S.insert(CI->getValue());
9851 }
9852 ContainsUndef &= S.empty();
9853
9854 return true;
9855 }
9856
9857 /// See AbstractAttribute::getAsStr().
9858 const std::string getAsStr(Attributor *A) const override {
9859 std::string Str;
9860 llvm::raw_string_ostream OS(Str);
9861 OS << getState();
9862 return Str;
9863 }
9864
9865 /// See AbstractAttribute::updateImpl(...).
9866 ChangeStatus updateImpl(Attributor &A) override {
9867 return indicatePessimisticFixpoint();
9868 }
9869};
9870
9871struct AAPotentialConstantValuesArgument final
9872 : AAArgumentFromCallSiteArguments<AAPotentialConstantValues,
9873 AAPotentialConstantValuesImpl,
9874 PotentialConstantIntValuesState> {
9875 using Base = AAArgumentFromCallSiteArguments<AAPotentialConstantValues,
9876 AAPotentialConstantValuesImpl,
9878 AAPotentialConstantValuesArgument(const IRPosition &IRP, Attributor &A)
9879 : Base(IRP, A) {}
9880
9881 /// See AbstractAttribute::trackStatistics()
9882 void trackStatistics() const override {
9883 STATS_DECLTRACK_ARG_ATTR(potential_values)
9884 }
9885};
9886
9887struct AAPotentialConstantValuesReturned
9888 : AAReturnedFromReturnedValues<AAPotentialConstantValues,
9889 AAPotentialConstantValuesImpl> {
9890 using Base = AAReturnedFromReturnedValues<AAPotentialConstantValues,
9891 AAPotentialConstantValuesImpl>;
9892 AAPotentialConstantValuesReturned(const IRPosition &IRP, Attributor &A)
9893 : Base(IRP, A) {}
9894
9895 void initialize(Attributor &A) override {
9896 if (!A.isFunctionIPOAmendable(*getAssociatedFunction()))
9897 indicatePessimisticFixpoint();
9898 Base::initialize(A);
9899 }
9900
9901 /// See AbstractAttribute::trackStatistics()
9902 void trackStatistics() const override {
9903 STATS_DECLTRACK_FNRET_ATTR(potential_values)
9904 }
9905};
9906
9907struct AAPotentialConstantValuesFloating : AAPotentialConstantValuesImpl {
9908 AAPotentialConstantValuesFloating(const IRPosition &IRP, Attributor &A)
9909 : AAPotentialConstantValuesImpl(IRP, A) {}
9910
9911 /// See AbstractAttribute::initialize(..).
9912 void initialize(Attributor &A) override {
9913 AAPotentialConstantValuesImpl::initialize(A);
9914 if (isAtFixpoint())
9915 return;
9916
9917 Value &V = getAssociatedValue();
9918
9919 if (auto *C = dyn_cast<ConstantInt>(&V)) {
9920 unionAssumed(C->getValue());
9921 indicateOptimisticFixpoint();
9922 return;
9923 }
9924
9925 if (isa<UndefValue>(&V)) {
9926 unionAssumedWithUndef();
9927 indicateOptimisticFixpoint();
9928 return;
9929 }
9930
9931 if (isa<BinaryOperator>(&V) || isa<ICmpInst>(&V) || isa<CastInst>(&V))
9932 return;
9933
9934 if (isa<SelectInst>(V) || isa<PHINode>(V) || isa<LoadInst>(V))
9935 return;
9936
9937 indicatePessimisticFixpoint();
9938
9939 LLVM_DEBUG(dbgs() << "[AAPotentialConstantValues] We give up: "
9940 << getAssociatedValue() << "\n");
9941 }
9942
9943 static bool calculateICmpInst(const ICmpInst *ICI, const APInt &LHS,
9944 const APInt &RHS) {
9945 return ICmpInst::compare(LHS, RHS, ICI->getPredicate());
9946 }
9947
9948 static APInt calculateCastInst(const CastInst *CI, const APInt &Src,
9949 uint32_t ResultBitWidth) {
9950 Instruction::CastOps CastOp = CI->getOpcode();
9951 switch (CastOp) {
9952 default:
9953 llvm_unreachable("unsupported or not integer cast");
9954 case Instruction::Trunc:
9955 return Src.trunc(ResultBitWidth);
9956 case Instruction::SExt:
9957 return Src.sext(ResultBitWidth);
9958 case Instruction::ZExt:
9959 return Src.zext(ResultBitWidth);
9960 case Instruction::BitCast:
9961 return Src;
9962 }
9963 }
9964
9965 static APInt calculateBinaryOperator(const BinaryOperator *BinOp,
9966 const APInt &LHS, const APInt &RHS,
9967 bool &SkipOperation, bool &Unsupported) {
9968 Instruction::BinaryOps BinOpcode = BinOp->getOpcode();
9969 // Unsupported is set to true when the binary operator is not supported.
9970 // SkipOperation is set to true when UB occur with the given operand pair
9971 // (LHS, RHS).
9972 // TODO: we should look at nsw and nuw keywords to handle operations
9973 // that create poison or undef value.
9974 switch (BinOpcode) {
9975 default:
9976 Unsupported = true;
9977 return LHS;
9978 case Instruction::Add:
9979 return LHS + RHS;
9980 case Instruction::Sub:
9981 return LHS - RHS;
9982 case Instruction::Mul:
9983 return LHS * RHS;
9984 case Instruction::UDiv:
9985 if (RHS.isZero()) {
9986 SkipOperation = true;
9987 return LHS;
9988 }
9989 return LHS.udiv(RHS);
9990 case Instruction::SDiv:
9991 if (RHS.isZero()) {
9992 SkipOperation = true;
9993 return LHS;
9994 }
9995 return LHS.sdiv(RHS);
9996 case Instruction::URem:
9997 if (RHS.isZero()) {
9998 SkipOperation = true;
9999 return LHS;
10000 }
10001 return LHS.urem(RHS);
10002 case Instruction::SRem:
10003 if (RHS.isZero()) {
10004 SkipOperation = true;
10005 return LHS;
10006 }
10007 return LHS.srem(RHS);
10008 case Instruction::Shl:
10009 return LHS.shl(RHS);
10010 case Instruction::LShr:
10011 return LHS.lshr(RHS);
10012 case Instruction::AShr:
10013 return LHS.ashr(RHS);
10014 case Instruction::And:
10015 return LHS & RHS;
10016 case Instruction::Or:
10017 return LHS | RHS;
10018 case Instruction::Xor:
10019 return LHS ^ RHS;
10020 }
10021 }
10022
10023 bool calculateBinaryOperatorAndTakeUnion(const BinaryOperator *BinOp,
10024 const APInt &LHS, const APInt &RHS) {
10025 bool SkipOperation = false;
10026 bool Unsupported = false;
10027 APInt Result =
10028 calculateBinaryOperator(BinOp, LHS, RHS, SkipOperation, Unsupported);
10029 if (Unsupported)
10030 return false;
10031 // If SkipOperation is true, we can ignore this operand pair (L, R).
10032 if (!SkipOperation)
10033 unionAssumed(Result);
10034 return isValidState();
10035 }
10036
10037 ChangeStatus updateWithICmpInst(Attributor &A, ICmpInst *ICI) {
10038 auto AssumedBefore = getAssumed();
10039 Value *LHS = ICI->getOperand(0);
10040 Value *RHS = ICI->getOperand(1);
10041
10042 bool LHSContainsUndef = false, RHSContainsUndef = false;
10043 SetTy LHSAAPVS, RHSAAPVS;
10044 if (!fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS,
10045 LHSContainsUndef, /* ForSelf */ false) ||
10046 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS,
10047 RHSContainsUndef, /* ForSelf */ false))
10048 return indicatePessimisticFixpoint();
10049
10050 // TODO: make use of undef flag to limit potential values aggressively.
10051 bool MaybeTrue = false, MaybeFalse = false;
10052 const APInt Zero(RHS->getType()->getIntegerBitWidth(), 0);
10053 if (LHSContainsUndef && RHSContainsUndef) {
10054 // The result of any comparison between undefs can be soundly replaced
10055 // with undef.
10056 unionAssumedWithUndef();
10057 } else if (LHSContainsUndef) {
10058 for (const APInt &R : RHSAAPVS) {
10059 bool CmpResult = calculateICmpInst(ICI, Zero, R);
10060 MaybeTrue |= CmpResult;
10061 MaybeFalse |= !CmpResult;
10062 if (MaybeTrue & MaybeFalse)
10063 return indicatePessimisticFixpoint();
10064 }
10065 } else if (RHSContainsUndef) {
10066 for (const APInt &L : LHSAAPVS) {
10067 bool CmpResult = calculateICmpInst(ICI, L, Zero);
10068 MaybeTrue |= CmpResult;
10069 MaybeFalse |= !CmpResult;
10070 if (MaybeTrue & MaybeFalse)
10071 return indicatePessimisticFixpoint();
10072 }
10073 } else {
10074 for (const APInt &L : LHSAAPVS) {
10075 for (const APInt &R : RHSAAPVS) {
10076 bool CmpResult = calculateICmpInst(ICI, L, R);
10077 MaybeTrue |= CmpResult;
10078 MaybeFalse |= !CmpResult;
10079 if (MaybeTrue & MaybeFalse)
10080 return indicatePessimisticFixpoint();
10081 }
10082 }
10083 }
10084 if (MaybeTrue)
10085 unionAssumed(APInt(/* numBits */ 1, /* val */ 1));
10086 if (MaybeFalse)
10087 unionAssumed(APInt(/* numBits */ 1, /* val */ 0));
10088 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10089 : ChangeStatus::CHANGED;
10090 }
10091
10092 ChangeStatus updateWithSelectInst(Attributor &A, SelectInst *SI) {
10093 auto AssumedBefore = getAssumed();
10094 Value *LHS = SI->getTrueValue();
10095 Value *RHS = SI->getFalseValue();
10096
10097 bool UsedAssumedInformation = false;
10098 std::optional<Constant *> C = A.getAssumedConstant(
10099 *SI->getCondition(), *this, UsedAssumedInformation);
10100
10101 // Check if we only need one operand.
10102 bool OnlyLeft = false, OnlyRight = false;
10103 if (C && *C && (*C)->isOneValue())
10104 OnlyLeft = true;
10105 else if (C && *C && (*C)->isNullValue())
10106 OnlyRight = true;
10107
10108 bool LHSContainsUndef = false, RHSContainsUndef = false;
10109 SetTy LHSAAPVS, RHSAAPVS;
10110 if (!OnlyRight &&
10111 !fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS,
10112 LHSContainsUndef, /* ForSelf */ false))
10113 return indicatePessimisticFixpoint();
10114
10115 if (!OnlyLeft &&
10116 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS,
10117 RHSContainsUndef, /* ForSelf */ false))
10118 return indicatePessimisticFixpoint();
10119
10120 if (OnlyLeft || OnlyRight) {
10121 // select (true/false), lhs, rhs
10122 auto *OpAA = OnlyLeft ? &LHSAAPVS : &RHSAAPVS;
10123 auto Undef = OnlyLeft ? LHSContainsUndef : RHSContainsUndef;
10124
10125 if (Undef)
10126 unionAssumedWithUndef();
10127 else {
10128 for (const auto &It : *OpAA)
10129 unionAssumed(It);
10130 }
10131
10132 } else if (LHSContainsUndef && RHSContainsUndef) {
10133 // select i1 *, undef , undef => undef
10134 unionAssumedWithUndef();
10135 } else {
10136 for (const auto &It : LHSAAPVS)
10137 unionAssumed(It);
10138 for (const auto &It : RHSAAPVS)
10139 unionAssumed(It);
10140 }
10141 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10142 : ChangeStatus::CHANGED;
10143 }
10144
10145 ChangeStatus updateWithCastInst(Attributor &A, CastInst *CI) {
10146 auto AssumedBefore = getAssumed();
10147 if (!CI->isIntegerCast())
10148 return indicatePessimisticFixpoint();
10149 assert(CI->getNumOperands() == 1 && "Expected cast to be unary!");
10150 uint32_t ResultBitWidth = CI->getDestTy()->getIntegerBitWidth();
10151 Value *Src = CI->getOperand(0);
10152
10153 bool SrcContainsUndef = false;
10154 SetTy SrcPVS;
10155 if (!fillSetWithConstantValues(A, IRPosition::value(*Src), SrcPVS,
10156 SrcContainsUndef, /* ForSelf */ false))
10157 return indicatePessimisticFixpoint();
10158
10159 if (SrcContainsUndef)
10160 unionAssumedWithUndef();
10161 else {
10162 for (const APInt &S : SrcPVS) {
10163 APInt T = calculateCastInst(CI, S, ResultBitWidth);
10164 unionAssumed(T);
10165 }
10166 }
10167 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10168 : ChangeStatus::CHANGED;
10169 }
10170
10171 ChangeStatus updateWithBinaryOperator(Attributor &A, BinaryOperator *BinOp) {
10172 auto AssumedBefore = getAssumed();
10173 Value *LHS = BinOp->getOperand(0);
10174 Value *RHS = BinOp->getOperand(1);
10175
10176 bool LHSContainsUndef = false, RHSContainsUndef = false;
10177 SetTy LHSAAPVS, RHSAAPVS;
10178 if (!fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS,
10179 LHSContainsUndef, /* ForSelf */ false) ||
10180 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS,
10181 RHSContainsUndef, /* ForSelf */ false))
10182 return indicatePessimisticFixpoint();
10183
10184 const APInt Zero = APInt(LHS->getType()->getIntegerBitWidth(), 0);
10185
10186 // TODO: make use of undef flag to limit potential values aggressively.
10187 if (LHSContainsUndef && RHSContainsUndef) {
10188 if (!calculateBinaryOperatorAndTakeUnion(BinOp, Zero, Zero))
10189 return indicatePessimisticFixpoint();
10190 } else if (LHSContainsUndef) {
10191 for (const APInt &R : RHSAAPVS) {
10192 if (!calculateBinaryOperatorAndTakeUnion(BinOp, Zero, R))
10193 return indicatePessimisticFixpoint();
10194 }
10195 } else if (RHSContainsUndef) {
10196 for (const APInt &L : LHSAAPVS) {
10197 if (!calculateBinaryOperatorAndTakeUnion(BinOp, L, Zero))
10198 return indicatePessimisticFixpoint();
10199 }
10200 } else {
10201 for (const APInt &L : LHSAAPVS) {
10202 for (const APInt &R : RHSAAPVS) {
10203 if (!calculateBinaryOperatorAndTakeUnion(BinOp, L, R))
10204 return indicatePessimisticFixpoint();
10205 }
10206 }
10207 }
10208 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10209 : ChangeStatus::CHANGED;
10210 }
10211
10212 ChangeStatus updateWithInstruction(Attributor &A, Instruction *Inst) {
10213 auto AssumedBefore = getAssumed();
10214 SetTy Incoming;
10215 bool ContainsUndef;
10216 if (!fillSetWithConstantValues(A, IRPosition::value(*Inst), Incoming,
10217 ContainsUndef, /* ForSelf */ true))
10218 return indicatePessimisticFixpoint();
10219 if (ContainsUndef) {
10220 unionAssumedWithUndef();
10221 } else {
10222 for (const auto &It : Incoming)
10223 unionAssumed(It);
10224 }
10225 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10226 : ChangeStatus::CHANGED;
10227 }
10228
10229 /// See AbstractAttribute::updateImpl(...).
10230 ChangeStatus updateImpl(Attributor &A) override {
10231 Value &V = getAssociatedValue();
10233
10234 if (auto *ICI = dyn_cast<ICmpInst>(I))
10235 return updateWithICmpInst(A, ICI);
10236
10237 if (auto *SI = dyn_cast<SelectInst>(I))
10238 return updateWithSelectInst(A, SI);
10239
10240 if (auto *CI = dyn_cast<CastInst>(I))
10241 return updateWithCastInst(A, CI);
10242
10243 if (auto *BinOp = dyn_cast<BinaryOperator>(I))
10244 return updateWithBinaryOperator(A, BinOp);
10245
10246 if (isa<PHINode>(I) || isa<LoadInst>(I))
10247 return updateWithInstruction(A, I);
10248
10249 return indicatePessimisticFixpoint();
10250 }
10251
10252 /// See AbstractAttribute::trackStatistics()
10253 void trackStatistics() const override {
10254 STATS_DECLTRACK_FLOATING_ATTR(potential_values)
10255 }
10256};
10257
10258struct AAPotentialConstantValuesFunction : AAPotentialConstantValuesImpl {
10259 AAPotentialConstantValuesFunction(const IRPosition &IRP, Attributor &A)
10260 : AAPotentialConstantValuesImpl(IRP, A) {}
10261
10262 /// See AbstractAttribute::initialize(...).
10263 ChangeStatus updateImpl(Attributor &A) override {
10265 "AAPotentialConstantValues(Function|CallSite)::updateImpl will "
10266 "not be called");
10267 }
10268
10269 /// See AbstractAttribute::trackStatistics()
10270 void trackStatistics() const override {
10271 STATS_DECLTRACK_FN_ATTR(potential_values)
10272 }
10273};
10274
10275struct AAPotentialConstantValuesCallSite : AAPotentialConstantValuesFunction {
10276 AAPotentialConstantValuesCallSite(const IRPosition &IRP, Attributor &A)
10277 : AAPotentialConstantValuesFunction(IRP, A) {}
10278
10279 /// See AbstractAttribute::trackStatistics()
10280 void trackStatistics() const override {
10281 STATS_DECLTRACK_CS_ATTR(potential_values)
10282 }
10283};
10284
10285struct AAPotentialConstantValuesCallSiteReturned
10286 : AACalleeToCallSite<AAPotentialConstantValues,
10287 AAPotentialConstantValuesImpl> {
10288 AAPotentialConstantValuesCallSiteReturned(const IRPosition &IRP,
10289 Attributor &A)
10290 : AACalleeToCallSite<AAPotentialConstantValues,
10291 AAPotentialConstantValuesImpl>(IRP, A) {}
10292
10293 /// See AbstractAttribute::trackStatistics()
10294 void trackStatistics() const override {
10295 STATS_DECLTRACK_CSRET_ATTR(potential_values)
10296 }
10297};
10298
10299struct AAPotentialConstantValuesCallSiteArgument
10300 : AAPotentialConstantValuesFloating {
10301 AAPotentialConstantValuesCallSiteArgument(const IRPosition &IRP,
10302 Attributor &A)
10303 : AAPotentialConstantValuesFloating(IRP, A) {}
10304
10305 /// See AbstractAttribute::initialize(..).
10306 void initialize(Attributor &A) override {
10307 AAPotentialConstantValuesImpl::initialize(A);
10308 if (isAtFixpoint())
10309 return;
10310
10311 Value &V = getAssociatedValue();
10312
10313 if (auto *C = dyn_cast<ConstantInt>(&V)) {
10314 unionAssumed(C->getValue());
10315 indicateOptimisticFixpoint();
10316 return;
10317 }
10318
10319 if (isa<UndefValue>(&V)) {
10320 unionAssumedWithUndef();
10321 indicateOptimisticFixpoint();
10322 return;
10323 }
10324 }
10325
10326 /// See AbstractAttribute::updateImpl(...).
10327 ChangeStatus updateImpl(Attributor &A) override {
10328 Value &V = getAssociatedValue();
10329 auto AssumedBefore = getAssumed();
10330 auto *AA = A.getAAFor<AAPotentialConstantValues>(
10331 *this, IRPosition::value(V), DepClassTy::REQUIRED);
10332 if (!AA)
10333 return indicatePessimisticFixpoint();
10334 const auto &S = AA->getAssumed();
10335 unionAssumed(S);
10336 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10337 : ChangeStatus::CHANGED;
10338 }
10339
10340 /// See AbstractAttribute::trackStatistics()
10341 void trackStatistics() const override {
10342 STATS_DECLTRACK_CSARG_ATTR(potential_values)
10343 }
10344};
10345} // namespace
10346
10347/// ------------------------ NoUndef Attribute ---------------------------------
10349 Attribute::AttrKind ImpliedAttributeKind,
10350 bool IgnoreSubsumingPositions) {
10351 assert(ImpliedAttributeKind == Attribute::NoUndef &&
10352 "Unexpected attribute kind");
10353 if (A.hasAttr(IRP, {Attribute::NoUndef}, IgnoreSubsumingPositions,
10354 Attribute::NoUndef))
10355 return true;
10356
10357 Value &Val = IRP.getAssociatedValue();
10360 LLVMContext &Ctx = Val.getContext();
10361 A.manifestAttrs(IRP, Attribute::get(Ctx, Attribute::NoUndef));
10362 return true;
10363 }
10364
10365 return false;
10366}
10367
10368namespace {
10369struct AANoUndefImpl : AANoUndef {
10370 AANoUndefImpl(const IRPosition &IRP, Attributor &A) : AANoUndef(IRP, A) {}
10371
10372 /// See AbstractAttribute::initialize(...).
10373 void initialize(Attributor &A) override {
10374 Value &V = getAssociatedValue();
10375 if (isa<UndefValue>(V))
10376 indicatePessimisticFixpoint();
10377 assert(!isImpliedByIR(A, getIRPosition(), Attribute::NoUndef));
10378 }
10379
10380 /// See followUsesInMBEC
10381 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
10382 AANoUndef::StateType &State) {
10383 const Value *UseV = U->get();
10384 const DominatorTree *DT = nullptr;
10385 AssumptionCache *AC = nullptr;
10386 InformationCache &InfoCache = A.getInfoCache();
10387 if (Function *F = getAnchorScope()) {
10388 DT = InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F);
10389 AC = InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F);
10390 }
10391 State.setKnown(isGuaranteedNotToBeUndefOrPoison(UseV, AC, I, DT));
10392 bool TrackUse = false;
10393 // Track use for instructions which must produce undef or poison bits when
10394 // at least one operand contains such bits.
10396 TrackUse = true;
10397 return TrackUse;
10398 }
10399
10400 /// See AbstractAttribute::getAsStr().
10401 const std::string getAsStr(Attributor *A) const override {
10402 return getAssumed() ? "noundef" : "may-undef-or-poison";
10403 }
10404
10405 ChangeStatus manifest(Attributor &A) override {
10406 // We don't manifest noundef attribute for dead positions because the
10407 // associated values with dead positions would be replaced with undef
10408 // values.
10409 bool UsedAssumedInformation = false;
10410 if (A.isAssumedDead(getIRPosition(), nullptr, nullptr,
10411 UsedAssumedInformation))
10412 return ChangeStatus::UNCHANGED;
10413 // A position whose simplified value does not have any value is
10414 // considered to be dead. We don't manifest noundef in such positions for
10415 // the same reason above.
10416 if (!A.getAssumedSimplified(getIRPosition(), *this, UsedAssumedInformation,
10418 .has_value())
10419 return ChangeStatus::UNCHANGED;
10420 return AANoUndef::manifest(A);
10421 }
10422};
10423
10424struct AANoUndefFloating : public AANoUndefImpl {
10425 AANoUndefFloating(const IRPosition &IRP, Attributor &A)
10426 : AANoUndefImpl(IRP, A) {}
10427
10428 /// See AbstractAttribute::initialize(...).
10429 void initialize(Attributor &A) override {
10430 AANoUndefImpl::initialize(A);
10431 if (!getState().isAtFixpoint() && getAnchorScope() &&
10432 !getAnchorScope()->isDeclaration())
10433 if (Instruction *CtxI = getCtxI())
10434 followUsesInMBEC(*this, A, getState(), *CtxI);
10435 }
10436
10437 /// See AbstractAttribute::updateImpl(...).
10438 ChangeStatus updateImpl(Attributor &A) override {
10439 auto VisitValueCB = [&](const IRPosition &IRP) -> bool {
10440 bool IsKnownNoUndef;
10442 A, this, IRP, DepClassTy::REQUIRED, IsKnownNoUndef);
10443 };
10444
10445 bool Stripped;
10446 bool UsedAssumedInformation = false;
10447 Value *AssociatedValue = &getAssociatedValue();
10449 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
10450 AA::AnyScope, UsedAssumedInformation))
10451 Stripped = false;
10452 else
10453 Stripped =
10454 Values.size() != 1 || Values.front().getValue() != AssociatedValue;
10455
10456 if (!Stripped) {
10457 // If we haven't stripped anything we might still be able to use a
10458 // different AA, but only if the IRP changes. Effectively when we
10459 // interpret this not as a call site value but as a floating/argument
10460 // value.
10461 const IRPosition AVIRP = IRPosition::value(*AssociatedValue);
10462 if (AVIRP == getIRPosition() || !VisitValueCB(AVIRP))
10463 return indicatePessimisticFixpoint();
10464 return ChangeStatus::UNCHANGED;
10465 }
10466
10467 for (const auto &VAC : Values)
10468 if (!VisitValueCB(IRPosition::value(*VAC.getValue())))
10469 return indicatePessimisticFixpoint();
10470
10471 return ChangeStatus::UNCHANGED;
10472 }
10473
10474 /// See AbstractAttribute::trackStatistics()
10475 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noundef) }
10476};
10477
10478struct AANoUndefReturned final
10479 : AAReturnedFromReturnedValues<AANoUndef, AANoUndefImpl> {
10480 AANoUndefReturned(const IRPosition &IRP, Attributor &A)
10481 : AAReturnedFromReturnedValues<AANoUndef, AANoUndefImpl>(IRP, A) {}
10482
10483 /// See AbstractAttribute::trackStatistics()
10484 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noundef) }
10485};
10486
10487struct AANoUndefArgument final
10488 : AAArgumentFromCallSiteArguments<AANoUndef, AANoUndefImpl> {
10489 AANoUndefArgument(const IRPosition &IRP, Attributor &A)
10490 : AAArgumentFromCallSiteArguments<AANoUndef, AANoUndefImpl>(IRP, A) {}
10491
10492 /// See AbstractAttribute::trackStatistics()
10493 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noundef) }
10494};
10495
10496struct AANoUndefCallSiteArgument final : AANoUndefFloating {
10497 AANoUndefCallSiteArgument(const IRPosition &IRP, Attributor &A)
10498 : AANoUndefFloating(IRP, A) {}
10499
10500 /// See AbstractAttribute::trackStatistics()
10501 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(noundef) }
10502};
10503
10504struct AANoUndefCallSiteReturned final
10505 : AACalleeToCallSite<AANoUndef, AANoUndefImpl> {
10506 AANoUndefCallSiteReturned(const IRPosition &IRP, Attributor &A)
10507 : AACalleeToCallSite<AANoUndef, AANoUndefImpl>(IRP, A) {}
10508
10509 /// See AbstractAttribute::trackStatistics()
10510 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(noundef) }
10511};
10512
10513/// ------------------------ NoFPClass Attribute -------------------------------
10514
10515struct AANoFPClassImpl : AANoFPClass {
10516 AANoFPClassImpl(const IRPosition &IRP, Attributor &A) : AANoFPClass(IRP, A) {}
10517
10518 void initialize(Attributor &A) override {
10519 const IRPosition &IRP = getIRPosition();
10520
10521 Value &V = IRP.getAssociatedValue();
10522 if (isa<UndefValue>(V)) {
10523 indicateOptimisticFixpoint();
10524 return;
10525 }
10526
10528 A.getAttrs(getIRPosition(), {Attribute::NoFPClass}, Attrs, false);
10529 for (const auto &Attr : Attrs) {
10530 addKnownBits(Attr.getNoFPClass());
10531 }
10532
10533 Instruction *CtxI = getCtxI();
10534
10535 if (getPositionKind() != IRPosition::IRP_RETURNED) {
10536 const DataLayout &DL = A.getDataLayout();
10537 InformationCache &InfoCache = A.getInfoCache();
10538
10539 const DominatorTree *DT = nullptr;
10540 AssumptionCache *AC = nullptr;
10541 const TargetLibraryInfo *TLI = nullptr;
10542 Function *F = getAnchorScope();
10543 if (F) {
10544 TLI = InfoCache.getTargetLibraryInfoForFunction(*F);
10545 if (!F->isDeclaration()) {
10546 DT =
10547 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F);
10548 AC = InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F);
10549 }
10550 }
10551
10552 SimplifyQuery Q(DL, TLI, DT, AC, CtxI);
10553
10554 KnownFPClass KnownFPClass = computeKnownFPClass(&V, fcAllFlags, Q);
10555 addKnownBits(~KnownFPClass.KnownFPClasses);
10556 }
10557
10558 if (CtxI)
10559 followUsesInMBEC(*this, A, getState(), *CtxI);
10560 }
10561
10562 /// See followUsesInMBEC
10563 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
10564 AANoFPClass::StateType &State) {
10565 // TODO: Determine what instructions can be looked through.
10566 auto *CB = dyn_cast<CallBase>(I);
10567 if (!CB)
10568 return false;
10569
10570 if (!CB->isArgOperand(U))
10571 return false;
10572
10573 unsigned ArgNo = CB->getArgOperandNo(U);
10574 IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo);
10575 if (auto *NoFPAA = A.getAAFor<AANoFPClass>(*this, IRP, DepClassTy::NONE))
10576 State.addKnownBits(NoFPAA->getState().getKnown());
10577 return false;
10578 }
10579
10580 const std::string getAsStr(Attributor *A) const override {
10581 std::string Result = "nofpclass";
10582 raw_string_ostream OS(Result);
10583 OS << getKnownNoFPClass() << '/' << getAssumedNoFPClass();
10584 return Result;
10585 }
10586
10587 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
10588 SmallVectorImpl<Attribute> &Attrs) const override {
10589 Attrs.emplace_back(Attribute::getWithNoFPClass(Ctx, getAssumedNoFPClass()));
10590 }
10591};
10592
10593struct AANoFPClassFloating : public AANoFPClassImpl {
10594 AANoFPClassFloating(const IRPosition &IRP, Attributor &A)
10595 : AANoFPClassImpl(IRP, A) {}
10596
10597 /// See AbstractAttribute::updateImpl(...).
10598 ChangeStatus updateImpl(Attributor &A) override {
10600 bool UsedAssumedInformation = false;
10601 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
10602 AA::AnyScope, UsedAssumedInformation)) {
10603 Values.push_back({getAssociatedValue(), getCtxI()});
10604 }
10605
10606 StateType T;
10607 auto VisitValueCB = [&](Value &V, const Instruction *CtxI) -> bool {
10608 const auto *AA = A.getAAFor<AANoFPClass>(*this, IRPosition::value(V),
10609 DepClassTy::REQUIRED);
10610 if (!AA || this == AA) {
10611 T.indicatePessimisticFixpoint();
10612 } else {
10613 const AANoFPClass::StateType &S =
10614 static_cast<const AANoFPClass::StateType &>(AA->getState());
10615 T ^= S;
10616 }
10617 return T.isValidState();
10618 };
10619
10620 for (const auto &VAC : Values)
10621 if (!VisitValueCB(*VAC.getValue(), VAC.getCtxI()))
10622 return indicatePessimisticFixpoint();
10623
10624 return clampStateAndIndicateChange(getState(), T);
10625 }
10626
10627 /// See AbstractAttribute::trackStatistics()
10628 void trackStatistics() const override {
10630 }
10631};
10632
10633struct AANoFPClassReturned final
10634 : AAReturnedFromReturnedValues<AANoFPClass, AANoFPClassImpl,
10635 AANoFPClassImpl::StateType, false,
10636 Attribute::None, false> {
10637 AANoFPClassReturned(const IRPosition &IRP, Attributor &A)
10638 : AAReturnedFromReturnedValues<AANoFPClass, AANoFPClassImpl,
10639 AANoFPClassImpl::StateType, false,
10640 Attribute::None, false>(IRP, A) {}
10641
10642 /// See AbstractAttribute::trackStatistics()
10643 void trackStatistics() const override {
10645 }
10646};
10647
10648struct AANoFPClassArgument final
10649 : AAArgumentFromCallSiteArguments<AANoFPClass, AANoFPClassImpl> {
10650 AANoFPClassArgument(const IRPosition &IRP, Attributor &A)
10651 : AAArgumentFromCallSiteArguments<AANoFPClass, AANoFPClassImpl>(IRP, A) {}
10652
10653 /// See AbstractAttribute::trackStatistics()
10654 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nofpclass) }
10655};
10656
10657struct AANoFPClassCallSiteArgument final : AANoFPClassFloating {
10658 AANoFPClassCallSiteArgument(const IRPosition &IRP, Attributor &A)
10659 : AANoFPClassFloating(IRP, A) {}
10660
10661 /// See AbstractAttribute::trackStatistics()
10662 void trackStatistics() const override {
10664 }
10665};
10666
10667struct AANoFPClassCallSiteReturned final
10668 : AACalleeToCallSite<AANoFPClass, AANoFPClassImpl> {
10669 AANoFPClassCallSiteReturned(const IRPosition &IRP, Attributor &A)
10670 : AACalleeToCallSite<AANoFPClass, AANoFPClassImpl>(IRP, A) {}
10671
10672 /// See AbstractAttribute::trackStatistics()
10673 void trackStatistics() const override {
10675 }
10676};
10677
10678struct AACallEdgesImpl : public AACallEdges {
10679 AACallEdgesImpl(const IRPosition &IRP, Attributor &A) : AACallEdges(IRP, A) {}
10680
10681 const SetVector<Function *> &getOptimisticEdges() const override {
10682 return CalledFunctions;
10683 }
10684
10685 bool hasUnknownCallee() const override { return HasUnknownCallee; }
10686
10687 bool hasNonAsmUnknownCallee() const override {
10688 return HasUnknownCalleeNonAsm;
10689 }
10690
10691 const std::string getAsStr(Attributor *A) const override {
10692 return "CallEdges[" + std::to_string(HasUnknownCallee) + "," +
10693 std::to_string(CalledFunctions.size()) + "]";
10694 }
10695
10696 void trackStatistics() const override {}
10697
10698protected:
10699 void addCalledFunction(Function *Fn, ChangeStatus &Change) {
10700 if (CalledFunctions.insert(Fn)) {
10701 Change = ChangeStatus::CHANGED;
10702 LLVM_DEBUG(dbgs() << "[AACallEdges] New call edge: " << Fn->getName()
10703 << "\n");
10704 }
10705 }
10706
10707 void setHasUnknownCallee(bool NonAsm, ChangeStatus &Change) {
10708 if (!HasUnknownCallee)
10709 Change = ChangeStatus::CHANGED;
10710 if (NonAsm && !HasUnknownCalleeNonAsm)
10711 Change = ChangeStatus::CHANGED;
10712 HasUnknownCalleeNonAsm |= NonAsm;
10713 HasUnknownCallee = true;
10714 }
10715
10716private:
10717 /// Optimistic set of functions that might be called by this position.
10718 SetVector<Function *> CalledFunctions;
10719
10720 /// Is there any call with a unknown callee.
10721 bool HasUnknownCallee = false;
10722
10723 /// Is there any call with a unknown callee, excluding any inline asm.
10724 bool HasUnknownCalleeNonAsm = false;
10725};
10726
10727struct AACallEdgesCallSite : public AACallEdgesImpl {
10728 AACallEdgesCallSite(const IRPosition &IRP, Attributor &A)
10729 : AACallEdgesImpl(IRP, A) {}
10730 /// See AbstractAttribute::updateImpl(...).
10731 ChangeStatus updateImpl(Attributor &A) override {
10732 ChangeStatus Change = ChangeStatus::UNCHANGED;
10733
10734 auto VisitValue = [&](Value &V, const Instruction *CtxI) -> bool {
10735 if (Function *Fn = dyn_cast<Function>(&V)) {
10736 addCalledFunction(Fn, Change);
10737 } else {
10738 LLVM_DEBUG(dbgs() << "[AACallEdges] Unrecognized value: " << V << "\n");
10739 setHasUnknownCallee(true, Change);
10740 }
10741
10742 // Explore all values.
10743 return true;
10744 };
10745
10747 // Process any value that we might call.
10748 auto ProcessCalledOperand = [&](Value *V, Instruction *CtxI) {
10749 if (isa<Constant>(V)) {
10750 VisitValue(*V, CtxI);
10751 return;
10752 }
10753
10754 bool UsedAssumedInformation = false;
10755 Values.clear();
10756 if (!A.getAssumedSimplifiedValues(IRPosition::value(*V), *this, Values,
10757 AA::AnyScope, UsedAssumedInformation)) {
10758 Values.push_back({*V, CtxI});
10759 }
10760 for (auto &VAC : Values)
10761 VisitValue(*VAC.getValue(), VAC.getCtxI());
10762 };
10763
10764 CallBase *CB = cast<CallBase>(getCtxI());
10765
10766 if (auto *IA = dyn_cast<InlineAsm>(CB->getCalledOperand())) {
10767 if (IA->hasSideEffects() &&
10768 !hasAssumption(*CB->getCaller(), "ompx_no_call_asm") &&
10769 !hasAssumption(*CB, "ompx_no_call_asm")) {
10770 setHasUnknownCallee(false, Change);
10771 }
10772 return Change;
10773 }
10774
10775 if (CB->isIndirectCall())
10776 if (auto *IndirectCallAA = A.getAAFor<AAIndirectCallInfo>(
10777 *this, getIRPosition(), DepClassTy::OPTIONAL))
10778 if (IndirectCallAA->foreachCallee(
10779 [&](Function *Fn) { return VisitValue(*Fn, CB); }))
10780 return Change;
10781
10782 // The most simple case.
10783 ProcessCalledOperand(CB->getCalledOperand(), CB);
10784
10785 // Process callback functions.
10786 SmallVector<const Use *, 4u> CallbackUses;
10787 AbstractCallSite::getCallbackUses(*CB, CallbackUses);
10788 for (const Use *U : CallbackUses)
10789 ProcessCalledOperand(U->get(), CB);
10790
10791 return Change;
10792 }
10793};
10794
10795struct AACallEdgesFunction : public AACallEdgesImpl {
10796 AACallEdgesFunction(const IRPosition &IRP, Attributor &A)
10797 : AACallEdgesImpl(IRP, A) {}
10798
10799 /// See AbstractAttribute::updateImpl(...).
10800 ChangeStatus updateImpl(Attributor &A) override {
10801 ChangeStatus Change = ChangeStatus::UNCHANGED;
10802
10803 auto ProcessCallInst = [&](Instruction &Inst) {
10804 CallBase &CB = cast<CallBase>(Inst);
10805
10806 auto *CBEdges = A.getAAFor<AACallEdges>(
10807 *this, IRPosition::callsite_function(CB), DepClassTy::REQUIRED);
10808 if (!CBEdges)
10809 return false;
10810 if (CBEdges->hasNonAsmUnknownCallee())
10811 setHasUnknownCallee(true, Change);
10812 if (CBEdges->hasUnknownCallee())
10813 setHasUnknownCallee(false, Change);
10814
10815 for (Function *F : CBEdges->getOptimisticEdges())
10816 addCalledFunction(F, Change);
10817
10818 return true;
10819 };
10820
10821 // Visit all callable instructions.
10822 bool UsedAssumedInformation = false;
10823 if (!A.checkForAllCallLikeInstructions(ProcessCallInst, *this,
10824 UsedAssumedInformation,
10825 /* CheckBBLivenessOnly */ true)) {
10826 // If we haven't looked at all call like instructions, assume that there
10827 // are unknown callees.
10828 setHasUnknownCallee(true, Change);
10829 }
10830
10831 return Change;
10832 }
10833};
10834
10835/// -------------------AAInterFnReachability Attribute--------------------------
10836
10837struct AAInterFnReachabilityFunction
10838 : public CachedReachabilityAA<AAInterFnReachability, Function> {
10839 using Base = CachedReachabilityAA<AAInterFnReachability, Function>;
10840 AAInterFnReachabilityFunction(const IRPosition &IRP, Attributor &A)
10841 : Base(IRP, A) {}
10842
10843 bool instructionCanReach(
10844 Attributor &A, const Instruction &From, const Function &To,
10845 const AA::InstExclusionSetTy *ExclusionSet) const override {
10846 assert(From.getFunction() == getAnchorScope() && "Queried the wrong AA!");
10847 auto *NonConstThis = const_cast<AAInterFnReachabilityFunction *>(this);
10848
10849 RQITy StackRQI(A, From, To, ExclusionSet, false);
10850 RQITy::Reachable Result;
10851 if (!NonConstThis->checkQueryCache(A, StackRQI, Result))
10852 return NonConstThis->isReachableImpl(A, StackRQI,
10853 /*IsTemporaryRQI=*/true);
10854 return Result == RQITy::Reachable::Yes;
10855 }
10856
10857 bool isReachableImpl(Attributor &A, RQITy &RQI,
10858 bool IsTemporaryRQI) override {
10859 const Instruction *EntryI =
10860 &RQI.From->getFunction()->getEntryBlock().front();
10861 if (EntryI != RQI.From &&
10862 !instructionCanReach(A, *EntryI, *RQI.To, nullptr))
10863 return rememberResult(A, RQITy::Reachable::No, RQI, false,
10864 IsTemporaryRQI);
10865
10866 auto CheckReachableCallBase = [&](CallBase *CB) {
10867 auto *CBEdges = A.getAAFor<AACallEdges>(
10868 *this, IRPosition::callsite_function(*CB), DepClassTy::OPTIONAL);
10869 if (!CBEdges || !CBEdges->getState().isValidState())
10870 return false;
10871 // TODO Check To backwards in this case.
10872 if (CBEdges->hasUnknownCallee())
10873 return false;
10874
10875 for (Function *Fn : CBEdges->getOptimisticEdges()) {
10876 if (Fn == RQI.To)
10877 return false;
10878
10879 if (Fn->isDeclaration()) {
10880 if (Fn->hasFnAttribute(Attribute::NoCallback))
10881 continue;
10882 // TODO Check To backwards in this case.
10883 return false;
10884 }
10885
10886 if (Fn == getAnchorScope()) {
10887 if (EntryI == RQI.From)
10888 continue;
10889 return false;
10890 }
10891
10892 const AAInterFnReachability *InterFnReachability =
10893 A.getAAFor<AAInterFnReachability>(*this, IRPosition::function(*Fn),
10894 DepClassTy::OPTIONAL);
10895
10896 const Instruction &FnFirstInst = Fn->getEntryBlock().front();
10897 if (!InterFnReachability ||
10898 InterFnReachability->instructionCanReach(A, FnFirstInst, *RQI.To,
10899 RQI.ExclusionSet))
10900 return false;
10901 }
10902 return true;
10903 };
10904
10905 const auto *IntraFnReachability = A.getAAFor<AAIntraFnReachability>(
10906 *this, IRPosition::function(*RQI.From->getFunction()),
10907 DepClassTy::OPTIONAL);
10908
10909 // Determine call like instructions that we can reach from the inst.
10910 auto CheckCallBase = [&](Instruction &CBInst) {
10911 // There are usually less nodes in the call graph, check inter function
10912 // reachability first.
10913 if (CheckReachableCallBase(cast<CallBase>(&CBInst)))
10914 return true;
10915 return IntraFnReachability && !IntraFnReachability->isAssumedReachable(
10916 A, *RQI.From, CBInst, RQI.ExclusionSet);
10917 };
10918
10919 bool UsedExclusionSet = /* conservative */ true;
10920 bool UsedAssumedInformation = false;
10921 if (!A.checkForAllCallLikeInstructions(CheckCallBase, *this,
10922 UsedAssumedInformation,
10923 /* CheckBBLivenessOnly */ true))
10924 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
10925 IsTemporaryRQI);
10926
10927 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
10928 IsTemporaryRQI);
10929 }
10930
10931 void trackStatistics() const override {}
10932};
10933} // namespace
10934
10935template <typename AAType>
10936static std::optional<Constant *>
10938 const IRPosition &IRP, Type &Ty) {
10939 if (!Ty.isIntegerTy())
10940 return nullptr;
10941
10942 // This will also pass the call base context.
10943 const auto *AA = A.getAAFor<AAType>(QueryingAA, IRP, DepClassTy::NONE);
10944 if (!AA)
10945 return nullptr;
10946
10947 std::optional<Constant *> COpt = AA->getAssumedConstant(A);
10948
10949 if (!COpt.has_value()) {
10950 A.recordDependence(*AA, QueryingAA, DepClassTy::OPTIONAL);
10951 return std::nullopt;
10952 }
10953 if (auto *C = *COpt) {
10954 A.recordDependence(*AA, QueryingAA, DepClassTy::OPTIONAL);
10955 return C;
10956 }
10957 return nullptr;
10958}
10959
10961 Attributor &A, const AbstractAttribute &AA, const IRPosition &IRP,
10963 Type &Ty = *IRP.getAssociatedType();
10964 std::optional<Value *> V;
10965 for (auto &It : Values) {
10966 V = AA::combineOptionalValuesInAAValueLatice(V, It.getValue(), &Ty);
10967 if (V.has_value() && !*V)
10968 break;
10969 }
10970 if (!V.has_value())
10971 return UndefValue::get(&Ty);
10972 return *V;
10973}
10974
10975namespace {
10976struct AAPotentialValuesImpl : AAPotentialValues {
10977 using StateType = PotentialLLVMValuesState;
10978
10979 AAPotentialValuesImpl(const IRPosition &IRP, Attributor &A)
10980 : AAPotentialValues(IRP, A) {}
10981
10982 /// See AbstractAttribute::initialize(..).
10983 void initialize(Attributor &A) override {
10984 if (A.hasSimplificationCallback(getIRPosition())) {
10985 indicatePessimisticFixpoint();
10986 return;
10987 }
10988 Value *Stripped = getAssociatedValue().stripPointerCasts();
10989 if (isa<Constant>(Stripped) && !isa<ConstantExpr>(Stripped)) {
10990 addValue(A, getState(), *Stripped, getCtxI(), AA::AnyScope,
10991 getAnchorScope());
10992 indicateOptimisticFixpoint();
10993 return;
10994 }
10995 AAPotentialValues::initialize(A);
10996 }
10997
10998 /// See AbstractAttribute::getAsStr().
10999 const std::string getAsStr(Attributor *A) const override {
11000 std::string Str;
11001 llvm::raw_string_ostream OS(Str);
11002 OS << getState();
11003 return Str;
11004 }
11005
11006 template <typename AAType>
11007 static std::optional<Value *> askOtherAA(Attributor &A,
11008 const AbstractAttribute &AA,
11009 const IRPosition &IRP, Type &Ty) {
11011 return &IRP.getAssociatedValue();
11012 std::optional<Constant *> C = askForAssumedConstant<AAType>(A, AA, IRP, Ty);
11013 if (!C)
11014 return std::nullopt;
11015 if (*C)
11016 if (auto *CC = AA::getWithType(**C, Ty))
11017 return CC;
11018 return nullptr;
11019 }
11020
11021 virtual void addValue(Attributor &A, StateType &State, Value &V,
11022 const Instruction *CtxI, AA::ValueScope S,
11023 Function *AnchorScope) const {
11024
11025 IRPosition ValIRP = IRPosition::value(V);
11026 if (auto *CB = dyn_cast_or_null<CallBase>(CtxI)) {
11027 for (const auto &U : CB->args()) {
11028 if (U.get() != &V)
11029 continue;
11030 ValIRP = IRPosition::callsite_argument(*CB, CB->getArgOperandNo(&U));
11031 break;
11032 }
11033 }
11034
11035 Value *VPtr = &V;
11036 if (ValIRP.getAssociatedType()->isIntegerTy()) {
11037 Type &Ty = *getAssociatedType();
11038 std::optional<Value *> SimpleV =
11039 askOtherAA<AAValueConstantRange>(A, *this, ValIRP, Ty);
11040 if (SimpleV.has_value() && !*SimpleV) {
11041 auto *PotentialConstantsAA = A.getAAFor<AAPotentialConstantValues>(
11042 *this, ValIRP, DepClassTy::OPTIONAL);
11043 if (PotentialConstantsAA && PotentialConstantsAA->isValidState()) {
11044 for (const auto &It : PotentialConstantsAA->getAssumedSet())
11045 State.unionAssumed({{*ConstantInt::get(&Ty, It), nullptr}, S});
11046 if (PotentialConstantsAA->undefIsContained())
11047 State.unionAssumed({{*UndefValue::get(&Ty), nullptr}, S});
11048 return;
11049 }
11050 }
11051 if (!SimpleV.has_value())
11052 return;
11053
11054 if (*SimpleV)
11055 VPtr = *SimpleV;
11056 }
11057
11058 if (isa<ConstantInt>(VPtr))
11059 CtxI = nullptr;
11060 if (!AA::isValidInScope(*VPtr, AnchorScope))
11062
11063 State.unionAssumed({{*VPtr, CtxI}, S});
11064 }
11065
11066 /// Helper struct to tie a value+context pair together with the scope for
11067 /// which this is the simplified version.
11068 struct ItemInfo {
11069 AA::ValueAndContext I;
11071
11072 bool operator==(const ItemInfo &II) const {
11073 return II.I == I && II.S == S;
11074 };
11075 bool operator<(const ItemInfo &II) const {
11076 return std::tie(I, S) < std::tie(II.I, II.S);
11077 };
11078 };
11079
11080 bool recurseForValue(Attributor &A, const IRPosition &IRP, AA::ValueScope S) {
11081 SmallMapVector<AA::ValueAndContext, int, 8> ValueScopeMap;
11082 for (auto CS : {AA::Intraprocedural, AA::Interprocedural}) {
11083 if (!(CS & S))
11084 continue;
11085
11086 bool UsedAssumedInformation = false;
11088 if (!A.getAssumedSimplifiedValues(IRP, this, Values, CS,
11089 UsedAssumedInformation))
11090 return false;
11091
11092 for (auto &It : Values)
11093 ValueScopeMap[It] += CS;
11094 }
11095 for (auto &It : ValueScopeMap)
11096 addValue(A, getState(), *It.first.getValue(), It.first.getCtxI(),
11097 AA::ValueScope(It.second), getAnchorScope());
11098
11099 return true;
11100 }
11101
11102 void giveUpOnIntraprocedural(Attributor &A) {
11103 auto NewS = StateType::getBestState(getState());
11104 for (const auto &It : getAssumedSet()) {
11105 if (It.second == AA::Intraprocedural)
11106 continue;
11107 addValue(A, NewS, *It.first.getValue(), It.first.getCtxI(),
11108 AA::Interprocedural, getAnchorScope());
11109 }
11110 assert(!undefIsContained() && "Undef should be an explicit value!");
11111 addValue(A, NewS, getAssociatedValue(), getCtxI(), AA::Intraprocedural,
11112 getAnchorScope());
11113 getState() = NewS;
11114 }
11115
11116 /// See AbstractState::indicatePessimisticFixpoint(...).
11117 ChangeStatus indicatePessimisticFixpoint() override {
11118 getState() = StateType::getBestState(getState());
11119 getState().unionAssumed({{getAssociatedValue(), getCtxI()}, AA::AnyScope});
11120 AAPotentialValues::indicateOptimisticFixpoint();
11121 return ChangeStatus::CHANGED;
11122 }
11123
11124 /// See AbstractAttribute::updateImpl(...).
11125 ChangeStatus updateImpl(Attributor &A) override {
11126 return indicatePessimisticFixpoint();
11127 }
11128
11129 /// See AbstractAttribute::manifest(...).
11130 ChangeStatus manifest(Attributor &A) override {
11133 Values.clear();
11134 if (!getAssumedSimplifiedValues(A, Values, S))
11135 continue;
11136 Value &OldV = getAssociatedValue();
11137 if (isa<UndefValue>(OldV))
11138 continue;
11139 Value *NewV = getSingleValue(A, *this, getIRPosition(), Values);
11140 if (!NewV || NewV == &OldV)
11141 continue;
11142 if (getCtxI() &&
11143 !AA::isValidAtPosition({*NewV, *getCtxI()}, A.getInfoCache()))
11144 continue;
11145 if (A.changeAfterManifest(getIRPosition(), *NewV))
11146 return ChangeStatus::CHANGED;
11147 }
11148 return ChangeStatus::UNCHANGED;
11149 }
11150
11151 bool getAssumedSimplifiedValues(
11152 Attributor &A, SmallVectorImpl<AA::ValueAndContext> &Values,
11153 AA::ValueScope S, bool RecurseForSelectAndPHI = false) const override {
11154 if (!isValidState())
11155 return false;
11156 bool UsedAssumedInformation = false;
11157 for (const auto &It : getAssumedSet())
11158 if (It.second & S) {
11159 if (RecurseForSelectAndPHI && (isa<PHINode>(It.first.getValue()) ||
11160 isa<SelectInst>(It.first.getValue()))) {
11161 if (A.getAssumedSimplifiedValues(
11162 IRPosition::inst(*cast<Instruction>(It.first.getValue())),
11163 this, Values, S, UsedAssumedInformation))
11164 continue;
11165 }
11166 Values.push_back(It.first);
11167 }
11168 assert(!undefIsContained() && "Undef should be an explicit value!");
11169 return true;
11170 }
11171};
11172
11173struct AAPotentialValuesFloating : AAPotentialValuesImpl {
11174 AAPotentialValuesFloating(const IRPosition &IRP, Attributor &A)
11175 : AAPotentialValuesImpl(IRP, A) {}
11176
11177 /// See AbstractAttribute::updateImpl(...).
11178 ChangeStatus updateImpl(Attributor &A) override {
11179 auto AssumedBefore = getAssumed();
11180
11181 genericValueTraversal(A, &getAssociatedValue());
11182
11183 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
11184 : ChangeStatus::CHANGED;
11185 }
11186
11187 /// Helper struct to remember which AAIsDead instances we actually used.
11188 struct LivenessInfo {
11189 const AAIsDead *LivenessAA = nullptr;
11190 bool AnyDead = false;
11191 };
11192
11193 /// Check if \p Cmp is a comparison we can simplify.
11194 ///
11195 /// We handle multiple cases, one in which at least one operand is an
11196 /// (assumed) nullptr. If so, try to simplify it using AANonNull on the other
11197 /// operand. Return true if successful, in that case Worklist will be updated.
11198 bool handleCmp(Attributor &A, Value &Cmp, Value *LHS, Value *RHS,
11199 CmpInst::Predicate Pred, ItemInfo II,
11200 SmallVectorImpl<ItemInfo> &Worklist) {
11201
11202 // Simplify the operands first.
11203 bool UsedAssumedInformation = false;
11204 SmallVector<AA::ValueAndContext> LHSValues, RHSValues;
11205 auto GetSimplifiedValues = [&](Value &V,
11207 if (!A.getAssumedSimplifiedValues(
11208 IRPosition::value(V, getCallBaseContext()), this, Values,
11209 AA::Intraprocedural, UsedAssumedInformation)) {
11210 Values.clear();
11211 Values.push_back(AA::ValueAndContext{V, II.I.getCtxI()});
11212 }
11213 return Values.empty();
11214 };
11215 if (GetSimplifiedValues(*LHS, LHSValues))
11216 return true;
11217 if (GetSimplifiedValues(*RHS, RHSValues))
11218 return true;
11219
11220 LLVMContext &Ctx = LHS->getContext();
11221
11222 InformationCache &InfoCache = A.getInfoCache();
11223 Instruction *CmpI = dyn_cast<Instruction>(&Cmp);
11224 Function *F = CmpI ? CmpI->getFunction() : nullptr;
11225 const auto *DT =
11226 F ? InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F)
11227 : nullptr;
11228 const auto *TLI =
11229 F ? A.getInfoCache().getTargetLibraryInfoForFunction(*F) : nullptr;
11230 auto *AC =
11231 F ? InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F)
11232 : nullptr;
11233
11234 const DataLayout &DL = A.getDataLayout();
11235 SimplifyQuery Q(DL, TLI, DT, AC, CmpI);
11236
11237 auto CheckPair = [&](Value &LHSV, Value &RHSV) {
11238 if (isa<UndefValue>(LHSV) || isa<UndefValue>(RHSV)) {
11239 addValue(A, getState(), *UndefValue::get(Cmp.getType()),
11240 /* CtxI */ nullptr, II.S, getAnchorScope());
11241 return true;
11242 }
11243
11244 // Handle the trivial case first in which we don't even need to think
11245 // about null or non-null.
11246 if (&LHSV == &RHSV &&
11248 Constant *NewV = ConstantInt::get(Type::getInt1Ty(Ctx),
11250 addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S,
11251 getAnchorScope());
11252 return true;
11253 }
11254
11255 auto *TypedLHS = AA::getWithType(LHSV, *LHS->getType());
11256 auto *TypedRHS = AA::getWithType(RHSV, *RHS->getType());
11257 if (TypedLHS && TypedRHS) {
11258 Value *NewV = simplifyCmpInst(Pred, TypedLHS, TypedRHS, Q);
11259 if (NewV && NewV != &Cmp) {
11260 addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S,
11261 getAnchorScope());
11262 return true;
11263 }
11264 }
11265
11266 // From now on we only handle equalities (==, !=).
11267 if (!CmpInst::isEquality(Pred))
11268 return false;
11269
11270 bool LHSIsNull = isa<ConstantPointerNull>(LHSV);
11271 bool RHSIsNull = isa<ConstantPointerNull>(RHSV);
11272 if (!LHSIsNull && !RHSIsNull)
11273 return false;
11274
11275 // Left is the nullptr ==/!= non-nullptr case. We'll use AANonNull on the
11276 // non-nullptr operand and if we assume it's non-null we can conclude the
11277 // result of the comparison.
11278 assert((LHSIsNull || RHSIsNull) &&
11279 "Expected nullptr versus non-nullptr comparison at this point");
11280
11281 // The index is the operand that we assume is not null.
11282 unsigned PtrIdx = LHSIsNull;
11283 bool IsKnownNonNull;
11284 bool IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>(
11285 A, this, IRPosition::value(*(PtrIdx ? &RHSV : &LHSV)),
11286 DepClassTy::REQUIRED, IsKnownNonNull);
11287 if (!IsAssumedNonNull)
11288 return false;
11289
11290 // The new value depends on the predicate, true for != and false for ==.
11291 Constant *NewV =
11292 ConstantInt::get(Type::getInt1Ty(Ctx), Pred == CmpInst::ICMP_NE);
11293 addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S,
11294 getAnchorScope());
11295 return true;
11296 };
11297
11298 for (auto &LHSValue : LHSValues)
11299 for (auto &RHSValue : RHSValues)
11300 if (!CheckPair(*LHSValue.getValue(), *RHSValue.getValue()))
11301 return false;
11302 return true;
11303 }
11304
11305 bool handleSelectInst(Attributor &A, SelectInst &SI, ItemInfo II,
11306 SmallVectorImpl<ItemInfo> &Worklist) {
11307 const Instruction *CtxI = II.I.getCtxI();
11308 bool UsedAssumedInformation = false;
11309
11310 std::optional<Constant *> C =
11311 A.getAssumedConstant(*SI.getCondition(), *this, UsedAssumedInformation);
11312 bool NoValueYet = !C.has_value();
11313 if (NoValueYet || isa_and_nonnull<UndefValue>(*C))
11314 return true;
11315 if (auto *CI = dyn_cast_or_null<ConstantInt>(*C)) {
11316 if (CI->isZero())
11317 Worklist.push_back({{*SI.getFalseValue(), CtxI}, II.S});
11318 else
11319 Worklist.push_back({{*SI.getTrueValue(), CtxI}, II.S});
11320 } else if (&SI == &getAssociatedValue()) {
11321 // We could not simplify the condition, assume both values.
11322 Worklist.push_back({{*SI.getTrueValue(), CtxI}, II.S});
11323 Worklist.push_back({{*SI.getFalseValue(), CtxI}, II.S});
11324 } else {
11325 std::optional<Value *> SimpleV = A.getAssumedSimplified(
11326 IRPosition::inst(SI), *this, UsedAssumedInformation, II.S);
11327 if (!SimpleV.has_value())
11328 return true;
11329 if (*SimpleV) {
11330 addValue(A, getState(), **SimpleV, CtxI, II.S, getAnchorScope());
11331 return true;
11332 }
11333 return false;
11334 }
11335 return true;
11336 }
11337
11338 bool handleLoadInst(Attributor &A, LoadInst &LI, ItemInfo II,
11339 SmallVectorImpl<ItemInfo> &Worklist) {
11340 SmallSetVector<Value *, 4> PotentialCopies;
11341 SmallSetVector<Instruction *, 4> PotentialValueOrigins;
11342 bool UsedAssumedInformation = false;
11343 if (!AA::getPotentiallyLoadedValues(A, LI, PotentialCopies,
11344 PotentialValueOrigins, *this,
11345 UsedAssumedInformation,
11346 /* OnlyExact */ true)) {
11347 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Failed to get potentially "
11348 "loaded values for load instruction "
11349 << LI << "\n");
11350 return false;
11351 }
11352
11353 // Do not simplify loads that are only used in llvm.assume if we cannot also
11354 // remove all stores that may feed into the load. The reason is that the
11355 // assume is probably worth something as long as the stores are around.
11356 InformationCache &InfoCache = A.getInfoCache();
11357 if (InfoCache.isOnlyUsedByAssume(LI)) {
11358 if (!llvm::all_of(PotentialValueOrigins, [&](Instruction *I) {
11359 if (!I || isa<AssumeInst>(I))
11360 return true;
11361 if (auto *SI = dyn_cast<StoreInst>(I))
11362 return A.isAssumedDead(SI->getOperandUse(0), this,
11363 /* LivenessAA */ nullptr,
11364 UsedAssumedInformation,
11365 /* CheckBBLivenessOnly */ false);
11366 return A.isAssumedDead(*I, this, /* LivenessAA */ nullptr,
11367 UsedAssumedInformation,
11368 /* CheckBBLivenessOnly */ false);
11369 })) {
11370 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Load is onl used by assumes "
11371 "and we cannot delete all the stores: "
11372 << LI << "\n");
11373 return false;
11374 }
11375 }
11376
11377 // Values have to be dynamically unique or we loose the fact that a
11378 // single llvm::Value might represent two runtime values (e.g.,
11379 // stack locations in different recursive calls).
11380 const Instruction *CtxI = II.I.getCtxI();
11381 bool ScopeIsLocal = (II.S & AA::Intraprocedural);
11382 bool AllLocal = ScopeIsLocal;
11383 bool DynamicallyUnique = llvm::all_of(PotentialCopies, [&](Value *PC) {
11384 AllLocal &= AA::isValidInScope(*PC, getAnchorScope());
11385 return AA::isDynamicallyUnique(A, *this, *PC);
11386 });
11387 if (!DynamicallyUnique) {
11388 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Not all potentially loaded "
11389 "values are dynamically unique: "
11390 << LI << "\n");
11391 return false;
11392 }
11393
11394 for (auto *PotentialCopy : PotentialCopies) {
11395 if (AllLocal) {
11396 Worklist.push_back({{*PotentialCopy, CtxI}, II.S});
11397 } else {
11398 Worklist.push_back({{*PotentialCopy, CtxI}, AA::Interprocedural});
11399 }
11400 }
11401 if (!AllLocal && ScopeIsLocal)
11402 addValue(A, getState(), LI, CtxI, AA::Intraprocedural, getAnchorScope());
11403 return true;
11404 }
11405
11406 bool handlePHINode(
11407 Attributor &A, PHINode &PHI, ItemInfo II,
11408 SmallVectorImpl<ItemInfo> &Worklist,
11409 SmallMapVector<const Function *, LivenessInfo, 4> &LivenessAAs) {
11410 auto GetLivenessInfo = [&](const Function &F) -> LivenessInfo & {
11411 LivenessInfo &LI = LivenessAAs[&F];
11412 if (!LI.LivenessAA)
11413 LI.LivenessAA = A.getAAFor<AAIsDead>(*this, IRPosition::function(F),
11414 DepClassTy::NONE);
11415 return LI;
11416 };
11417
11418 if (&PHI == &getAssociatedValue()) {
11419 LivenessInfo &LI = GetLivenessInfo(*PHI.getFunction());
11420 const auto *CI =
11421 A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>(
11422 *PHI.getFunction());
11423
11424 Cycle *C = nullptr;
11425 bool CyclePHI = mayBeInCycle(CI, &PHI, /* HeaderOnly */ true, &C);
11426 for (unsigned u = 0, e = PHI.getNumIncomingValues(); u < e; u++) {
11427 BasicBlock *IncomingBB = PHI.getIncomingBlock(u);
11428 if (LI.LivenessAA &&
11429 LI.LivenessAA->isEdgeDead(IncomingBB, PHI.getParent())) {
11430 LI.AnyDead = true;
11431 continue;
11432 }
11433 Value *V = PHI.getIncomingValue(u);
11434 if (V == &PHI)
11435 continue;
11436
11437 // If the incoming value is not the PHI but an instruction in the same
11438 // cycle we might have multiple versions of it flying around.
11439 if (CyclePHI && isa<Instruction>(V) &&
11440 (!C || C->contains(cast<Instruction>(V)->getParent())))
11441 return false;
11442
11443 Worklist.push_back({{*V, IncomingBB->getTerminator()}, II.S});
11444 }
11445 return true;
11446 }
11447
11448 bool UsedAssumedInformation = false;
11449 std::optional<Value *> SimpleV = A.getAssumedSimplified(
11450 IRPosition::inst(PHI), *this, UsedAssumedInformation, II.S);
11451 if (!SimpleV.has_value())
11452 return true;
11453 if (!(*SimpleV))
11454 return false;
11455 addValue(A, getState(), **SimpleV, &PHI, II.S, getAnchorScope());
11456 return true;
11457 }
11458
11459 /// Use the generic, non-optimistic InstSimplfy functionality if we managed to
11460 /// simplify any operand of the instruction \p I. Return true if successful,
11461 /// in that case Worklist will be updated.
11462 bool handleGenericInst(Attributor &A, Instruction &I, ItemInfo II,
11463 SmallVectorImpl<ItemInfo> &Worklist) {
11464 bool SomeSimplified = false;
11465 bool UsedAssumedInformation = false;
11466
11467 SmallVector<Value *, 8> NewOps(I.getNumOperands());
11468 int Idx = 0;
11469 for (Value *Op : I.operands()) {
11470 const auto &SimplifiedOp = A.getAssumedSimplified(
11471 IRPosition::value(*Op, getCallBaseContext()), *this,
11472 UsedAssumedInformation, AA::Intraprocedural);
11473 // If we are not sure about any operand we are not sure about the entire
11474 // instruction, we'll wait.
11475 if (!SimplifiedOp.has_value())
11476 return true;
11477
11478 if (*SimplifiedOp)
11479 NewOps[Idx] = *SimplifiedOp;
11480 else
11481 NewOps[Idx] = Op;
11482
11483 SomeSimplified |= (NewOps[Idx] != Op);
11484 ++Idx;
11485 }
11486
11487 // We won't bother with the InstSimplify interface if we didn't simplify any
11488 // operand ourselves.
11489 if (!SomeSimplified)
11490 return false;
11491
11492 InformationCache &InfoCache = A.getInfoCache();
11493 Function *F = I.getFunction();
11494 const auto *DT =
11495 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F);
11496 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
11497 auto *AC = InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F);
11498
11499 const DataLayout &DL = I.getDataLayout();
11500 SimplifyQuery Q(DL, TLI, DT, AC, &I);
11501 Value *NewV = simplifyInstructionWithOperands(&I, NewOps, Q);
11502 if (!NewV || NewV == &I)
11503 return false;
11504
11505 LLVM_DEBUG(dbgs() << "Generic inst " << I << " assumed simplified to "
11506 << *NewV << "\n");
11507 Worklist.push_back({{*NewV, II.I.getCtxI()}, II.S});
11508 return true;
11509 }
11510
11512 Attributor &A, Instruction &I, ItemInfo II,
11513 SmallVectorImpl<ItemInfo> &Worklist,
11514 SmallMapVector<const Function *, LivenessInfo, 4> &LivenessAAs) {
11515 if (auto *CI = dyn_cast<CmpInst>(&I))
11516 return handleCmp(A, *CI, CI->getOperand(0), CI->getOperand(1),
11517 CI->getPredicate(), II, Worklist);
11518
11519 switch (I.getOpcode()) {
11520 case Instruction::Select:
11521 return handleSelectInst(A, cast<SelectInst>(I), II, Worklist);
11522 case Instruction::PHI:
11523 return handlePHINode(A, cast<PHINode>(I), II, Worklist, LivenessAAs);
11524 case Instruction::Load:
11525 return handleLoadInst(A, cast<LoadInst>(I), II, Worklist);
11526 default:
11527 return handleGenericInst(A, I, II, Worklist);
11528 };
11529 return false;
11530 }
11531
11532 void genericValueTraversal(Attributor &A, Value *InitialV) {
11533 SmallMapVector<const Function *, LivenessInfo, 4> LivenessAAs;
11534
11535 SmallSet<ItemInfo, 16> Visited;
11537 Worklist.push_back({{*InitialV, getCtxI()}, AA::AnyScope});
11538
11539 int Iteration = 0;
11540 do {
11541 ItemInfo II = Worklist.pop_back_val();
11542 Value *V = II.I.getValue();
11543 assert(V);
11544 const Instruction *CtxI = II.I.getCtxI();
11545 AA::ValueScope S = II.S;
11546
11547 // Check if we should process the current value. To prevent endless
11548 // recursion keep a record of the values we followed!
11549 if (!Visited.insert(II).second)
11550 continue;
11551
11552 // Make sure we limit the compile time for complex expressions.
11553 if (Iteration++ >= MaxPotentialValuesIterations) {
11554 LLVM_DEBUG(dbgs() << "Generic value traversal reached iteration limit: "
11555 << Iteration << "!\n");
11556 addValue(A, getState(), *V, CtxI, S, getAnchorScope());
11557 continue;
11558 }
11559
11560 // Explicitly look through calls with a "returned" attribute if we do
11561 // not have a pointer as stripPointerCasts only works on them.
11562 Value *NewV = nullptr;
11563 if (V->getType()->isPointerTy()) {
11564 NewV = AA::getWithType(*V->stripPointerCasts(), *V->getType());
11565 } else {
11566 if (auto *CB = dyn_cast<CallBase>(V))
11567 if (auto *Callee =
11569 for (Argument &Arg : Callee->args())
11570 if (Arg.hasReturnedAttr()) {
11571 NewV = CB->getArgOperand(Arg.getArgNo());
11572 break;
11573 }
11574 }
11575 }
11576 if (NewV && NewV != V) {
11577 Worklist.push_back({{*NewV, CtxI}, S});
11578 continue;
11579 }
11580
11581 if (auto *I = dyn_cast<Instruction>(V)) {
11582 if (simplifyInstruction(A, *I, II, Worklist, LivenessAAs))
11583 continue;
11584 }
11585
11586 if (V != InitialV || isa<Argument>(V))
11587 if (recurseForValue(A, IRPosition::value(*V), II.S))
11588 continue;
11589
11590 // If we haven't stripped anything we give up.
11591 if (V == InitialV && CtxI == getCtxI()) {
11592 indicatePessimisticFixpoint();
11593 return;
11594 }
11595
11596 addValue(A, getState(), *V, CtxI, S, getAnchorScope());
11597 } while (!Worklist.empty());
11598
11599 // If we actually used liveness information so we have to record a
11600 // dependence.
11601 for (auto &It : LivenessAAs)
11602 if (It.second.AnyDead)
11603 A.recordDependence(*It.second.LivenessAA, *this, DepClassTy::OPTIONAL);
11604 }
11605
11606 /// See AbstractAttribute::trackStatistics()
11607 void trackStatistics() const override {
11608 STATS_DECLTRACK_FLOATING_ATTR(potential_values)
11609 }
11610};
11611
11612struct AAPotentialValuesArgument final : AAPotentialValuesImpl {
11613 using Base = AAPotentialValuesImpl;
11614 AAPotentialValuesArgument(const IRPosition &IRP, Attributor &A)
11615 : Base(IRP, A) {}
11616
11617 /// See AbstractAttribute::initialize(..).
11618 void initialize(Attributor &A) override {
11619 auto &Arg = cast<Argument>(getAssociatedValue());
11621 indicatePessimisticFixpoint();
11622 }
11623
11624 /// See AbstractAttribute::updateImpl(...).
11625 ChangeStatus updateImpl(Attributor &A) override {
11626 auto AssumedBefore = getAssumed();
11627
11628 unsigned ArgNo = getCalleeArgNo();
11629
11630 bool UsedAssumedInformation = false;
11632 auto CallSitePred = [&](AbstractCallSite ACS) {
11633 const auto CSArgIRP = IRPosition::callsite_argument(ACS, ArgNo);
11634 if (CSArgIRP.getPositionKind() == IRP_INVALID)
11635 return false;
11636
11637 if (!A.getAssumedSimplifiedValues(CSArgIRP, this, Values,
11639 UsedAssumedInformation))
11640 return false;
11641
11642 return isValidState();
11643 };
11644
11645 if (!A.checkForAllCallSites(CallSitePred, *this,
11646 /* RequireAllCallSites */ true,
11647 UsedAssumedInformation))
11648 return indicatePessimisticFixpoint();
11649
11650 Function *Fn = getAssociatedFunction();
11651 bool AnyNonLocal = false;
11652 for (auto &It : Values) {
11653 if (isa<Constant>(It.getValue())) {
11654 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::AnyScope,
11655 getAnchorScope());
11656 continue;
11657 }
11658 if (!AA::isDynamicallyUnique(A, *this, *It.getValue()))
11659 return indicatePessimisticFixpoint();
11660
11661 if (auto *Arg = dyn_cast<Argument>(It.getValue()))
11662 if (Arg->getParent() == Fn) {
11663 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::AnyScope,
11664 getAnchorScope());
11665 continue;
11666 }
11667 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::Interprocedural,
11668 getAnchorScope());
11669 AnyNonLocal = true;
11670 }
11671 assert(!undefIsContained() && "Undef should be an explicit value!");
11672 if (AnyNonLocal)
11673 giveUpOnIntraprocedural(A);
11674
11675 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
11676 : ChangeStatus::CHANGED;
11677 }
11678
11679 /// See AbstractAttribute::trackStatistics()
11680 void trackStatistics() const override {
11681 STATS_DECLTRACK_ARG_ATTR(potential_values)
11682 }
11683};
11684
11685struct AAPotentialValuesReturned : public AAPotentialValuesFloating {
11686 using Base = AAPotentialValuesFloating;
11687 AAPotentialValuesReturned(const IRPosition &IRP, Attributor &A)
11688 : Base(IRP, A) {}
11689
11690 /// See AbstractAttribute::initialize(..).
11691 void initialize(Attributor &A) override {
11692 Function *F = getAssociatedFunction();
11693 if (!F || F->isDeclaration() || F->getReturnType()->isVoidTy()) {
11694 indicatePessimisticFixpoint();
11695 return;
11696 }
11697
11698 for (Argument &Arg : F->args())
11699 if (Arg.hasReturnedAttr()) {
11700 addValue(A, getState(), Arg, nullptr, AA::AnyScope, F);
11701 ReturnedArg = &Arg;
11702 break;
11703 }
11704 if (!A.isFunctionIPOAmendable(*F) ||
11705 A.hasSimplificationCallback(getIRPosition())) {
11706 if (!ReturnedArg)
11707 indicatePessimisticFixpoint();
11708 else
11709 indicateOptimisticFixpoint();
11710 }
11711 }
11712
11713 /// See AbstractAttribute::updateImpl(...).
11714 ChangeStatus updateImpl(Attributor &A) override {
11715 auto AssumedBefore = getAssumed();
11716 bool UsedAssumedInformation = false;
11717
11719 Function *AnchorScope = getAnchorScope();
11720 auto HandleReturnedValue = [&](Value &V, Instruction *CtxI,
11721 bool AddValues) {
11723 Values.clear();
11724 if (!A.getAssumedSimplifiedValues(IRPosition::value(V), this, Values, S,
11725 UsedAssumedInformation,
11726 /* RecurseForSelectAndPHI */ true))
11727 return false;
11728 if (!AddValues)
11729 continue;
11730
11731 bool AllInterAreIntra = false;
11732 if (S == AA::Interprocedural)
11733 AllInterAreIntra =
11734 llvm::all_of(Values, [&](const AA::ValueAndContext &VAC) {
11735 return AA::isValidInScope(*VAC.getValue(), AnchorScope);
11736 });
11737
11738 for (const AA::ValueAndContext &VAC : Values) {
11739 addValue(A, getState(), *VAC.getValue(),
11740 VAC.getCtxI() ? VAC.getCtxI() : CtxI,
11741 AllInterAreIntra ? AA::AnyScope : S, AnchorScope);
11742 }
11743 if (AllInterAreIntra)
11744 break;
11745 }
11746 return true;
11747 };
11748
11749 if (ReturnedArg) {
11750 HandleReturnedValue(*ReturnedArg, nullptr, true);
11751 } else {
11752 auto RetInstPred = [&](Instruction &RetI) {
11753 bool AddValues = true;
11754 if (isa<PHINode>(RetI.getOperand(0)) ||
11755 isa<SelectInst>(RetI.getOperand(0))) {
11756 addValue(A, getState(), *RetI.getOperand(0), &RetI, AA::AnyScope,
11757 AnchorScope);
11758 AddValues = false;
11759 }
11760 return HandleReturnedValue(*RetI.getOperand(0), &RetI, AddValues);
11761 };
11762
11763 if (!A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret},
11764 UsedAssumedInformation,
11765 /* CheckBBLivenessOnly */ true))
11766 return indicatePessimisticFixpoint();
11767 }
11768
11769 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
11770 : ChangeStatus::CHANGED;
11771 }
11772
11773 ChangeStatus manifest(Attributor &A) override {
11774 if (ReturnedArg)
11775 return ChangeStatus::UNCHANGED;
11777 if (!getAssumedSimplifiedValues(A, Values, AA::ValueScope::Intraprocedural,
11778 /* RecurseForSelectAndPHI */ true))
11779 return ChangeStatus::UNCHANGED;
11780 Value *NewVal = getSingleValue(A, *this, getIRPosition(), Values);
11781 if (!NewVal)
11782 return ChangeStatus::UNCHANGED;
11783
11784 ChangeStatus Changed = ChangeStatus::UNCHANGED;
11785 if (auto *Arg = dyn_cast<Argument>(NewVal)) {
11786 STATS_DECLTRACK(UniqueReturnValue, FunctionReturn,
11787 "Number of function with unique return");
11788 Changed |= A.manifestAttrs(
11790 {Attribute::get(Arg->getContext(), Attribute::Returned)});
11791 STATS_DECLTRACK_ARG_ATTR(returned);
11792 }
11793
11794 auto RetInstPred = [&](Instruction &RetI) {
11795 Value *RetOp = RetI.getOperand(0);
11796 if (isa<UndefValue>(RetOp) || RetOp == NewVal)
11797 return true;
11798 if (AA::isValidAtPosition({*NewVal, RetI}, A.getInfoCache()))
11799 if (A.changeUseAfterManifest(RetI.getOperandUse(0), *NewVal))
11800 Changed = ChangeStatus::CHANGED;
11801 return true;
11802 };
11803 bool UsedAssumedInformation = false;
11804 (void)A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret},
11805 UsedAssumedInformation,
11806 /* CheckBBLivenessOnly */ true);
11807 return Changed;
11808 }
11809
11810 ChangeStatus indicatePessimisticFixpoint() override {
11811 return AAPotentialValues::indicatePessimisticFixpoint();
11812 }
11813
11814 /// See AbstractAttribute::trackStatistics()
11815 void trackStatistics() const override{
11816 STATS_DECLTRACK_FNRET_ATTR(potential_values)}
11817
11818 /// The argumented with an existing `returned` attribute.
11819 Argument *ReturnedArg = nullptr;
11820};
11821
11822struct AAPotentialValuesFunction : AAPotentialValuesImpl {
11823 AAPotentialValuesFunction(const IRPosition &IRP, Attributor &A)
11824 : AAPotentialValuesImpl(IRP, A) {}
11825
11826 /// See AbstractAttribute::updateImpl(...).
11827 ChangeStatus updateImpl(Attributor &A) override {
11828 llvm_unreachable("AAPotentialValues(Function|CallSite)::updateImpl will "
11829 "not be called");
11830 }
11831
11832 /// See AbstractAttribute::trackStatistics()
11833 void trackStatistics() const override {
11834 STATS_DECLTRACK_FN_ATTR(potential_values)
11835 }
11836};
11837
11838struct AAPotentialValuesCallSite : AAPotentialValuesFunction {
11839 AAPotentialValuesCallSite(const IRPosition &IRP, Attributor &A)
11840 : AAPotentialValuesFunction(IRP, A) {}
11841
11842 /// See AbstractAttribute::trackStatistics()
11843 void trackStatistics() const override {
11844 STATS_DECLTRACK_CS_ATTR(potential_values)
11845 }
11846};
11847
11848struct AAPotentialValuesCallSiteReturned : AAPotentialValuesImpl {
11849 AAPotentialValuesCallSiteReturned(const IRPosition &IRP, Attributor &A)
11850 : AAPotentialValuesImpl(IRP, A) {}
11851
11852 /// See AbstractAttribute::updateImpl(...).
11853 ChangeStatus updateImpl(Attributor &A) override {
11854 auto AssumedBefore = getAssumed();
11855
11856 Function *Callee = getAssociatedFunction();
11857 if (!Callee)
11858 return indicatePessimisticFixpoint();
11859
11860 bool UsedAssumedInformation = false;
11861 auto *CB = cast<CallBase>(getCtxI());
11862 if (CB->isMustTailCall() &&
11863 !A.isAssumedDead(IRPosition::inst(*CB), this, nullptr,
11864 UsedAssumedInformation))
11865 return indicatePessimisticFixpoint();
11866
11867 Function *Caller = CB->getCaller();
11868
11869 auto AddScope = [&](AA::ValueScope S) {
11871 if (!A.getAssumedSimplifiedValues(IRPosition::returned(*Callee), this,
11872 Values, S, UsedAssumedInformation))
11873 return false;
11874
11875 for (auto &It : Values) {
11876 Value *V = It.getValue();
11877 std::optional<Value *> CallerV = A.translateArgumentToCallSiteContent(
11878 V, *CB, *this, UsedAssumedInformation);
11879 if (!CallerV.has_value()) {
11880 // Nothing to do as long as no value was determined.
11881 continue;
11882 }
11883 V = *CallerV ? *CallerV : V;
11884 if (*CallerV && AA::isDynamicallyUnique(A, *this, *V)) {
11885 if (recurseForValue(A, IRPosition::value(*V), S))
11886 continue;
11887 }
11888 if (S == AA::Intraprocedural && !AA::isValidInScope(*V, Caller)) {
11889 giveUpOnIntraprocedural(A);
11890 return true;
11891 }
11892 addValue(A, getState(), *V, CB, S, getAnchorScope());
11893 }
11894 return true;
11895 };
11896 if (!AddScope(AA::Intraprocedural))
11897 return indicatePessimisticFixpoint();
11898 if (!AddScope(AA::Interprocedural))
11899 return indicatePessimisticFixpoint();
11900 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
11901 : ChangeStatus::CHANGED;
11902 }
11903
11904 ChangeStatus indicatePessimisticFixpoint() override {
11905 return AAPotentialValues::indicatePessimisticFixpoint();
11906 }
11907
11908 /// See AbstractAttribute::trackStatistics()
11909 void trackStatistics() const override {
11910 STATS_DECLTRACK_CSRET_ATTR(potential_values)
11911 }
11912};
11913
11914struct AAPotentialValuesCallSiteArgument : AAPotentialValuesFloating {
11915 AAPotentialValuesCallSiteArgument(const IRPosition &IRP, Attributor &A)
11916 : AAPotentialValuesFloating(IRP, A) {}
11917
11918 /// See AbstractAttribute::trackStatistics()
11919 void trackStatistics() const override {
11920 STATS_DECLTRACK_CSARG_ATTR(potential_values)
11921 }
11922};
11923} // namespace
11924
11925/// ---------------------- Assumption Propagation ------------------------------
11926namespace {
11927struct AAAssumptionInfoImpl : public AAAssumptionInfo {
11928 AAAssumptionInfoImpl(const IRPosition &IRP, Attributor &A,
11929 const DenseSet<StringRef> &Known)
11930 : AAAssumptionInfo(IRP, A, Known) {}
11931
11932 /// See AbstractAttribute::manifest(...).
11933 ChangeStatus manifest(Attributor &A) override {
11934 // Don't manifest a universal set if it somehow made it here.
11935 if (getKnown().isUniversal())
11936 return ChangeStatus::UNCHANGED;
11937
11938 const IRPosition &IRP = getIRPosition();
11939 SmallVector<StringRef, 0> Set(getAssumed().getSet().begin(),
11940 getAssumed().getSet().end());
11941 llvm::sort(Set);
11942 return A.manifestAttrs(IRP,
11943 Attribute::get(IRP.getAnchorValue().getContext(),
11945 llvm::join(Set, ",")),
11946 /*ForceReplace=*/true);
11947 }
11948
11949 bool hasAssumption(const StringRef Assumption) const override {
11950 return isValidState() && setContains(Assumption);
11951 }
11952
11953 /// See AbstractAttribute::getAsStr()
11954 const std::string getAsStr(Attributor *A) const override {
11955 const SetContents &Known = getKnown();
11956 const SetContents &Assumed = getAssumed();
11957
11958 SmallVector<StringRef, 0> Set(Known.getSet().begin(), Known.getSet().end());
11959 llvm::sort(Set);
11960 const std::string KnownStr = llvm::join(Set, ",");
11961
11962 std::string AssumedStr = "Universal";
11963 if (!Assumed.isUniversal()) {
11964 Set.assign(Assumed.getSet().begin(), Assumed.getSet().end());
11965 AssumedStr = llvm::join(Set, ",");
11966 }
11967 return "Known [" + KnownStr + "]," + " Assumed [" + AssumedStr + "]";
11968 }
11969};
11970
11971/// Propagates assumption information from parent functions to all of their
11972/// successors. An assumption can be propagated if the containing function
11973/// dominates the called function.
11974///
11975/// We start with a "known" set of assumptions already valid for the associated
11976/// function and an "assumed" set that initially contains all possible
11977/// assumptions. The assumed set is inter-procedurally updated by narrowing its
11978/// contents as concrete values are known. The concrete values are seeded by the
11979/// first nodes that are either entries into the call graph, or contains no
11980/// assumptions. Each node is updated as the intersection of the assumed state
11981/// with all of its predecessors.
11982struct AAAssumptionInfoFunction final : AAAssumptionInfoImpl {
11983 AAAssumptionInfoFunction(const IRPosition &IRP, Attributor &A)
11984 : AAAssumptionInfoImpl(IRP, A,
11985 getAssumptions(*IRP.getAssociatedFunction())) {}
11986
11987 /// See AbstractAttribute::updateImpl(...).
11988 ChangeStatus updateImpl(Attributor &A) override {
11989 bool Changed = false;
11990
11991 auto CallSitePred = [&](AbstractCallSite ACS) {
11992 const auto *AssumptionAA = A.getAAFor<AAAssumptionInfo>(
11993 *this, IRPosition::callsite_function(*ACS.getInstruction()),
11994 DepClassTy::REQUIRED);
11995 if (!AssumptionAA)
11996 return false;
11997 // Get the set of assumptions shared by all of this function's callers.
11998 Changed |= getIntersection(AssumptionAA->getAssumed());
11999 return !getAssumed().empty() || !getKnown().empty();
12000 };
12001
12002 bool UsedAssumedInformation = false;
12003 // Get the intersection of all assumptions held by this node's predecessors.
12004 // If we don't know all the call sites then this is either an entry into the
12005 // call graph or an empty node. This node is known to only contain its own
12006 // assumptions and can be propagated to its successors.
12007 if (!A.checkForAllCallSites(CallSitePred, *this, true,
12008 UsedAssumedInformation))
12009 return indicatePessimisticFixpoint();
12010
12011 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
12012 }
12013
12014 void trackStatistics() const override {}
12015};
12016
12017/// Assumption Info defined for call sites.
12018struct AAAssumptionInfoCallSite final : AAAssumptionInfoImpl {
12019
12020 AAAssumptionInfoCallSite(const IRPosition &IRP, Attributor &A)
12021 : AAAssumptionInfoImpl(IRP, A, getInitialAssumptions(IRP)) {}
12022
12023 /// See AbstractAttribute::initialize(...).
12024 void initialize(Attributor &A) override {
12025 const IRPosition &FnPos = IRPosition::function(*getAnchorScope());
12026 A.getAAFor<AAAssumptionInfo>(*this, FnPos, DepClassTy::REQUIRED);
12027 }
12028
12029 /// See AbstractAttribute::updateImpl(...).
12030 ChangeStatus updateImpl(Attributor &A) override {
12031 const IRPosition &FnPos = IRPosition::function(*getAnchorScope());
12032 auto *AssumptionAA =
12033 A.getAAFor<AAAssumptionInfo>(*this, FnPos, DepClassTy::REQUIRED);
12034 if (!AssumptionAA)
12035 return indicatePessimisticFixpoint();
12036 bool Changed = getIntersection(AssumptionAA->getAssumed());
12037 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
12038 }
12039
12040 /// See AbstractAttribute::trackStatistics()
12041 void trackStatistics() const override {}
12042
12043private:
12044 /// Helper to initialized the known set as all the assumptions this call and
12045 /// the callee contain.
12046 DenseSet<StringRef> getInitialAssumptions(const IRPosition &IRP) {
12047 const CallBase &CB = cast<CallBase>(IRP.getAssociatedValue());
12048 auto Assumptions = getAssumptions(CB);
12049 if (const Function *F = CB.getCaller())
12050 set_union(Assumptions, getAssumptions(*F));
12051 if (Function *F = IRP.getAssociatedFunction())
12052 set_union(Assumptions, getAssumptions(*F));
12053 return Assumptions;
12054 }
12055};
12056} // namespace
12057
12059 return static_cast<AACallGraphNode *>(const_cast<AACallEdges *>(
12060 A.getOrCreateAAFor<AACallEdges>(IRPosition::function(**I))));
12061}
12062
12064
12065/// ------------------------ UnderlyingObjects ---------------------------------
12066
12067namespace {
12068struct AAUnderlyingObjectsImpl
12069 : StateWrapper<BooleanState, AAUnderlyingObjects> {
12071 AAUnderlyingObjectsImpl(const IRPosition &IRP, Attributor &A) : BaseTy(IRP) {}
12072
12073 /// See AbstractAttribute::getAsStr().
12074 const std::string getAsStr(Attributor *A) const override {
12075 if (!isValidState())
12076 return "<invalid>";
12077 std::string Str;
12079 OS << "underlying objects: inter " << InterAssumedUnderlyingObjects.size()
12080 << " objects, intra " << IntraAssumedUnderlyingObjects.size()
12081 << " objects.\n";
12082 if (!InterAssumedUnderlyingObjects.empty()) {
12083 OS << "inter objects:\n";
12084 for (auto *Obj : InterAssumedUnderlyingObjects)
12085 OS << *Obj << '\n';
12086 }
12087 if (!IntraAssumedUnderlyingObjects.empty()) {
12088 OS << "intra objects:\n";
12089 for (auto *Obj : IntraAssumedUnderlyingObjects)
12090 OS << *Obj << '\n';
12091 }
12092 return Str;
12093 }
12094
12095 /// See AbstractAttribute::trackStatistics()
12096 void trackStatistics() const override {}
12097
12098 /// See AbstractAttribute::updateImpl(...).
12099 ChangeStatus updateImpl(Attributor &A) override {
12100 auto &Ptr = getAssociatedValue();
12101
12102 bool UsedAssumedInformation = false;
12103 auto DoUpdate = [&](SmallSetVector<Value *, 8> &UnderlyingObjects,
12105 SmallPtrSet<Value *, 8> SeenObjects;
12107
12108 if (!A.getAssumedSimplifiedValues(IRPosition::value(Ptr), *this, Values,
12109 Scope, UsedAssumedInformation))
12110 return UnderlyingObjects.insert(&Ptr);
12111
12112 bool Changed = false;
12113
12114 for (unsigned I = 0; I < Values.size(); ++I) {
12115 auto &VAC = Values[I];
12116 auto *Obj = VAC.getValue();
12117 Value *UO = getUnderlyingObject(Obj);
12118 if (!SeenObjects.insert(UO ? UO : Obj).second)
12119 continue;
12120 if (UO && UO != Obj) {
12121 if (isa<AllocaInst>(UO) || isa<GlobalValue>(UO)) {
12122 Changed |= UnderlyingObjects.insert(UO);
12123 continue;
12124 }
12125
12126 const auto *OtherAA = A.getAAFor<AAUnderlyingObjects>(
12127 *this, IRPosition::value(*UO), DepClassTy::OPTIONAL);
12128 auto Pred = [&](Value &V) {
12129 if (&V == UO)
12130 Changed |= UnderlyingObjects.insert(UO);
12131 else
12132 Values.emplace_back(V, nullptr);
12133 return true;
12134 };
12135
12136 if (!OtherAA || !OtherAA->forallUnderlyingObjects(Pred, Scope))
12138 "The forall call should not return false at this position");
12139 UsedAssumedInformation |= !OtherAA->getState().isAtFixpoint();
12140 continue;
12141 }
12142
12143 if (isa<SelectInst>(Obj)) {
12144 Changed |= handleIndirect(A, *Obj, UnderlyingObjects, Scope,
12145 UsedAssumedInformation);
12146 continue;
12147 }
12148 if (auto *PHI = dyn_cast<PHINode>(Obj)) {
12149 // Explicitly look through PHIs as we do not care about dynamically
12150 // uniqueness.
12151 for (unsigned u = 0, e = PHI->getNumIncomingValues(); u < e; u++) {
12152 Changed |=
12153 handleIndirect(A, *PHI->getIncomingValue(u), UnderlyingObjects,
12154 Scope, UsedAssumedInformation);
12155 }
12156 continue;
12157 }
12158
12159 Changed |= UnderlyingObjects.insert(Obj);
12160 }
12161
12162 return Changed;
12163 };
12164
12165 bool Changed = false;
12166 Changed |= DoUpdate(IntraAssumedUnderlyingObjects, AA::Intraprocedural);
12167 Changed |= DoUpdate(InterAssumedUnderlyingObjects, AA::Interprocedural);
12168 if (!UsedAssumedInformation)
12169 indicateOptimisticFixpoint();
12170 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
12171 }
12172
12173 bool forallUnderlyingObjects(
12174 function_ref<bool(Value &)> Pred,
12175 AA::ValueScope Scope = AA::Interprocedural) const override {
12176 if (!isValidState())
12177 return Pred(getAssociatedValue());
12178
12179 auto &AssumedUnderlyingObjects = Scope == AA::Intraprocedural
12180 ? IntraAssumedUnderlyingObjects
12181 : InterAssumedUnderlyingObjects;
12182 for (Value *Obj : AssumedUnderlyingObjects)
12183 if (!Pred(*Obj))
12184 return false;
12185
12186 return true;
12187 }
12188
12189private:
12190 /// Handle the case where the value is not the actual underlying value, such
12191 /// as a phi node or a select instruction.
12192 bool handleIndirect(Attributor &A, Value &V,
12193 SmallSetVector<Value *, 8> &UnderlyingObjects,
12194 AA::ValueScope Scope, bool &UsedAssumedInformation) {
12195 bool Changed = false;
12196 const auto *AA = A.getAAFor<AAUnderlyingObjects>(
12197 *this, IRPosition::value(V), DepClassTy::OPTIONAL);
12198 auto Pred = [&](Value &V) {
12199 Changed |= UnderlyingObjects.insert(&V);
12200 return true;
12201 };
12202 if (!AA || !AA->forallUnderlyingObjects(Pred, Scope))
12204 "The forall call should not return false at this position");
12205 UsedAssumedInformation |= !AA->getState().isAtFixpoint();
12206 return Changed;
12207 }
12208
12209 /// All the underlying objects collected so far via intra procedural scope.
12210 SmallSetVector<Value *, 8> IntraAssumedUnderlyingObjects;
12211 /// All the underlying objects collected so far via inter procedural scope.
12212 SmallSetVector<Value *, 8> InterAssumedUnderlyingObjects;
12213};
12214
12215struct AAUnderlyingObjectsFloating final : AAUnderlyingObjectsImpl {
12216 AAUnderlyingObjectsFloating(const IRPosition &IRP, Attributor &A)
12217 : AAUnderlyingObjectsImpl(IRP, A) {}
12218};
12219
12220struct AAUnderlyingObjectsArgument final : AAUnderlyingObjectsImpl {
12221 AAUnderlyingObjectsArgument(const IRPosition &IRP, Attributor &A)
12222 : AAUnderlyingObjectsImpl(IRP, A) {}
12223};
12224
12225struct AAUnderlyingObjectsCallSite final : AAUnderlyingObjectsImpl {
12226 AAUnderlyingObjectsCallSite(const IRPosition &IRP, Attributor &A)
12227 : AAUnderlyingObjectsImpl(IRP, A) {}
12228};
12229
12230struct AAUnderlyingObjectsCallSiteArgument final : AAUnderlyingObjectsImpl {
12231 AAUnderlyingObjectsCallSiteArgument(const IRPosition &IRP, Attributor &A)
12232 : AAUnderlyingObjectsImpl(IRP, A) {}
12233};
12234
12235struct AAUnderlyingObjectsReturned final : AAUnderlyingObjectsImpl {
12236 AAUnderlyingObjectsReturned(const IRPosition &IRP, Attributor &A)
12237 : AAUnderlyingObjectsImpl(IRP, A) {}
12238};
12239
12240struct AAUnderlyingObjectsCallSiteReturned final : AAUnderlyingObjectsImpl {
12241 AAUnderlyingObjectsCallSiteReturned(const IRPosition &IRP, Attributor &A)
12242 : AAUnderlyingObjectsImpl(IRP, A) {}
12243};
12244
12245struct AAUnderlyingObjectsFunction final : AAUnderlyingObjectsImpl {
12246 AAUnderlyingObjectsFunction(const IRPosition &IRP, Attributor &A)
12247 : AAUnderlyingObjectsImpl(IRP, A) {}
12248};
12249} // namespace
12250
12251/// ------------------------ Global Value Info -------------------------------
12252namespace {
12253struct AAGlobalValueInfoFloating : public AAGlobalValueInfo {
12254 AAGlobalValueInfoFloating(const IRPosition &IRP, Attributor &A)
12255 : AAGlobalValueInfo(IRP, A) {}
12256
12257 /// See AbstractAttribute::initialize(...).
12258 void initialize(Attributor &A) override {}
12259
12260 bool checkUse(Attributor &A, const Use &U, bool &Follow,
12261 SmallVectorImpl<const Value *> &Worklist) {
12262 Instruction *UInst = dyn_cast<Instruction>(U.getUser());
12263 if (!UInst) {
12264 Follow = true;
12265 return true;
12266 }
12267
12268 LLVM_DEBUG(dbgs() << "[AAGlobalValueInfo] Check use: " << *U.get() << " in "
12269 << *UInst << "\n");
12270
12271 if (auto *Cmp = dyn_cast<ICmpInst>(U.getUser())) {
12272 int Idx = &Cmp->getOperandUse(0) == &U;
12273 if (isa<Constant>(Cmp->getOperand(Idx)))
12274 return true;
12275 return U == &getAnchorValue();
12276 }
12277
12278 // Explicitly catch return instructions.
12279 if (isa<ReturnInst>(UInst)) {
12280 auto CallSitePred = [&](AbstractCallSite ACS) {
12281 Worklist.push_back(ACS.getInstruction());
12282 return true;
12283 };
12284 bool UsedAssumedInformation = false;
12285 // TODO: We should traverse the uses or add a "non-call-site" CB.
12286 if (!A.checkForAllCallSites(CallSitePred, *UInst->getFunction(),
12287 /*RequireAllCallSites=*/true, this,
12288 UsedAssumedInformation))
12289 return false;
12290 return true;
12291 }
12292
12293 // For now we only use special logic for call sites. However, the tracker
12294 // itself knows about a lot of other non-capturing cases already.
12295 auto *CB = dyn_cast<CallBase>(UInst);
12296 if (!CB)
12297 return false;
12298 // Direct calls are OK uses.
12299 if (CB->isCallee(&U))
12300 return true;
12301 // Non-argument uses are scary.
12302 if (!CB->isArgOperand(&U))
12303 return false;
12304 // TODO: Iterate callees.
12305 auto *Fn = dyn_cast<Function>(CB->getCalledOperand());
12306 if (!Fn || !A.isFunctionIPOAmendable(*Fn))
12307 return false;
12308
12309 unsigned ArgNo = CB->getArgOperandNo(&U);
12310 Worklist.push_back(Fn->getArg(ArgNo));
12311 return true;
12312 }
12313
12314 ChangeStatus updateImpl(Attributor &A) override {
12315 unsigned NumUsesBefore = Uses.size();
12316
12317 SmallPtrSet<const Value *, 8> Visited;
12319 Worklist.push_back(&getAnchorValue());
12320
12321 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
12322 Uses.insert(&U);
12323 // TODO(captures): Make this more precise.
12324 UseCaptureInfo CI = DetermineUseCaptureKind(U, /*Base=*/nullptr);
12325 if (CI.isPassthrough()) {
12326 Follow = true;
12327 return true;
12328 }
12329 return checkUse(A, U, Follow, Worklist);
12330 };
12331 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) {
12332 Uses.insert(&OldU);
12333 return true;
12334 };
12335
12336 while (!Worklist.empty()) {
12337 const Value *V = Worklist.pop_back_val();
12338 if (!Visited.insert(V).second)
12339 continue;
12340 if (!A.checkForAllUses(UsePred, *this, *V,
12341 /* CheckBBLivenessOnly */ true,
12342 DepClassTy::OPTIONAL,
12343 /* IgnoreDroppableUses */ true, EquivalentUseCB)) {
12344 return indicatePessimisticFixpoint();
12345 }
12346 }
12347
12348 return Uses.size() == NumUsesBefore ? ChangeStatus::UNCHANGED
12349 : ChangeStatus::CHANGED;
12350 }
12351
12352 bool isPotentialUse(const Use &U) const override {
12353 return !isValidState() || Uses.contains(&U);
12354 }
12355
12356 /// See AbstractAttribute::manifest(...).
12357 ChangeStatus manifest(Attributor &A) override {
12358 return ChangeStatus::UNCHANGED;
12359 }
12360
12361 /// See AbstractAttribute::getAsStr().
12362 const std::string getAsStr(Attributor *A) const override {
12363 return "[" + std::to_string(Uses.size()) + " uses]";
12364 }
12365
12366 void trackStatistics() const override {
12367 STATS_DECLTRACK_FLOATING_ATTR(GlobalValuesTracked);
12368 }
12369
12370private:
12371 /// Set of (transitive) uses of this GlobalValue.
12372 SmallPtrSet<const Use *, 8> Uses;
12373};
12374} // namespace
12375
12376/// ------------------------ Indirect Call Info -------------------------------
12377namespace {
12378struct AAIndirectCallInfoCallSite : public AAIndirectCallInfo {
12379 AAIndirectCallInfoCallSite(const IRPosition &IRP, Attributor &A)
12380 : AAIndirectCallInfo(IRP, A) {}
12381
12382 /// See AbstractAttribute::initialize(...).
12383 void initialize(Attributor &A) override {
12384 auto *MD = getCtxI()->getMetadata(LLVMContext::MD_callees);
12385 if (!MD && !A.isClosedWorldModule())
12386 return;
12387
12388 if (MD) {
12389 for (const auto &Op : MD->operands())
12390 if (Function *Callee = mdconst::dyn_extract_or_null<Function>(Op))
12391 PotentialCallees.insert(Callee);
12392 } else if (A.isClosedWorldModule()) {
12393 ArrayRef<Function *> IndirectlyCallableFunctions =
12394 A.getInfoCache().getIndirectlyCallableFunctions(A);
12395 PotentialCallees.insert_range(IndirectlyCallableFunctions);
12396 }
12397
12398 if (PotentialCallees.empty())
12399 indicateOptimisticFixpoint();
12400 }
12401
12402 ChangeStatus updateImpl(Attributor &A) override {
12403 CallBase *CB = cast<CallBase>(getCtxI());
12404 const Use &CalleeUse = CB->getCalledOperandUse();
12405 Value *FP = CB->getCalledOperand();
12406
12407 SmallSetVector<Function *, 4> AssumedCalleesNow;
12408 bool AllCalleesKnownNow = AllCalleesKnown;
12409
12410 auto CheckPotentialCalleeUse = [&](Function &PotentialCallee,
12411 bool &UsedAssumedInformation) {
12412 const auto *GIAA = A.getAAFor<AAGlobalValueInfo>(
12413 *this, IRPosition::value(PotentialCallee), DepClassTy::OPTIONAL);
12414 if (!GIAA || GIAA->isPotentialUse(CalleeUse))
12415 return true;
12416 UsedAssumedInformation = !GIAA->isAtFixpoint();
12417 return false;
12418 };
12419
12420 auto AddPotentialCallees = [&]() {
12421 for (auto *PotentialCallee : PotentialCallees) {
12422 bool UsedAssumedInformation = false;
12423 if (CheckPotentialCalleeUse(*PotentialCallee, UsedAssumedInformation))
12424 AssumedCalleesNow.insert(PotentialCallee);
12425 }
12426 };
12427
12428 // Use simplification to find potential callees, if !callees was present,
12429 // fallback to that set if necessary.
12430 bool UsedAssumedInformation = false;
12432 if (!A.getAssumedSimplifiedValues(IRPosition::value(*FP), this, Values,
12433 AA::ValueScope::AnyScope,
12434 UsedAssumedInformation)) {
12435 if (PotentialCallees.empty())
12436 return indicatePessimisticFixpoint();
12437 AddPotentialCallees();
12438 }
12439
12440 // Try to find a reason for \p Fn not to be a potential callee. If none was
12441 // found, add it to the assumed callees set.
12442 auto CheckPotentialCallee = [&](Function &Fn) {
12443 if (!PotentialCallees.empty() && !PotentialCallees.count(&Fn))
12444 return false;
12445
12446 auto &CachedResult = FilterResults[&Fn];
12447 if (CachedResult.has_value())
12448 return CachedResult.value();
12449
12450 bool UsedAssumedInformation = false;
12451 if (!CheckPotentialCalleeUse(Fn, UsedAssumedInformation)) {
12452 if (!UsedAssumedInformation)
12453 CachedResult = false;
12454 return false;
12455 }
12456
12457 int NumFnArgs = Fn.arg_size();
12458 int NumCBArgs = CB->arg_size();
12459
12460 // Check if any excess argument (which we fill up with poison) is known to
12461 // be UB on undef.
12462 for (int I = NumCBArgs; I < NumFnArgs; ++I) {
12463 bool IsKnown = false;
12465 A, this, IRPosition::argument(*Fn.getArg(I)),
12466 DepClassTy::OPTIONAL, IsKnown)) {
12467 if (IsKnown)
12468 CachedResult = false;
12469 return false;
12470 }
12471 }
12472
12473 CachedResult = true;
12474 return true;
12475 };
12476
12477 // Check simplification result, prune known UB callees, also restrict it to
12478 // the !callees set, if present.
12479 for (auto &VAC : Values) {
12480 if (isa<UndefValue>(VAC.getValue()))
12481 continue;
12483 VAC.getValue()->getType()->getPointerAddressSpace() == 0)
12484 continue;
12485 // TODO: Check for known UB, e.g., poison + noundef.
12486 if (auto *VACFn = dyn_cast<Function>(VAC.getValue())) {
12487 if (CheckPotentialCallee(*VACFn))
12488 AssumedCalleesNow.insert(VACFn);
12489 continue;
12490 }
12491 if (!PotentialCallees.empty()) {
12492 AddPotentialCallees();
12493 break;
12494 }
12495 AllCalleesKnownNow = false;
12496 }
12497
12498 if (AssumedCalleesNow == AssumedCallees &&
12499 AllCalleesKnown == AllCalleesKnownNow)
12500 return ChangeStatus::UNCHANGED;
12501
12502 std::swap(AssumedCallees, AssumedCalleesNow);
12503 AllCalleesKnown = AllCalleesKnownNow;
12504 return ChangeStatus::CHANGED;
12505 }
12506
12507 /// See AbstractAttribute::manifest(...).
12508 ChangeStatus manifest(Attributor &A) override {
12509 // If we can't specialize at all, give up now.
12510 if (!AllCalleesKnown && AssumedCallees.empty())
12511 return ChangeStatus::UNCHANGED;
12512
12513 CallBase *CB = cast<CallBase>(getCtxI());
12514 bool UsedAssumedInformation = false;
12515 if (A.isAssumedDead(*CB, this, /*LivenessAA=*/nullptr,
12516 UsedAssumedInformation))
12517 return ChangeStatus::UNCHANGED;
12518
12519 ChangeStatus Changed = ChangeStatus::UNCHANGED;
12520 Value *FP = CB->getCalledOperand();
12521 if (FP->getType()->getPointerAddressSpace())
12522 FP = new AddrSpaceCastInst(FP, PointerType::get(FP->getContext(), 0),
12523 FP->getName() + ".as0", CB->getIterator());
12524
12525 bool CBIsVoid = CB->getType()->isVoidTy();
12527 FunctionType *CSFT = CB->getFunctionType();
12528 SmallVector<Value *> CSArgs(CB->args());
12529
12530 // If we know all callees and there are none, the call site is (effectively)
12531 // dead (or UB).
12532 if (AssumedCallees.empty()) {
12533 assert(AllCalleesKnown &&
12534 "Expected all callees to be known if there are none.");
12535 A.changeToUnreachableAfterManifest(CB);
12536 return ChangeStatus::CHANGED;
12537 }
12538
12539 // Special handling for the single callee case.
12540 if (AllCalleesKnown && AssumedCallees.size() == 1) {
12541 auto *NewCallee = AssumedCallees.front();
12542 if (isLegalToPromote(*CB, NewCallee)) {
12543 promoteCall(*CB, NewCallee, nullptr);
12544 NumIndirectCallsPromoted++;
12545 return ChangeStatus::CHANGED;
12546 }
12547 Instruction *NewCall =
12548 CallInst::Create(FunctionCallee(CSFT, NewCallee), CSArgs,
12549 CB->getName(), CB->getIterator());
12550 if (!CBIsVoid)
12551 A.changeAfterManifest(IRPosition::callsite_returned(*CB), *NewCall);
12552 A.deleteAfterManifest(*CB);
12553 return ChangeStatus::CHANGED;
12554 }
12555
12556 // For each potential value we create a conditional
12557 //
12558 // ```
12559 // if (ptr == value) value(args);
12560 // else ...
12561 // ```
12562 //
12563 bool SpecializedForAnyCallees = false;
12564 bool SpecializedForAllCallees = AllCalleesKnown;
12565 ICmpInst *LastCmp = nullptr;
12566 SmallVector<Function *, 8> SkippedAssumedCallees;
12568 for (Function *NewCallee : AssumedCallees) {
12569 if (!A.shouldSpecializeCallSiteForCallee(*this, *CB, *NewCallee,
12570 AssumedCallees.size())) {
12571 SkippedAssumedCallees.push_back(NewCallee);
12572 SpecializedForAllCallees = false;
12573 continue;
12574 }
12575 SpecializedForAnyCallees = true;
12576
12577 LastCmp = new ICmpInst(IP, llvm::CmpInst::ICMP_EQ, FP, NewCallee);
12578 Instruction *ThenTI =
12579 SplitBlockAndInsertIfThen(LastCmp, IP, /* Unreachable */ false);
12580 BasicBlock *CBBB = CB->getParent();
12581 A.registerManifestAddedBasicBlock(*ThenTI->getParent());
12582 A.registerManifestAddedBasicBlock(*IP->getParent());
12583 auto *SplitTI = cast<CondBrInst>(LastCmp->getNextNode());
12584 BasicBlock *ElseBB;
12585 if (&*IP == CB) {
12586 ElseBB = BasicBlock::Create(ThenTI->getContext(), "",
12587 ThenTI->getFunction(), CBBB);
12588 A.registerManifestAddedBasicBlock(*ElseBB);
12589 IP = UncondBrInst::Create(CBBB, ElseBB)->getIterator();
12590 SplitTI->replaceUsesOfWith(CBBB, ElseBB);
12591 } else {
12592 ElseBB = IP->getParent();
12593 ThenTI->replaceUsesOfWith(ElseBB, CBBB);
12594 }
12595 CastInst *RetBC = nullptr;
12596 CallInst *NewCall = nullptr;
12597 if (isLegalToPromote(*CB, NewCallee)) {
12598 auto *CBClone = cast<CallBase>(CB->clone());
12599 CBClone->insertBefore(ThenTI->getIterator());
12600 NewCall = &cast<CallInst>(promoteCall(*CBClone, NewCallee, &RetBC));
12601 NumIndirectCallsPromoted++;
12602 } else {
12603 NewCall = CallInst::Create(FunctionCallee(CSFT, NewCallee), CSArgs,
12604 CB->getName(), ThenTI->getIterator());
12605 }
12606 NewCalls.push_back({NewCall, RetBC});
12607 }
12608
12609 auto AttachCalleeMetadata = [&](CallBase &IndirectCB) {
12610 if (!AllCalleesKnown)
12611 return ChangeStatus::UNCHANGED;
12612 MDBuilder MDB(IndirectCB.getContext());
12613 MDNode *Callees = MDB.createCallees(SkippedAssumedCallees);
12614 IndirectCB.setMetadata(LLVMContext::MD_callees, Callees);
12615 return ChangeStatus::CHANGED;
12616 };
12617
12618 if (!SpecializedForAnyCallees)
12619 return AttachCalleeMetadata(*CB);
12620
12621 // Check if we need the fallback indirect call still.
12622 if (SpecializedForAllCallees) {
12624 LastCmp->eraseFromParent();
12625 new UnreachableInst(IP->getContext(), IP);
12626 IP->eraseFromParent();
12627 } else {
12628 auto *CBClone = cast<CallInst>(CB->clone());
12629 CBClone->setName(CB->getName());
12630 CBClone->insertBefore(*IP->getParent(), IP);
12631 NewCalls.push_back({CBClone, nullptr});
12632 AttachCalleeMetadata(*CBClone);
12633 }
12634
12635 // Check if we need a PHI to merge the results.
12636 if (!CBIsVoid) {
12637 auto *PHI = PHINode::Create(CB->getType(), NewCalls.size(),
12638 CB->getName() + ".phi",
12639 CB->getParent()->getFirstInsertionPt());
12640 for (auto &It : NewCalls) {
12641 CallBase *NewCall = It.first;
12642 Instruction *CallRet = It.second ? It.second : It.first;
12643 if (CallRet->getType() == CB->getType())
12644 PHI->addIncoming(CallRet, CallRet->getParent());
12645 else if (NewCall->getType()->isVoidTy())
12646 PHI->addIncoming(PoisonValue::get(CB->getType()),
12647 NewCall->getParent());
12648 else
12649 llvm_unreachable("Call return should match or be void!");
12650 }
12651 A.changeAfterManifest(IRPosition::callsite_returned(*CB), *PHI);
12652 }
12653
12654 A.deleteAfterManifest(*CB);
12655 Changed = ChangeStatus::CHANGED;
12656
12657 return Changed;
12658 }
12659
12660 /// See AbstractAttribute::getAsStr().
12661 const std::string getAsStr(Attributor *A) const override {
12662 return std::string(AllCalleesKnown ? "eliminate" : "specialize") +
12663 " indirect call site with " + std::to_string(AssumedCallees.size()) +
12664 " functions";
12665 }
12666
12667 void trackStatistics() const override {
12668 if (AllCalleesKnown) {
12670 Eliminated, CallSites,
12671 "Number of indirect call sites eliminated via specialization")
12672 } else {
12673 STATS_DECLTRACK(Specialized, CallSites,
12674 "Number of indirect call sites specialized")
12675 }
12676 }
12677
12678 bool foreachCallee(function_ref<bool(Function *)> CB) const override {
12679 return isValidState() && AllCalleesKnown && all_of(AssumedCallees, CB);
12680 }
12681
12682private:
12683 /// Map to remember filter results.
12684 DenseMap<Function *, std::optional<bool>> FilterResults;
12685
12686 /// If the !callee metadata was present, this set will contain all potential
12687 /// callees (superset).
12688 SmallSetVector<Function *, 4> PotentialCallees;
12689
12690 /// This set contains all currently assumed calllees, which might grow over
12691 /// time.
12692 SmallSetVector<Function *, 4> AssumedCallees;
12693
12694 /// Flag to indicate if all possible callees are in the AssumedCallees set or
12695 /// if there could be others.
12696 bool AllCalleesKnown = true;
12697};
12698} // namespace
12699
12700/// --------------------- Invariant Load Pointer -------------------------------
12701namespace {
12702
12703struct AAInvariantLoadPointerImpl
12704 : public StateWrapper<BitIntegerState<uint8_t, 15>,
12705 AAInvariantLoadPointer> {
12706
12707 enum {
12708 // pointer does not alias within the bounds of the function
12709 IS_NOALIAS = 1 << 0,
12710 // pointer is not involved in any effectful instructions within the bounds
12711 // of the function
12712 IS_NOEFFECT = 1 << 1,
12713 // loads are invariant within the bounds of the function
12714 IS_LOCALLY_INVARIANT = 1 << 2,
12715 // memory lifetime is constrained within the bounds of the function
12716 IS_LOCALLY_CONSTRAINED = 1 << 3,
12717
12718 IS_BEST_STATE = IS_NOALIAS | IS_NOEFFECT | IS_LOCALLY_INVARIANT |
12719 IS_LOCALLY_CONSTRAINED,
12720 };
12721 static_assert(getBestState() == IS_BEST_STATE, "Unexpected best state");
12722
12723 using Base =
12724 StateWrapper<BitIntegerState<uint8_t, 15>, AAInvariantLoadPointer>;
12725
12726 // the BitIntegerState is optimistic about IS_NOALIAS and IS_NOEFFECT, but
12727 // pessimistic about IS_KNOWN_INVARIANT
12728 AAInvariantLoadPointerImpl(const IRPosition &IRP, Attributor &A)
12729 : Base(IRP) {}
12730
12731 bool isKnownInvariant() const final {
12732 return isKnownLocallyInvariant() && isKnown(IS_LOCALLY_CONSTRAINED);
12733 }
12734
12735 bool isKnownLocallyInvariant() const final {
12736 if (isKnown(IS_LOCALLY_INVARIANT))
12737 return true;
12738 return isKnown(IS_NOALIAS | IS_NOEFFECT);
12739 }
12740
12741 bool isAssumedInvariant() const final {
12742 return isAssumedLocallyInvariant() && isAssumed(IS_LOCALLY_CONSTRAINED);
12743 }
12744
12745 bool isAssumedLocallyInvariant() const final {
12746 if (isAssumed(IS_LOCALLY_INVARIANT))
12747 return true;
12748 return isAssumed(IS_NOALIAS | IS_NOEFFECT);
12749 }
12750
12751 ChangeStatus updateImpl(Attributor &A) override {
12752 ChangeStatus Changed = ChangeStatus::UNCHANGED;
12753
12754 Changed |= updateNoAlias(A);
12755 if (requiresNoAlias() && !isAssumed(IS_NOALIAS))
12756 return indicatePessimisticFixpoint();
12757
12758 Changed |= updateNoEffect(A);
12759
12760 Changed |= updateLocalInvariance(A);
12761
12762 return Changed;
12763 }
12764
12765 ChangeStatus manifest(Attributor &A) override {
12766 if (!isKnownInvariant())
12767 return ChangeStatus::UNCHANGED;
12768
12769 ChangeStatus Changed = ChangeStatus::UNCHANGED;
12770 const Value *Ptr = &getAssociatedValue();
12771 const auto TagInvariantLoads = [&](const Use &U, bool &) {
12772 if (U.get() != Ptr)
12773 return true;
12774 auto *I = dyn_cast<Instruction>(U.getUser());
12775 if (!I)
12776 return true;
12777
12778 // Ensure that we are only changing uses from the corresponding callgraph
12779 // SSC in the case that the AA isn't run on the entire module
12780 if (!A.isRunOn(I->getFunction()))
12781 return true;
12782
12783 if (I->hasMetadata(LLVMContext::MD_invariant_load))
12784 return true;
12785
12786 if (auto *LI = dyn_cast<LoadInst>(I)) {
12787 LI->setMetadata(LLVMContext::MD_invariant_load,
12788 MDNode::get(LI->getContext(), {}));
12789 Changed = ChangeStatus::CHANGED;
12790 }
12791 return true;
12792 };
12793
12794 (void)A.checkForAllUses(TagInvariantLoads, *this, *Ptr);
12795 return Changed;
12796 }
12797
12798 /// See AbstractAttribute::getAsStr().
12799 const std::string getAsStr(Attributor *) const override {
12800 if (isKnownInvariant())
12801 return "load-invariant pointer";
12802 return "non-invariant pointer";
12803 }
12804
12805 /// See AbstractAttribute::trackStatistics().
12806 void trackStatistics() const override {}
12807
12808private:
12809 /// Indicate that noalias is required for the pointer to be invariant.
12810 bool requiresNoAlias() const {
12811 switch (getPositionKind()) {
12812 default:
12813 // Conservatively default to require noalias.
12814 return true;
12815 case IRP_FLOAT:
12816 case IRP_RETURNED:
12817 case IRP_CALL_SITE:
12818 return false;
12819 case IRP_CALL_SITE_RETURNED: {
12820 const auto &CB = cast<CallBase>(getAnchorValue());
12822 &CB, /*MustPreserveOffset=*/false);
12823 }
12824 case IRP_ARGUMENT: {
12825 const Function *F = getAssociatedFunction();
12826 assert(F && "no associated function for argument");
12827 return !isCallableCC(F->getCallingConv());
12828 }
12829 }
12830 }
12831
12832 bool isExternal() const {
12833 const Function *F = getAssociatedFunction();
12834 if (!F)
12835 return true;
12836 return isCallableCC(F->getCallingConv()) &&
12837 getPositionKind() != IRP_CALL_SITE_RETURNED;
12838 }
12839
12840 ChangeStatus updateNoAlias(Attributor &A) {
12841 if (isKnown(IS_NOALIAS) || !isAssumed(IS_NOALIAS))
12842 return ChangeStatus::UNCHANGED;
12843
12844 // Try to use AANoAlias.
12845 if (const auto *ANoAlias = A.getOrCreateAAFor<AANoAlias>(
12846 getIRPosition(), this, DepClassTy::REQUIRED)) {
12847 if (ANoAlias->isKnownNoAlias()) {
12848 addKnownBits(IS_NOALIAS);
12849 return ChangeStatus::CHANGED;
12850 }
12851
12852 if (!ANoAlias->isAssumedNoAlias()) {
12853 removeAssumedBits(IS_NOALIAS);
12854 return ChangeStatus::CHANGED;
12855 }
12856
12857 return ChangeStatus::UNCHANGED;
12858 }
12859
12860 // Try to infer noalias from argument attribute, since it is applicable for
12861 // the duration of the function.
12862 if (const Argument *Arg = getAssociatedArgument()) {
12863 if (Arg->hasNoAliasAttr()) {
12864 addKnownBits(IS_NOALIAS);
12865 return ChangeStatus::UNCHANGED;
12866 }
12867
12868 // Noalias information is not provided, and cannot be inferred,
12869 // so we conservatively assume the pointer aliases.
12870 removeAssumedBits(IS_NOALIAS);
12871 return ChangeStatus::CHANGED;
12872 }
12873
12874 return ChangeStatus::UNCHANGED;
12875 }
12876
12877 ChangeStatus updateNoEffect(Attributor &A) {
12878 if (isKnown(IS_NOEFFECT) || !isAssumed(IS_NOEFFECT))
12879 return ChangeStatus::UNCHANGED;
12880
12881 if (!getAssociatedFunction())
12882 return indicatePessimisticFixpoint();
12883
12884 if (isa<AllocaInst>(&getAssociatedValue()))
12885 return indicatePessimisticFixpoint();
12886
12887 const auto HasNoEffectLoads = [&](const Use &U, bool &) {
12888 const auto *LI = dyn_cast<LoadInst>(U.getUser());
12889 return !LI || !LI->mayHaveSideEffects();
12890 };
12891 if (!A.checkForAllUses(HasNoEffectLoads, *this, getAssociatedValue()))
12892 return indicatePessimisticFixpoint();
12893
12894 if (const auto *AMemoryBehavior = A.getOrCreateAAFor<AAMemoryBehavior>(
12895 getIRPosition(), this, DepClassTy::REQUIRED)) {
12896 // For non-instructions, try to use AAMemoryBehavior to infer the readonly
12897 // attribute
12898 if (!AMemoryBehavior->isAssumedReadOnly())
12899 return indicatePessimisticFixpoint();
12900
12901 if (AMemoryBehavior->isKnownReadOnly()) {
12902 addKnownBits(IS_NOEFFECT);
12903 return ChangeStatus::UNCHANGED;
12904 }
12905
12906 return ChangeStatus::UNCHANGED;
12907 }
12908
12909 if (const Argument *Arg = getAssociatedArgument()) {
12910 if (Arg->onlyReadsMemory()) {
12911 addKnownBits(IS_NOEFFECT);
12912 return ChangeStatus::UNCHANGED;
12913 }
12914
12915 // Readonly information is not provided, and cannot be inferred from
12916 // AAMemoryBehavior.
12917 return indicatePessimisticFixpoint();
12918 }
12919
12920 return ChangeStatus::UNCHANGED;
12921 }
12922
12923 ChangeStatus updateLocalInvariance(Attributor &A) {
12924 if (isKnown(IS_LOCALLY_INVARIANT) || !isAssumed(IS_LOCALLY_INVARIANT))
12925 return ChangeStatus::UNCHANGED;
12926
12927 // try to infer invariance from underlying objects
12928 const auto *AUO = A.getOrCreateAAFor<AAUnderlyingObjects>(
12929 getIRPosition(), this, DepClassTy::REQUIRED);
12930 if (!AUO)
12931 return ChangeStatus::UNCHANGED;
12932
12933 bool UsedAssumedInformation = false;
12934 const auto IsLocallyInvariantLoadIfPointer = [&](const Value &V) {
12935 if (!V.getType()->isPointerTy())
12936 return true;
12937 const auto *IsInvariantLoadPointer =
12938 A.getOrCreateAAFor<AAInvariantLoadPointer>(IRPosition::value(V), this,
12939 DepClassTy::REQUIRED);
12940 // Conservatively fail if invariance cannot be inferred.
12941 if (!IsInvariantLoadPointer)
12942 return false;
12943
12944 if (IsInvariantLoadPointer->isKnownLocallyInvariant())
12945 return true;
12946 if (!IsInvariantLoadPointer->isAssumedLocallyInvariant())
12947 return false;
12948
12949 UsedAssumedInformation = true;
12950 return true;
12951 };
12952 if (!AUO->forallUnderlyingObjects(IsLocallyInvariantLoadIfPointer))
12953 return indicatePessimisticFixpoint();
12954
12955 if (const auto *CB = dyn_cast<CallBase>(&getAnchorValue())) {
12957 CB, /*MustPreserveOffset=*/false)) {
12958 for (const Value *Arg : CB->args()) {
12959 if (!IsLocallyInvariantLoadIfPointer(*Arg))
12960 return indicatePessimisticFixpoint();
12961 }
12962 }
12963 }
12964
12965 if (!UsedAssumedInformation) {
12966 // Pointer is known and not just assumed to be locally invariant.
12967 addKnownBits(IS_LOCALLY_INVARIANT);
12968 return ChangeStatus::CHANGED;
12969 }
12970
12971 return ChangeStatus::UNCHANGED;
12972 }
12973};
12974
12975struct AAInvariantLoadPointerFloating final : AAInvariantLoadPointerImpl {
12976 AAInvariantLoadPointerFloating(const IRPosition &IRP, Attributor &A)
12977 : AAInvariantLoadPointerImpl(IRP, A) {}
12978};
12979
12980struct AAInvariantLoadPointerReturned final : AAInvariantLoadPointerImpl {
12981 AAInvariantLoadPointerReturned(const IRPosition &IRP, Attributor &A)
12982 : AAInvariantLoadPointerImpl(IRP, A) {}
12983
12984 void initialize(Attributor &) override {
12985 removeAssumedBits(IS_LOCALLY_CONSTRAINED);
12986 }
12987};
12988
12989struct AAInvariantLoadPointerCallSiteReturned final
12990 : AAInvariantLoadPointerImpl {
12991 AAInvariantLoadPointerCallSiteReturned(const IRPosition &IRP, Attributor &A)
12992 : AAInvariantLoadPointerImpl(IRP, A) {}
12993
12994 void initialize(Attributor &A) override {
12995 const Function *F = getAssociatedFunction();
12996 assert(F && "no associated function for return from call");
12997
12998 if (!F->isDeclaration() && !F->isIntrinsic())
12999 return AAInvariantLoadPointerImpl::initialize(A);
13000
13001 const auto &CB = cast<CallBase>(getAnchorValue());
13003 &CB, /*MustPreserveOffset=*/false))
13004 return AAInvariantLoadPointerImpl::initialize(A);
13005
13006 if (F->onlyReadsMemory() && F->hasNoSync())
13007 return AAInvariantLoadPointerImpl::initialize(A);
13008
13009 // At this point, the function is opaque, so we conservatively assume
13010 // non-invariance.
13011 indicatePessimisticFixpoint();
13012 }
13013};
13014
13015struct AAInvariantLoadPointerArgument final : AAInvariantLoadPointerImpl {
13016 AAInvariantLoadPointerArgument(const IRPosition &IRP, Attributor &A)
13017 : AAInvariantLoadPointerImpl(IRP, A) {}
13018
13019 void initialize(Attributor &) override {
13020 const Function *F = getAssociatedFunction();
13021 assert(F && "no associated function for argument");
13022
13023 if (!isCallableCC(F->getCallingConv())) {
13024 addKnownBits(IS_LOCALLY_CONSTRAINED);
13025 return;
13026 }
13027
13028 if (!F->hasLocalLinkage())
13029 removeAssumedBits(IS_LOCALLY_CONSTRAINED);
13030 }
13031};
13032
13033struct AAInvariantLoadPointerCallSiteArgument final
13034 : AAInvariantLoadPointerImpl {
13035 AAInvariantLoadPointerCallSiteArgument(const IRPosition &IRP, Attributor &A)
13036 : AAInvariantLoadPointerImpl(IRP, A) {}
13037};
13038} // namespace
13039
13040/// ------------------------ Address Space ------------------------------------
13041namespace {
13042
13043template <typename InstType>
13044static bool makeChange(Attributor &A, InstType *MemInst, const Use &U,
13045 Value *OriginalValue, PointerType *NewPtrTy,
13046 bool UseOriginalValue) {
13047 if (U.getOperandNo() != InstType::getPointerOperandIndex())
13048 return false;
13049
13050 if (MemInst->isVolatile()) {
13051 auto *TTI = A.getInfoCache().getAnalysisResultForFunction<TargetIRAnalysis>(
13052 *MemInst->getFunction());
13053 unsigned NewAS = NewPtrTy->getPointerAddressSpace();
13054 if (!TTI || !TTI->hasVolatileVariant(MemInst, NewAS))
13055 return false;
13056 }
13057
13058 if (UseOriginalValue) {
13059 A.changeUseAfterManifest(const_cast<Use &>(U), *OriginalValue);
13060 return true;
13061 }
13062
13063 Instruction *CastInst = new AddrSpaceCastInst(OriginalValue, NewPtrTy);
13064 CastInst->insertBefore(MemInst->getIterator());
13065 A.changeUseAfterManifest(const_cast<Use &>(U), *CastInst);
13066 return true;
13067}
13068
13069struct AAAddressSpaceImpl : public AAAddressSpace {
13070 AAAddressSpaceImpl(const IRPosition &IRP, Attributor &A)
13071 : AAAddressSpace(IRP, A) {}
13072
13073 uint32_t getAddressSpace() const override {
13074 assert(isValidState() && "the AA is invalid");
13075 return AssumedAddressSpace;
13076 }
13077
13078 /// See AbstractAttribute::initialize(...).
13079 void initialize(Attributor &A) override {
13080 assert(getAssociatedType()->isPtrOrPtrVectorTy() &&
13081 "Associated value is not a pointer");
13082
13083 if (!A.getInfoCache().getFlatAddressSpace().has_value()) {
13084 indicatePessimisticFixpoint();
13085 return;
13086 }
13087
13088 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13089 unsigned AS = getAssociatedType()->getPointerAddressSpace();
13090 if (AS != FlatAS) {
13091 [[maybe_unused]] bool R = takeAddressSpace(AS);
13092 assert(R && "The take should happen");
13093 indicateOptimisticFixpoint();
13094 }
13095 }
13096
13097 ChangeStatus updateImpl(Attributor &A) override {
13098 uint32_t OldAddressSpace = AssumedAddressSpace;
13099 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13100
13101 auto CheckAddressSpace = [&](Value &Obj) {
13102 // Ignore undef.
13103 if (isa<UndefValue>(&Obj))
13104 return true;
13105
13106 // If the object already has a non-flat address space, we simply take it.
13107 unsigned ObjAS = Obj.getType()->getPointerAddressSpace();
13108 if (ObjAS != FlatAS)
13109 return takeAddressSpace(ObjAS);
13110
13111 // At this point, we know Obj is in the flat address space. For a final
13112 // attempt, we want to use getAssumedAddrSpace, but first we must get the
13113 // associated function, if possible.
13114 Function *F = nullptr;
13115 if (auto *Arg = dyn_cast<Argument>(&Obj))
13116 F = Arg->getParent();
13117 else if (auto *I = dyn_cast<Instruction>(&Obj))
13118 F = I->getFunction();
13119
13120 // Use getAssumedAddrSpace if the associated function exists.
13121 if (F) {
13122 auto *TTI =
13123 A.getInfoCache().getAnalysisResultForFunction<TargetIRAnalysis>(*F);
13124 unsigned AssumedAS = TTI->getAssumedAddrSpace(&Obj);
13125 if (AssumedAS != ~0U)
13126 return takeAddressSpace(AssumedAS);
13127 }
13128
13129 // Now we can't do anything else but to take the flat AS.
13130 return takeAddressSpace(FlatAS);
13131 };
13132
13133 auto *AUO = A.getOrCreateAAFor<AAUnderlyingObjects>(getIRPosition(), this,
13134 DepClassTy::REQUIRED);
13135 if (!AUO->forallUnderlyingObjects(CheckAddressSpace))
13136 return indicatePessimisticFixpoint();
13137
13138 return OldAddressSpace == AssumedAddressSpace ? ChangeStatus::UNCHANGED
13139 : ChangeStatus::CHANGED;
13140 }
13141
13142 /// See AbstractAttribute::manifest(...).
13143 ChangeStatus manifest(Attributor &A) override {
13144 unsigned NewAS = getAddressSpace();
13145
13146 if (NewAS == InvalidAddressSpace ||
13147 NewAS == getAssociatedType()->getPointerAddressSpace())
13148 return ChangeStatus::UNCHANGED;
13149
13150 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13151
13152 Value *AssociatedValue = &getAssociatedValue();
13153 Value *OriginalValue = peelAddrspacecast(AssociatedValue, FlatAS);
13154
13155 PointerType *NewPtrTy =
13156 PointerType::get(getAssociatedType()->getContext(), NewAS);
13157 bool UseOriginalValue =
13158 OriginalValue->getType()->getPointerAddressSpace() == NewAS;
13159
13160 bool Changed = false;
13161
13162 auto Pred = [&](const Use &U, bool &) {
13163 if (U.get() != AssociatedValue)
13164 return true;
13165 auto *Inst = dyn_cast<Instruction>(U.getUser());
13166 if (!Inst)
13167 return true;
13168 // This is a WA to make sure we only change uses from the corresponding
13169 // CGSCC if the AA is run on CGSCC instead of the entire module.
13170 if (!A.isRunOn(Inst->getFunction()))
13171 return true;
13172 if (auto *LI = dyn_cast<LoadInst>(Inst)) {
13173 Changed |=
13174 makeChange(A, LI, U, OriginalValue, NewPtrTy, UseOriginalValue);
13175 } else if (auto *SI = dyn_cast<StoreInst>(Inst)) {
13176 Changed |=
13177 makeChange(A, SI, U, OriginalValue, NewPtrTy, UseOriginalValue);
13178 } else if (auto *RMW = dyn_cast<AtomicRMWInst>(Inst)) {
13179 Changed |=
13180 makeChange(A, RMW, U, OriginalValue, NewPtrTy, UseOriginalValue);
13181 } else if (auto *CmpX = dyn_cast<AtomicCmpXchgInst>(Inst)) {
13182 Changed |=
13183 makeChange(A, CmpX, U, OriginalValue, NewPtrTy, UseOriginalValue);
13184 }
13185 return true;
13186 };
13187
13188 // It doesn't matter if we can't check all uses as we can simply
13189 // conservatively ignore those that can not be visited.
13190 (void)A.checkForAllUses(Pred, *this, getAssociatedValue(),
13191 /* CheckBBLivenessOnly */ true);
13192
13193 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
13194 }
13195
13196 /// See AbstractAttribute::getAsStr().
13197 const std::string getAsStr(Attributor *A) const override {
13198 if (!isValidState())
13199 return "addrspace(<invalid>)";
13200 return "addrspace(" +
13201 (AssumedAddressSpace == InvalidAddressSpace
13202 ? "none"
13203 : std::to_string(AssumedAddressSpace)) +
13204 ")";
13205 }
13206
13207private:
13208 uint32_t AssumedAddressSpace = InvalidAddressSpace;
13209
13210 bool takeAddressSpace(uint32_t AS) {
13211 if (AssumedAddressSpace == InvalidAddressSpace) {
13212 AssumedAddressSpace = AS;
13213 return true;
13214 }
13215 return AssumedAddressSpace == AS;
13216 }
13217
13218 static Value *peelAddrspacecast(Value *V, unsigned FlatAS) {
13219 if (auto *I = dyn_cast<AddrSpaceCastInst>(V)) {
13220 assert(I->getSrcAddressSpace() != FlatAS &&
13221 "there should not be flat AS -> non-flat AS");
13222 return I->getPointerOperand();
13223 }
13224 if (auto *C = dyn_cast<ConstantExpr>(V))
13225 if (C->getOpcode() == Instruction::AddrSpaceCast) {
13226 assert(C->getOperand(0)->getType()->getPointerAddressSpace() !=
13227 FlatAS &&
13228 "there should not be flat AS -> non-flat AS X");
13229 return C->getOperand(0);
13230 }
13231 return V;
13232 }
13233};
13234
13235struct AAAddressSpaceFloating final : AAAddressSpaceImpl {
13236 AAAddressSpaceFloating(const IRPosition &IRP, Attributor &A)
13237 : AAAddressSpaceImpl(IRP, A) {}
13238
13239 void trackStatistics() const override {
13241 }
13242};
13243
13244struct AAAddressSpaceReturned final : AAAddressSpaceImpl {
13245 AAAddressSpaceReturned(const IRPosition &IRP, Attributor &A)
13246 : AAAddressSpaceImpl(IRP, A) {}
13247
13248 /// See AbstractAttribute::initialize(...).
13249 void initialize(Attributor &A) override {
13250 // TODO: we don't rewrite function argument for now because it will need to
13251 // rewrite the function signature and all call sites.
13252 (void)indicatePessimisticFixpoint();
13253 }
13254
13255 void trackStatistics() const override {
13256 STATS_DECLTRACK_FNRET_ATTR(addrspace);
13257 }
13258};
13259
13260struct AAAddressSpaceCallSiteReturned final : AAAddressSpaceImpl {
13261 AAAddressSpaceCallSiteReturned(const IRPosition &IRP, Attributor &A)
13262 : AAAddressSpaceImpl(IRP, A) {}
13263
13264 void trackStatistics() const override {
13265 STATS_DECLTRACK_CSRET_ATTR(addrspace);
13266 }
13267};
13268
13269struct AAAddressSpaceArgument final : AAAddressSpaceImpl {
13270 AAAddressSpaceArgument(const IRPosition &IRP, Attributor &A)
13271 : AAAddressSpaceImpl(IRP, A) {}
13272
13273 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(addrspace); }
13274};
13275
13276struct AAAddressSpaceCallSiteArgument final : AAAddressSpaceImpl {
13277 AAAddressSpaceCallSiteArgument(const IRPosition &IRP, Attributor &A)
13278 : AAAddressSpaceImpl(IRP, A) {}
13279
13280 /// See AbstractAttribute::initialize(...).
13281 void initialize(Attributor &A) override {
13282 // TODO: we don't rewrite call site argument for now because it will need to
13283 // rewrite the function signature of the callee.
13284 (void)indicatePessimisticFixpoint();
13285 }
13286
13287 void trackStatistics() const override {
13288 STATS_DECLTRACK_CSARG_ATTR(addrspace);
13289 }
13290};
13291} // namespace
13292
13293/// ------------------------ No Alias Address Space ---------------------------
13294// This attribute assumes flat address space can alias all other address space
13295
13296// TODO: this is similar to AAAddressSpace, most of the code should be merged.
13297// But merging it created failing cased on gateway test that cannot be
13298// reproduced locally. So should open a separated PR to handle the merge of
13299// AANoAliasAddrSpace and AAAddressSpace attribute
13300
13301namespace {
13302struct AANoAliasAddrSpaceImpl : public AANoAliasAddrSpace {
13303 AANoAliasAddrSpaceImpl(const IRPosition &IRP, Attributor &A)
13304 : AANoAliasAddrSpace(IRP, A) {}
13305
13306 void initialize(Attributor &A) override {
13307 assert(getAssociatedType()->isPtrOrPtrVectorTy() &&
13308 "Associated value is not a pointer");
13309
13310 resetASRanges(A);
13311
13312 std::optional<unsigned> FlatAS = A.getInfoCache().getFlatAddressSpace();
13313 if (!FlatAS.has_value()) {
13314 indicatePessimisticFixpoint();
13315 return;
13316 }
13317
13318 removeAS(*FlatAS);
13319
13320 unsigned AS = getAssociatedType()->getPointerAddressSpace();
13321 if (AS != *FlatAS) {
13322 removeAS(AS);
13323 indicateOptimisticFixpoint();
13324 }
13325 }
13326
13327 ChangeStatus updateImpl(Attributor &A) override {
13328 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13329 uint32_t OldAssumed = getAssumed();
13330
13331 auto CheckAddressSpace = [&](Value &Obj) {
13332 if (isa<PoisonValue>(&Obj))
13333 return true;
13334
13335 unsigned AS = Obj.getType()->getPointerAddressSpace();
13336 if (AS == FlatAS)
13337 return false;
13338
13339 removeAS(Obj.getType()->getPointerAddressSpace());
13340 return true;
13341 };
13342
13343 const AAUnderlyingObjects *AUO = A.getOrCreateAAFor<AAUnderlyingObjects>(
13344 getIRPosition(), this, DepClassTy::REQUIRED);
13345 if (!AUO->forallUnderlyingObjects(CheckAddressSpace))
13346 return indicatePessimisticFixpoint();
13347
13348 return OldAssumed == getAssumed() ? ChangeStatus::UNCHANGED
13349 : ChangeStatus::CHANGED;
13350 }
13351
13352 /// See AbstractAttribute::manifest(...).
13353 ChangeStatus manifest(Attributor &A) override {
13354 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13355
13356 unsigned AS = getAssociatedType()->getPointerAddressSpace();
13357 if (AS != FlatAS || Map.empty())
13358 return ChangeStatus::UNCHANGED;
13359
13360 LLVMContext &Ctx = getAssociatedValue().getContext();
13361 MDNode *NoAliasASNode = nullptr;
13362 MDBuilder MDB(Ctx);
13363 // Has to use iterator to get the range info.
13364 for (RangeMap::const_iterator I = Map.begin(); I != Map.end(); I++) {
13365 if (!I.value())
13366 continue;
13367 unsigned Upper = I.stop();
13368 unsigned Lower = I.start();
13369 if (!NoAliasASNode) {
13370 NoAliasASNode = MDB.createRange(APInt(32, Lower), APInt(32, Upper + 1));
13371 continue;
13372 }
13373 MDNode *ASRange = MDB.createRange(APInt(32, Lower), APInt(32, Upper + 1));
13374 NoAliasASNode = MDNode::getMostGenericRange(NoAliasASNode, ASRange);
13375 }
13376
13377 Value *AssociatedValue = &getAssociatedValue();
13378 bool Changed = false;
13379
13380 auto AddNoAliasAttr = [&](const Use &U, bool &) {
13381 if (U.get() != AssociatedValue)
13382 return true;
13383 Instruction *Inst = dyn_cast<Instruction>(U.getUser());
13384 if (!Inst || Inst->hasMetadata(LLVMContext::MD_noalias_addrspace))
13385 return true;
13386 if (!isa<LoadInst>(Inst) && !isa<StoreInst>(Inst) &&
13388 return true;
13389 if (!A.isRunOn(Inst->getFunction()))
13390 return true;
13391 Inst->setMetadata(LLVMContext::MD_noalias_addrspace, NoAliasASNode);
13392 Changed = true;
13393 return true;
13394 };
13395 (void)A.checkForAllUses(AddNoAliasAttr, *this, *AssociatedValue,
13396 /*CheckBBLivenessOnly=*/true);
13397 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
13398 }
13399
13400 /// See AbstractAttribute::getAsStr().
13401 const std::string getAsStr(Attributor *A) const override {
13402 if (!isValidState())
13403 return "<invalid>";
13404 std::string Str;
13405 raw_string_ostream OS(Str);
13406 OS << "CanNotBeAddrSpace(";
13407 for (RangeMap::const_iterator I = Map.begin(); I != Map.end(); I++) {
13408 unsigned Upper = I.stop();
13409 unsigned Lower = I.start();
13410 OS << ' ' << '[' << Upper << ',' << Lower + 1 << ')';
13411 }
13412 OS << " )";
13413 return OS.str();
13414 }
13415
13416private:
13417 void removeAS(unsigned AS) {
13418 RangeMap::iterator I = Map.find(AS);
13419
13420 if (I != Map.end()) {
13421 unsigned Upper = I.stop();
13422 unsigned Lower = I.start();
13423 I.erase();
13424 if (Upper == Lower)
13425 return;
13426 if (AS != ~((unsigned)0) && AS + 1 <= Upper)
13427 Map.insert(AS + 1, Upper, /*what ever this variable name is=*/true);
13428 if (AS != 0 && Lower <= AS - 1)
13429 Map.insert(Lower, AS - 1, true);
13430 }
13431 }
13432
13433 void resetASRanges(Attributor &A) {
13434 Map.clear();
13435 Map.insert(0, A.getInfoCache().getMaxAddrSpace(), true);
13436 }
13437};
13438
13439struct AANoAliasAddrSpaceFloating final : AANoAliasAddrSpaceImpl {
13440 AANoAliasAddrSpaceFloating(const IRPosition &IRP, Attributor &A)
13441 : AANoAliasAddrSpaceImpl(IRP, A) {}
13442
13443 void trackStatistics() const override {
13444 STATS_DECLTRACK_FLOATING_ATTR(noaliasaddrspace);
13445 }
13446};
13447
13448struct AANoAliasAddrSpaceReturned final : AANoAliasAddrSpaceImpl {
13449 AANoAliasAddrSpaceReturned(const IRPosition &IRP, Attributor &A)
13450 : AANoAliasAddrSpaceImpl(IRP, A) {}
13451
13452 void trackStatistics() const override {
13453 STATS_DECLTRACK_FNRET_ATTR(noaliasaddrspace);
13454 }
13455};
13456
13457struct AANoAliasAddrSpaceCallSiteReturned final : AANoAliasAddrSpaceImpl {
13458 AANoAliasAddrSpaceCallSiteReturned(const IRPosition &IRP, Attributor &A)
13459 : AANoAliasAddrSpaceImpl(IRP, A) {}
13460
13461 void trackStatistics() const override {
13462 STATS_DECLTRACK_CSRET_ATTR(noaliasaddrspace);
13463 }
13464};
13465
13466struct AANoAliasAddrSpaceArgument final : AANoAliasAddrSpaceImpl {
13467 AANoAliasAddrSpaceArgument(const IRPosition &IRP, Attributor &A)
13468 : AANoAliasAddrSpaceImpl(IRP, A) {}
13469
13470 void trackStatistics() const override {
13471 STATS_DECLTRACK_ARG_ATTR(noaliasaddrspace);
13472 }
13473};
13474
13475struct AANoAliasAddrSpaceCallSiteArgument final : AANoAliasAddrSpaceImpl {
13476 AANoAliasAddrSpaceCallSiteArgument(const IRPosition &IRP, Attributor &A)
13477 : AANoAliasAddrSpaceImpl(IRP, A) {}
13478
13479 void trackStatistics() const override {
13480 STATS_DECLTRACK_CSARG_ATTR(noaliasaddrspace);
13481 }
13482};
13483} // namespace
13484/// ----------- Allocation Info ----------
13485namespace {
13486struct AAAllocationInfoImpl : public AAAllocationInfo {
13487 AAAllocationInfoImpl(const IRPosition &IRP, Attributor &A)
13488 : AAAllocationInfo(IRP, A) {}
13489
13490 std::optional<TypeSize> getAllocatedSize() const override {
13491 assert(isValidState() && "the AA is invalid");
13492 return AssumedAllocatedSize;
13493 }
13494
13495 std::optional<TypeSize> findInitialAllocationSize(Instruction *I,
13496 const DataLayout &DL) {
13497
13498 // TODO: implement case for malloc like instructions
13499 switch (I->getOpcode()) {
13500 case Instruction::Alloca: {
13501 AllocaInst *AI = cast<AllocaInst>(I);
13502 return AI->getAllocationSize(DL);
13503 }
13504 default:
13505 return std::nullopt;
13506 }
13507 }
13508
13509 ChangeStatus updateImpl(Attributor &A) override {
13510
13511 const IRPosition &IRP = getIRPosition();
13512 Instruction *I = IRP.getCtxI();
13513
13514 // TODO: update check for malloc like calls
13515 if (!isa<AllocaInst>(I))
13516 return indicatePessimisticFixpoint();
13517
13518 bool IsKnownNoCapture;
13520 A, this, IRP, DepClassTy::OPTIONAL, IsKnownNoCapture))
13521 return indicatePessimisticFixpoint();
13522
13523 const AAPointerInfo *PI =
13524 A.getOrCreateAAFor<AAPointerInfo>(IRP, *this, DepClassTy::REQUIRED);
13525
13526 if (!PI)
13527 return indicatePessimisticFixpoint();
13528
13529 if (!PI->getState().isValidState() || PI->reachesReturn())
13530 return indicatePessimisticFixpoint();
13531
13532 const DataLayout &DL = A.getDataLayout();
13533 const auto AllocationSize = findInitialAllocationSize(I, DL);
13534
13535 // If allocation size is nullopt, we give up.
13536 if (!AllocationSize)
13537 return indicatePessimisticFixpoint();
13538
13539 // For zero sized allocations, we give up.
13540 // Since we can't reduce further
13541 if (*AllocationSize == 0)
13542 return indicatePessimisticFixpoint();
13543
13544 int64_t BinSize = PI->numOffsetBins();
13545
13546 // TODO: implement for multiple bins
13547 if (BinSize > 1)
13548 return indicatePessimisticFixpoint();
13549
13550 if (BinSize == 0) {
13551 auto NewAllocationSize = std::make_optional<TypeSize>(0, false);
13552 if (!changeAllocationSize(NewAllocationSize))
13553 return ChangeStatus::UNCHANGED;
13554 return ChangeStatus::CHANGED;
13555 }
13556
13557 // TODO: refactor this to be part of multiple bin case
13558 const auto &It = PI->begin();
13559
13560 // TODO: handle if Offset is not zero
13561 if (It->first.Offset != 0)
13562 return indicatePessimisticFixpoint();
13563
13564 uint64_t SizeOfBin = It->first.Offset + It->first.Size;
13565
13566 if (SizeOfBin >= *AllocationSize)
13567 return indicatePessimisticFixpoint();
13568
13569 auto NewAllocationSize = std::make_optional<TypeSize>(SizeOfBin * 8, false);
13570
13571 if (!changeAllocationSize(NewAllocationSize))
13572 return ChangeStatus::UNCHANGED;
13573
13574 return ChangeStatus::CHANGED;
13575 }
13576
13577 /// See AbstractAttribute::manifest(...).
13578 ChangeStatus manifest(Attributor &A) override {
13579
13580 assert(isValidState() &&
13581 "Manifest should only be called if the state is valid.");
13582
13583 Instruction *I = getIRPosition().getCtxI();
13584
13585 auto FixedAllocatedSizeInBits = getAllocatedSize()->getFixedValue();
13586
13587 unsigned long NumBytesToAllocate = (FixedAllocatedSizeInBits + 7) / 8;
13588
13589 switch (I->getOpcode()) {
13590 // TODO: add case for malloc like calls
13591 case Instruction::Alloca: {
13592
13593 AllocaInst *AI = cast<AllocaInst>(I);
13594
13595 Type *CharType = Type::getInt8Ty(I->getContext());
13596
13597 auto *NumBytesToValue =
13598 ConstantInt::get(I->getContext(), APInt(32, NumBytesToAllocate));
13599
13600 BasicBlock::iterator insertPt = AI->getIterator();
13601 insertPt = std::next(insertPt);
13602 AllocaInst *NewAllocaInst =
13603 new AllocaInst(CharType, AI->getAddressSpace(), NumBytesToValue,
13604 AI->getAlign(), AI->getName(), insertPt);
13605
13606 if (A.changeAfterManifest(IRPosition::inst(*AI), *NewAllocaInst))
13607 return ChangeStatus::CHANGED;
13608
13609 break;
13610 }
13611 default:
13612 break;
13613 }
13614
13615 return ChangeStatus::UNCHANGED;
13616 }
13617
13618 /// See AbstractAttribute::getAsStr().
13619 const std::string getAsStr(Attributor *A) const override {
13620 if (!isValidState())
13621 return "allocationinfo(<invalid>)";
13622 return "allocationinfo(" +
13623 (AssumedAllocatedSize == HasNoAllocationSize
13624 ? "none"
13625 : std::to_string(AssumedAllocatedSize->getFixedValue())) +
13626 ")";
13627 }
13628
13629private:
13630 std::optional<TypeSize> AssumedAllocatedSize = HasNoAllocationSize;
13631
13632 // Maintain the computed allocation size of the object.
13633 // Returns (bool) weather the size of the allocation was modified or not.
13634 bool changeAllocationSize(std::optional<TypeSize> Size) {
13635 if (AssumedAllocatedSize == HasNoAllocationSize ||
13636 AssumedAllocatedSize != Size) {
13637 AssumedAllocatedSize = Size;
13638 return true;
13639 }
13640 return false;
13641 }
13642};
13643
13644struct AAAllocationInfoFloating : AAAllocationInfoImpl {
13645 AAAllocationInfoFloating(const IRPosition &IRP, Attributor &A)
13646 : AAAllocationInfoImpl(IRP, A) {}
13647
13648 void trackStatistics() const override {
13649 STATS_DECLTRACK_FLOATING_ATTR(allocationinfo);
13650 }
13651};
13652
13653struct AAAllocationInfoReturned : AAAllocationInfoImpl {
13654 AAAllocationInfoReturned(const IRPosition &IRP, Attributor &A)
13655 : AAAllocationInfoImpl(IRP, A) {}
13656
13657 /// See AbstractAttribute::initialize(...).
13658 void initialize(Attributor &A) override {
13659 // TODO: we don't rewrite function argument for now because it will need to
13660 // rewrite the function signature and all call sites
13661 (void)indicatePessimisticFixpoint();
13662 }
13663
13664 void trackStatistics() const override {
13665 STATS_DECLTRACK_FNRET_ATTR(allocationinfo);
13666 }
13667};
13668
13669struct AAAllocationInfoCallSiteReturned : AAAllocationInfoImpl {
13670 AAAllocationInfoCallSiteReturned(const IRPosition &IRP, Attributor &A)
13671 : AAAllocationInfoImpl(IRP, A) {}
13672
13673 void trackStatistics() const override {
13674 STATS_DECLTRACK_CSRET_ATTR(allocationinfo);
13675 }
13676};
13677
13678struct AAAllocationInfoArgument : AAAllocationInfoImpl {
13679 AAAllocationInfoArgument(const IRPosition &IRP, Attributor &A)
13680 : AAAllocationInfoImpl(IRP, A) {}
13681
13682 void trackStatistics() const override {
13683 STATS_DECLTRACK_ARG_ATTR(allocationinfo);
13684 }
13685};
13686
13687struct AAAllocationInfoCallSiteArgument : AAAllocationInfoImpl {
13688 AAAllocationInfoCallSiteArgument(const IRPosition &IRP, Attributor &A)
13689 : AAAllocationInfoImpl(IRP, A) {}
13690
13691 /// See AbstractAttribute::initialize(...).
13692 void initialize(Attributor &A) override {
13693
13694 (void)indicatePessimisticFixpoint();
13695 }
13696
13697 void trackStatistics() const override {
13698 STATS_DECLTRACK_CSARG_ATTR(allocationinfo);
13699 }
13700};
13701} // namespace
13702
13703const char AANoUnwind::ID = 0;
13704const char AANoSync::ID = 0;
13705const char AANoFree::ID = 0;
13706const char AANonNull::ID = 0;
13707const char AAMustProgress::ID = 0;
13708const char AANoRecurse::ID = 0;
13709const char AANonConvergent::ID = 0;
13710const char AAWillReturn::ID = 0;
13711const char AAUndefinedBehavior::ID = 0;
13712const char AANoAlias::ID = 0;
13713const char AAIntraFnReachability::ID = 0;
13714const char AANoReturn::ID = 0;
13715const char AAIsDead::ID = 0;
13716const char AADereferenceable::ID = 0;
13717const char AAAlign::ID = 0;
13718const char AAInstanceInfo::ID = 0;
13719const char AANoCapture::ID = 0;
13720const char AAValueSimplify::ID = 0;
13721const char AAHeapToStack::ID = 0;
13722const char AAPrivatizablePtr::ID = 0;
13723const char AAMemoryBehavior::ID = 0;
13724const char AAMemoryLocation::ID = 0;
13725const char AAValueConstantRange::ID = 0;
13726const char AAPotentialConstantValues::ID = 0;
13727const char AAPotentialValues::ID = 0;
13728const char AANoUndef::ID = 0;
13729const char AANoFPClass::ID = 0;
13730const char AACallEdges::ID = 0;
13731const char AAInterFnReachability::ID = 0;
13732const char AAPointerInfo::ID = 0;
13733const char AAAssumptionInfo::ID = 0;
13734const char AAUnderlyingObjects::ID = 0;
13735const char AAInvariantLoadPointer::ID = 0;
13736const char AAAddressSpace::ID = 0;
13737const char AANoAliasAddrSpace::ID = 0;
13738const char AAAllocationInfo::ID = 0;
13739const char AAIndirectCallInfo::ID = 0;
13740const char AAGlobalValueInfo::ID = 0;
13741const char AADenormalFPMath::ID = 0;
13742
13743// Macro magic to create the static generator function for attributes that
13744// follow the naming scheme.
13745
13746#define SWITCH_PK_INV(CLASS, PK, POS_NAME) \
13747 case IRPosition::PK: \
13748 llvm_unreachable("Cannot create " #CLASS " for a " POS_NAME " position!");
13749
13750#define SWITCH_PK_CREATE(CLASS, IRP, PK, SUFFIX) \
13751 case IRPosition::PK: \
13752 AA = new (A.Allocator) CLASS##SUFFIX(IRP, A); \
13753 ++NumAAs; \
13754 break;
13755
13756#define CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13757 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13758 CLASS *AA = nullptr; \
13759 switch (IRP.getPositionKind()) { \
13760 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13761 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
13762 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
13763 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
13764 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
13765 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
13766 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
13767 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
13768 } \
13769 return *AA; \
13770 }
13771
13772#define CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13773 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13774 CLASS *AA = nullptr; \
13775 switch (IRP.getPositionKind()) { \
13776 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13777 SWITCH_PK_INV(CLASS, IRP_FUNCTION, "function") \
13778 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
13779 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
13780 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
13781 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
13782 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
13783 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
13784 } \
13785 return *AA; \
13786 }
13787
13788#define CREATE_ABSTRACT_ATTRIBUTE_FOR_ONE_POSITION(POS, SUFFIX, CLASS) \
13789 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13790 CLASS *AA = nullptr; \
13791 switch (IRP.getPositionKind()) { \
13792 SWITCH_PK_CREATE(CLASS, IRP, POS, SUFFIX) \
13793 default: \
13794 llvm_unreachable("Cannot create " #CLASS " for position otherthan " #POS \
13795 " position!"); \
13796 } \
13797 return *AA; \
13798 }
13799
13800#define CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13801 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13802 CLASS *AA = nullptr; \
13803 switch (IRP.getPositionKind()) { \
13804 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13805 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
13806 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
13807 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
13808 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
13809 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
13810 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
13811 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
13812 } \
13813 return *AA; \
13814 }
13815
13816#define CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13817 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13818 CLASS *AA = nullptr; \
13819 switch (IRP.getPositionKind()) { \
13820 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13821 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
13822 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
13823 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
13824 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
13825 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
13826 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
13827 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
13828 } \
13829 return *AA; \
13830 }
13831
13832#define CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13833 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13834 CLASS *AA = nullptr; \
13835 switch (IRP.getPositionKind()) { \
13836 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13837 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
13838 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
13839 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
13840 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
13841 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
13842 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
13843 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
13844 } \
13845 return *AA; \
13846 }
13847
13857
13875
13880
13885
13892
13894
13895#undef CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION
13896#undef CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION
13897#undef CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION
13898#undef CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION
13899#undef CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION
13900#undef CREATE_ABSTRACT_ATTRIBUTE_FOR_ONE_POSITION
13901#undef SWITCH_PK_CREATE
13902#undef SWITCH_PK_INV
#define Success
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
aarch64 promote const
AMDGPU Register Bank Select
Rewrite undef for PHI
This file implements a class to represent arbitrary precision integral constant values and operations...
ReachingDefInfo InstSet & ToRemove
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis false
This file contains the simple types necessary to represent the attributes associated with functions a...
#define STATS_DECLTRACK(NAME, TYPE, MSG)
static std::optional< Constant * > askForAssumedConstant(Attributor &A, const AbstractAttribute &QueryingAA, const IRPosition &IRP, Type &Ty)
static cl::opt< unsigned, true > MaxPotentialValues("attributor-max-potential-values", cl::Hidden, cl::desc("Maximum number of potential values to be " "tracked for each position."), cl::location(llvm::PotentialConstantIntValuesState::MaxPotentialValues), cl::init(7))
static void clampReturnedValueStates(Attributor &A, const AAType &QueryingAA, StateType &S, const IRPosition::CallBaseContext *CBContext=nullptr)
Clamp the information known for all returned values of a function (identified by QueryingAA) into S.
#define STATS_DECLTRACK_FN_ATTR(NAME)
#define CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
static cl::opt< int > MaxPotentialValuesIterations("attributor-max-potential-values-iterations", cl::Hidden, cl::desc("Maximum number of iterations we keep dismantling potential values."), cl::init(64))
#define STATS_DECLTRACK_CS_ATTR(NAME)
#define PIPE_OPERATOR(CLASS)
static bool mayBeInCycle(const CycleInfo *CI, const Instruction *I, bool HeaderOnly, Cycle **CPtr=nullptr)
#define STATS_DECLTRACK_ARG_ATTR(NAME)
static const Value * stripAndAccumulateOffsets(Attributor &A, const AbstractAttribute &QueryingAA, const Value *Val, const DataLayout &DL, APInt &Offset, bool GetMinOffset, bool AllowNonInbounds, bool UseAssumed=false)
#define STATS_DECLTRACK_CSRET_ATTR(NAME)
static cl::opt< bool > ManifestInternal("attributor-manifest-internal", cl::Hidden, cl::desc("Manifest Attributor internal string attributes."), cl::init(false))
static Value * constructPointer(Value *Ptr, int64_t Offset, IRBuilder< NoFolder > &IRB)
Helper function to create a pointer based on Ptr, and advanced by Offset bytes.
#define CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
#define BUILD_STAT_NAME(NAME, TYPE)
static bool isDenselyPacked(Type *Ty, const DataLayout &DL)
Checks if a type could have padding bytes.
#define CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
static const Value * getMinimalBaseOfPointer(Attributor &A, const AbstractAttribute &QueryingAA, const Value *Ptr, int64_t &BytesOffset, const DataLayout &DL, bool AllowNonInbounds=false)
#define STATS_DECLTRACK_FNRET_ATTR(NAME)
#define STATS_DECLTRACK_CSARG_ATTR(NAME)
#define CREATE_ABSTRACT_ATTRIBUTE_FOR_ONE_POSITION(POS, SUFFIX, CLASS)
#define CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
static cl::opt< int > MaxHeapToStackSize("max-heap-to-stack-size", cl::init(128), cl::Hidden)
#define CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
#define STATS_DECLTRACK_FLOATING_ATTR(NAME)
#define STATS_DECL(NAME, TYPE, MSG)
basic Basic Alias true
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static bool isReachableImpl(SmallVectorImpl< BasicBlock * > &Worklist, const StopSetT &StopSet, const SmallPtrSetImpl< BasicBlock * > *ExclusionSet, const DominatorTree *DT, const LoopInfo *LI, const CycleInfo *CI)
Definition CFG.cpp:145
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file declares an analysis pass that computes CycleInfo for LLVM IR, specialized from GenericCycl...
static uint64_t align(uint64_t Size)
DXIL Forward Handle Accesses
DXIL Resource Access
dxil translate DXIL Translate Metadata
This file defines DenseMapInfo traits for DenseMap.
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:1587
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:267
LLVM_ABI bool onlyReadsMemory() const
Return true if this argument has the readonly or readnone attribute.
Definition Function.cpp:303
LLVM_ABI bool hasPointeeInMemoryValueAttr() const
Return true if this argument has the byval, sret, inalloca, preallocated, or byref attribute.
Definition Function.cpp:170
LLVM_ABI bool hasReturnedAttr() const
Return true if this argument has the returned attribute.
Definition Function.cpp:291
LLVM_ABI bool hasByValAttr() const
Return true if this argument has the byval attribute.
Definition Function.cpp:127
const Function * getParent() const
Definition Argument.h:44
unsigned getArgNo() const
Return the index of this formal argument in its containing function.
Definition Argument.h:50
A function analysis which provides an AssumptionCache.
A cache of @llvm.assume calls within a function.
Functions, function parameters, and return types can have attributes to indicate how they should be t...
Definition Attributes.h:105
static LLVM_ABI Attribute get(LLVMContext &Context, AttrKind Kind, uint64_t Val=0)
Return a uniquified Attribute object.
LLVM_ABI FPClassTest getNoFPClass() const
Return the FPClassTest for nofpclass.
LLVM_ABI Attribute::AttrKind getKindAsEnum() const
Return the attribute's kind as an enum (Attribute::AttrKind).
LLVM_ABI MemoryEffects getMemoryEffects() const
Returns memory effects.
AttrKind
This enumeration lists the attributes that can be associated with parameters, function results,...
Definition Attributes.h:124
static LLVM_ABI Attribute getWithCaptureInfo(LLVMContext &Context, CaptureInfo CI)
static bool isEnumAttrKind(AttrKind Kind)
Definition Attributes.h:137
bool isValid() const
Return true if the attribute is any kind of attribute.
Definition Attributes.h:261
LLVM_ABI CaptureInfo getCaptureInfo() const
Returns information from captures attribute.
LLVM Basic Block Representation.
Definition BasicBlock.h:62
LLVM_ABI const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
const Function * getParent() const
Return the enclosing method, or null if none.
Definition BasicBlock.h:213
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition BasicBlock.h:206
const Instruction & front() const
Definition BasicBlock.h:484
InstListType::iterator iterator
Instruction iterators...
Definition BasicBlock.h:170
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
Definition BasicBlock.h:237
BinaryOps getOpcode() const
Definition InstrTypes.h:409
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
LLVM_ABI bool isMustTailCall() const
Tests if this call site must be tail call optimized.
LLVM_ABI bool isIndirectCall() const
Return true if the callsite is an indirect call.
bool isCallee(Value::const_user_iterator UI) const
Determine whether the passed iterator points to the callee operand's Use.
Value * getCalledOperand() const
const Use & getCalledOperandUse() const
Attribute getFnAttr(StringRef Kind) const
Get the attribute of a given kind for the function.
const Use & getArgOperandUse(unsigned i) const
Wrappers for getting the Use of a call argument.
LLVM_ABI std::optional< ConstantRange > getRange() const
If this return value has a range attribute, return the value range of the argument.
Value * getArgOperand(unsigned i) const
bool isBundleOperand(unsigned Idx) const
Return true if the operand at index Idx is a bundle operand.
bool isConvergent() const
Determine if the invoke is convergent.
FunctionType * getFunctionType() const
LLVM_ABI Intrinsic::ID getIntrinsicID() const
Returns the intrinsic ID of the intrinsic called or Intrinsic::not_intrinsic if the called function i...
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
unsigned getArgOperandNo(const Use *U) const
Given a use for a arg operand, get the arg operand number that corresponds to it.
unsigned arg_size() const
bool isArgOperand(const Use *U) const
LLVM_ABI Function * getCaller()
Helper to get the caller (the parent function).
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
static CaptureInfo none()
Create CaptureInfo that does not capture any components of the pointer.
Definition ModRef.h:427
Instruction::CastOps getOpcode() const
Return the opcode of this CastInst.
Definition InstrTypes.h:674
LLVM_ABI bool isIntegerCast() const
There are several places where we need to know if a cast instruction only deals with integer source a...
Type * getDestTy() const
Return the destination type, as a convenience.
Definition InstrTypes.h:681
bool isEquality() const
Determine if this is an equals/not equals predicate.
Definition InstrTypes.h:978
bool isFalseWhenEqual() const
This is just a convenience.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition InstrTypes.h:740
@ ICMP_NE
not equal
Definition InstrTypes.h:762
bool isTrueWhenEqual() const
This is just a convenience.
Predicate getPredicate() const
Return the predicate for this instruction.
Definition InstrTypes.h:828
Conditional Branch instruction.
Value * getCondition() const
BasicBlock * getSuccessor(unsigned i) const
static ConstantAsMetadata * get(Constant *C)
Definition Metadata.h:537
static LLVM_ABI Constant * getExtractElement(Constant *Vec, Constant *Idx, Type *OnlyIfReducedTy=nullptr)
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
This class represents a range of values.
const APInt & getLower() const
Return the lower value for this range.
LLVM_ABI bool isFullSet() const
Return true if this set contains all of the elements possible for this data-type.
LLVM_ABI bool isEmptySet() const
Return true if this set contains no members.
bool isSingleElement() const
Return true if this set contains exactly one member.
static LLVM_ABI ConstantRange makeAllowedICmpRegion(CmpInst::Predicate Pred, const ConstantRange &Other)
Produce the smallest range such that all values that may satisfy the given predicate with any value c...
const APInt & getUpper() const
Return the upper value for this range.
LLVM_ABI bool contains(const APInt &Val) const
Return true if the specified value is in the set.
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
iterator find(const_arg_type_t< KeyT > Val)
Definition DenseMap.h:223
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
Definition DenseMap.h:299
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:219
iterator end()
Definition DenseMap.h:141
bool contains(const_arg_type_t< KeyT > Val) const
Return true if the specified key is in the map, false otherwise.
Definition DenseMap.h:214
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition DenseMap.h:284
Analysis pass which computes a DominatorTree.
Definition Dominators.h:270
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition Dominators.h:151
LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
const BasicBlock & getEntryBlock() const
Definition Function.h:783
Argument * arg_iterator
Definition Function.h:73
iterator_range< arg_iterator > args()
Definition Function.h:866
const Function & getFunction() const
Definition Function.h:166
size_t arg_size() const
Definition Function.h:875
Argument * getArg(unsigned i) const
Definition Function.h:860
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition Function.cpp:723
CycleT * getCycle(const BlockT *Block) const
Find the innermost cycle containing a given block.
LLVM_ABI bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
Definition Globals.cpp:408
bool hasLocalLinkage() const
static LLVM_ABI bool compare(const APInt &LHS, const APInt &RHS, ICmpInst::Predicate Pred)
Return result of LHS Pred RHS comparison.
Value * CreatePtrAdd(Value *Ptr, Value *Offset, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
Definition IRBuilder.h:2092
ConstantInt * getInt64(uint64_t C)
Get a constant 64-bit value.
Definition IRBuilder.h:482
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2893
LLVM_ABI Instruction * clone() const
Create a copy of 'this' instruction that is identical in all ways except the following:
LLVM_ABI bool isLifetimeStartOrEnd() const LLVM_READONLY
Return true if the instruction is a llvm.lifetime.start or llvm.lifetime.end marker.
bool mayReadOrWriteMemory() const
Return true if this instruction may read or write memory.
LLVM_ABI bool mayWriteToMemory() const LLVM_READONLY
Return true if this instruction may modify memory.
bool hasMetadata() const
Return true if this instruction has any metadata attached to it.
LLVM_ABI void insertBefore(InstListType::iterator InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified position.
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
LLVM_ABI const Function * getFunction() const
Return the function this instruction belongs to.
LLVM_ABI BasicBlock * getSuccessor(unsigned Idx) const LLVM_READONLY
Return the specified successor. This instruction must be a terminator.
LLVM_ABI bool mayHaveSideEffects() const LLVM_READONLY
Return true if the instruction may have side effects.
bool isTerminator() const
LLVM_ABI bool mayReadFromMemory() const LLVM_READONLY
Return true if this instruction may read memory.
LLVM_ABI void setMetadata(unsigned KindID, MDNode *Node)
Set the metadata of the specified kind to the specified node.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this instruction belongs to.
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:68
LLVM_ABI ConstantRange getConstantRange(Value *V, Instruction *CxtI, bool UndefAllowed)
Return the ConstantRange constraint that is known to hold for the specified value at the specified in...
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition Metadata.h:1565
static LLVM_ABI MDNode * getMostGenericRange(MDNode *A, MDNode *B)
bool empty() const
Definition MapVector.h:79
static MemoryEffectsBase readOnly()
Definition ModRef.h:133
bool doesNotAccessMemory() const
Whether this function accesses no memory.
Definition ModRef.h:246
static MemoryEffectsBase argMemOnly(ModRefInfo MR=ModRefInfo::ModRef)
Definition ModRef.h:143
static MemoryEffectsBase inaccessibleMemOnly(ModRefInfo MR=ModRefInfo::ModRef)
Definition ModRef.h:149
bool onlyAccessesInaccessibleMem() const
Whether this function only (at most) accesses inaccessible memory.
Definition ModRef.h:265
ModRefInfo getModRef(Location Loc) const
Get ModRefInfo for the given Location.
Definition ModRef.h:219
bool onlyAccessesArgPointees() const
Whether this function only (at most) accesses argument memory.
Definition ModRef.h:255
bool onlyReadsMemory() const
Whether this function only (at most) reads memory.
Definition ModRef.h:249
static MemoryEffectsBase writeOnly()
Definition ModRef.h:138
static MemoryEffectsBase inaccessibleOrArgMemOnly(ModRefInfo MR=ModRefInfo::ModRef)
Definition ModRef.h:166
static MemoryEffectsBase none()
Definition ModRef.h:128
bool onlyAccessesInaccessibleOrArgMem() const
Whether this function only (at most) accesses argument and inaccessible memory.
Definition ModRef.h:305
static MemoryEffectsBase unknown()
Definition ModRef.h:123
static LLVM_ABI std::optional< MemoryLocation > getOrNone(const Instruction *Inst)
static SizeOffsetValue unknown()
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
Value * getReturnValue() const
Convenience accessor. Returns null if there is no return value.
LLVM_ABI const SCEV * getSCEVAtScope(const SCEV *S, const Loop *L)
Return a SCEV expression for the specified value at the specified scope in the program.
LLVM_ABI const SCEV * getSCEV(Value *V)
Return a SCEV expression for the full generality of the specified expression.
LLVM_ABI unsigned getSmallConstantMaxTripCount(const Loop *L, SmallVectorImpl< const SCEVPredicate * > *Predicates=nullptr)
Returns the upper bound of the loop trip count as a normal unsigned value.
ConstantRange getUnsignedRange(const SCEV *S)
Determine the unsigned range for a particular SCEV.
A vector that has set insertion semantics.
Definition SetVector.h:57
size_type size() const
Determine the number of elements in the SetVector.
Definition SetVector.h:103
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition SetVector.h:151
bool erase(PtrType Ptr)
Remove pointer from the set.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
Definition SmallSet.h:184
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Used to lazily calculate structure layout information for a target machine, based on the DataLayout s...
Definition DataLayout.h:743
TypeSize getElementOffset(unsigned Idx) const
Definition DataLayout.h:774
TypeSize getElementOffsetInBits(unsigned Idx) const
Definition DataLayout.h:779
Class to represent struct types.
unsigned getNumElements() const
Random access to the elements.
Type * getElementType(unsigned N) const
LLVM_ABI bool areTypesABICompatible(const Function *Caller, const Function *Callee, ArrayRef< Type * > Types) const
LLVM_ABI unsigned getAssumedAddrSpace(const Value *V) const
LLVM_ABI bool hasVolatileVariant(Instruction *I, unsigned AddrSpace) const
Return true if the given instruction (assumed to be a memory access instruction) has a volatile varia...
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
LLVM_ABI unsigned getIntegerBitWidth() const
bool isPointerTy() const
True if this is an instance of PointerType.
Definition Type.h:282
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
bool isPtrOrPtrVectorTy() const
Return true if this is a pointer type or a vector of pointer types.
Definition Type.h:285
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:257
bool isVoidTy() const
Return true if this is 'void'.
Definition Type.h:141
static UncondBrInst * Create(BasicBlock *Target, InsertPosition InsertBefore=nullptr)
BasicBlock * getSuccessor(unsigned i=0) const
static LLVM_ABI UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
A Use represents the edge between a Value definition and its users.
Definition Use.h:35
User * getUser() const
Returns the User that contains this Use.
Definition Use.h:61
Value * get() const
Definition Use.h:55
const Use & getOperandUse(unsigned i) const
Definition User.h:220
LLVM_ABI bool isDroppable() const
A droppable user is a user for which uses can be dropped without affecting correctness and should be ...
Definition User.cpp:119
LLVM_ABI bool replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
Definition User.cpp:25
Value * getOperand(unsigned i) const
Definition User.h:207
unsigned getNumOperands() const
Definition User.h:229
ValueT lookup(const KeyT &Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
Definition ValueMap.h:167
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:255
static constexpr uint64_t MaximumAlignment
Definition Value.h:799
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:258
iterator_range< user_iterator > users()
Definition Value.h:426
LLVM_ABI const Value * stripAndAccumulateConstantOffsets(const DataLayout &DL, APInt &Offset, bool AllowNonInbounds, bool AllowInvariantGroup=false, function_ref< bool(Value &Value, APInt &Offset)> ExternalAnalysis=nullptr, bool LookThroughIntToPtr=false) const
Accumulate the constant offset this value has compared to a base pointer.
bool use_empty() const
Definition Value.h:346
static constexpr unsigned MaxAlignmentExponent
The maximum alignment for instructions.
Definition Value.h:798
iterator_range< use_iterator > uses()
Definition Value.h:380
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp: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:335
LLVM_ABI std::optional< Value * > combineOptionalValuesInAAValueLatice(const std::optional< Value * > &A, const std::optional< Value * > &B, Type *Ty)
Return the combination of A and B such that the result is a possible value of both.
LLVM_ABI bool isValidAtPosition(const ValueAndContext &VAC, InformationCache &InfoCache)
Return true if the value of VAC is a valid at the position of VAC, that is a constant,...
LLVM_ABI bool isAssumedThreadLocalObject(Attributor &A, Value &Obj, const AbstractAttribute &QueryingAA)
Return true if Obj is assumed to be a thread local object.
LLVM_ABI bool isGPUConstantAddressSpace(const Module &M, unsigned AS)
Check if the given address space AS corresponds to a GPU constant address space for the target triple...
LLVM_ABI bool isDynamicallyUnique(Attributor &A, const AbstractAttribute &QueryingAA, const Value &V, bool ForAnalysisOnly=true)
Return true if V is dynamically unique, that is, there are no two "instances" of V at runtime with di...
LLVM_ABI bool getPotentialCopiesOfStoredValue(Attributor &A, StoreInst &SI, SmallSetVector< Value *, 4 > &PotentialCopies, const AbstractAttribute &QueryingAA, bool &UsedAssumedInformation, bool OnlyExact=false)
Collect all potential values of the one stored by SI into PotentialCopies.
LLVM_ABI bool isGPUSharedAddressSpace(const Module &M, unsigned AS)
Check if the given address space AS corresponds to a GPU shared address space for the target triple i...
LLVM_ABI bool isGPULocalAddressSpace(const Module &M, unsigned AS)
Check if the given address space AS corresponds to a GPU local/private address space for the target t...
SmallPtrSet< Instruction *, 4 > InstExclusionSetTy
Definition Attributor.h:166
LLVM_ABI bool isGPU(const Module &M)
Return true iff M target a GPU (and we can use GPU AS reasoning).
ValueScope
Flags to distinguish intra-procedural queries from potentially inter-procedural queries.
Definition Attributor.h:194
@ Intraprocedural
Definition Attributor.h:195
@ Interprocedural
Definition Attributor.h:196
LLVM_ABI bool isValidInScope(const Value &V, const Function *Scope)
Return true if V is a valid value in Scope, that is a constant or an instruction/argument of Scope.
LLVM_ABI bool isPotentiallyReachable(Attributor &A, const Instruction &FromI, const Instruction &ToI, const AbstractAttribute &QueryingAA, const AA::InstExclusionSetTy *ExclusionSet=nullptr, std::function< bool(const Function &F)> GoBackwardsCB=nullptr)
Return true if ToI is potentially reachable from FromI without running into any instruction in Exclus...
LLVM_ABI bool isNoSyncInst(Attributor &A, const Instruction &I, const AbstractAttribute &QueryingAA)
Return true if I is a nosync instruction.
bool hasAssumedIRAttr(Attributor &A, const AbstractAttribute *QueryingAA, const IRPosition &IRP, DepClassTy DepClass, bool &IsKnown, bool IgnoreSubsumingPositions=false, const AAType **AAPtr=nullptr)
Helper to avoid creating an AA for IR Attributes that might already be set.
LLVM_ABI bool getPotentiallyLoadedValues(Attributor &A, LoadInst &LI, SmallSetVector< Value *, 4 > &PotentialValues, SmallSetVector< Instruction *, 4 > &PotentialValueOrigins, const AbstractAttribute &QueryingAA, bool &UsedAssumedInformation, bool OnlyExact=false)
Collect all potential values LI could read into PotentialValues.
LLVM_ABI Value * getWithType(Value &V, Type &Ty)
Try to convert V to type Ty without introducing new instructions.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char Attrs[]
Key for Kernel::Metadata::mAttrs.
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
@ BasicBlock
Various leaf nodes.
Definition ISDOpcodes.h:81
@ Unsupported
This operation is completely unsupported on the target.
Offsets
Offsets in bytes from the start of the input buffer.
@ SingleThread
Synchronized with respect to signal handlers executing in the same thread.
Definition LLVMContext.h:55
@ CE
Windows NT (Windows on ARM)
Definition MCAsmInfo.h:50
@ Valid
The data is already valid.
initializer< Ty > init(const Ty &Val)
LocationClass< Ty > location(Ty &L)
unsigned combineHashValue(unsigned a, unsigned b)
Simplistic combination of 32-bit hash values into 32-bit hash values.
ElementType
The element type of an SRV or UAV resource.
Definition DXILABI.h:68
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > dyn_extract_or_null(Y &&MD)
Extract a Value from Metadata, if any, allowing null.
Definition Metadata.h:709
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > extract(Y &&MD)
Extract a Value from Metadata.
Definition Metadata.h:668
@ User
could "use" a pointer
DiagnosticInfoOptimizationBase::Argument NV
NodeAddr< UseNode * > Use
Definition RDFGraph.h:387
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:573
@ Length
Definition DWP.cpp:573
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:1739
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:1669
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:386
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:1703
LLVM_ABI raw_fd_ostream & outs()
This returns a reference to a raw_fd_ostream for standard output.
LLVM_ABI Value * getAllocAlignment(const CallBase *V, const TargetLibraryInfo *TLI)
Gets the alignment argument for an aligned_alloc-like function, using either built-in knowledge based...
auto dyn_cast_if_present(const Y &Val)
dyn_cast_if_present<X> - Functionally identical to dyn_cast, except that a null (or none in the case ...
Definition Casting.h:732
LLVM_ABI Value * simplifyInstructionWithOperands(Instruction *I, ArrayRef< Value * > NewOps, const SimplifyQuery &Q)
Like simplifyInstruction but the operands of I are replaced with NewOps.
Value * GetPointerBaseWithConstantOffset(Value *Ptr, int64_t &Offset, const DataLayout &DL, bool AllowNonInbounds=true)
Analyze the specified pointer to see if it can be expressed as a base pointer plus a constant offset.
scc_iterator< T > scc_begin(const T &G)
Construct the begin iterator for a deduced graph type T.
LLVM_ABI bool isIntrinsicReturningPointerAliasingArgumentWithoutCapturing(const CallBase *Call, bool MustPreserveOffset)
{launder,strip}.invariant.group returns pointer that aliases its argument, and it only captures point...
LLVM_ABI bool isNoAliasCall(const Value *V)
Return true if this pointer is returned by a noalias function.
MemoryEffectsBase< IRMemLocation > MemoryEffects
Summary of how a function affects memory in the program.
Definition ModRef.h:356
raw_ostream & WriteGraph(raw_ostream &O, const GraphType &G, bool ShortNames=false, const Twine &Title="")
LLVM_ABI bool isSafeToSpeculativelyExecute(const Instruction *I, const Instruction *CtxI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr, const TargetLibraryInfo *TLI=nullptr, bool UseVariableInfo=true, bool IgnoreUBImplyingAttrs=true)
Return true if the instruction does not have any effects besides calculating the result and does not ...
bool isa_and_nonnull(const Y &Val)
Definition Casting.h:676
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
LLVM_ABI ConstantRange getConstantRangeFromMetadata(const MDNode &RangeMD)
Parse out a conservative ConstantRange from !range metadata.
auto map_range(ContainerTy &&C, FuncTy F)
Return a range that applies F to the elements of C.
Definition STLExtras.h:365
const Value * getPointerOperand(const Value *V)
A helper function that returns the pointer operand of a load, store or GEP instruction.
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
CycleInfo::CycleT Cycle
Definition CycleInfo.h:26
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1746
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Definition MathExtras.h:331
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition MathExtras.h:279
PotentialValuesState< std::pair< AA::ValueAndContext, AA::ValueScope > > PotentialLLVMValuesState
void sort(IteratorTy Start, IteratorTy End)
Definition STLExtras.h:1636
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:374
LLVM_ABI bool wouldInstructionBeTriviallyDead(const Instruction *I, const TargetLibraryInfo *TLI=nullptr)
Return true if the result produced by the instruction would have no side effects if it was not used.
Definition Local.cpp:422
bool set_union(S1Ty &S1, const S2Ty &S2)
set_union(A, B) - Compute A := A u B, return whether A changed.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
LLVM_ABI CallBase & promoteCall(CallBase &CB, Function *Callee, CastInst **RetBitCast=nullptr)
Promote the given indirect call site to unconditionally call Callee.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
LLVM_ABI bool hasAssumption(const Function &F, const KnownAssumptionString &AssumptionStr)
Return true if F has the assumption AssumptionStr attached.
LLVM_ABI RetainedKnowledge getKnowledgeFromUse(const Use *U, ArrayRef< Attribute::AttrKind > AttrKinds)
Return a valid Knowledge associated to the Use U if its Attribute kind is in AttrKinds.
@ Success
The lock was released successfully.
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
LLVM_ABI bool isKnownNonZero(const Value *V, const SimplifyQuery &Q, unsigned Depth=0)
Return true if the given value is known to be non-zero when defined.
AtomicOrdering
Atomic ordering for LLVM's memory model.
@ Other
Any other memory.
Definition ModRef.h:68
PotentialValuesState< APInt > PotentialConstantIntValuesState
TargetTransformInfo TTI
std::string join(IteratorT Begin, IteratorT End, StringRef Separator)
Joins the strings in the range [Begin, End), adding Separator between the elements.
IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >
InterleavedRange< Range > interleaved_array(const Range &R, StringRef Separator=", ")
Output range R as an array of interleaved elements.
ChangeStatus clampStateAndIndicateChange< DerefState >(DerefState &S, const DerefState &R)
void RemapInstruction(Instruction *I, ValueToValueMapTy &VM, RemapFlags Flags=RF_None, ValueMapTypeRemapper *TypeMapper=nullptr, ValueMaterializer *Materializer=nullptr, const MetadataPredicate *IdentityMD=nullptr)
Convert the instruction operands from referencing the current values into those specified by VM.
DWARFExpression::Operation Op
LLVM_ABI bool isGuaranteedNotToBeUndefOrPoison(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Return true if this function can prove that V does not have undef bits and is never poison.
ArrayRef(const T &OneElt) -> ArrayRef< T >
LLVM_ABI Value * getFreedOperand(const CallBase *CB, const TargetLibraryInfo *TLI)
If this if a call to a free function, return the freed operand.
ChangeStatus clampStateAndIndicateChange(StateType &S, const StateType &R)
Helper function to clamp a state S of type StateType with the information in R and indicate/return if...
constexpr unsigned BitWidth
ValueMap< const Value *, WeakTrackingVH > ValueToValueMapTy
auto pred_begin(const MachineBasicBlock *BB)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
iterator_range< pointer_iterator< WrappedIteratorT > > make_pointer_range(RangeT &&Range)
Definition iterator.h:368
ChangeStatus
{
Definition Attributor.h:485
LLVM_ABI std::optional< APInt > getAllocSize(const CallBase *CB, const TargetLibraryInfo *TLI, function_ref< const Value *(const Value *)> Mapper=[](const Value *V) { return V;})
Return the size of the requested allocation.
LLVM_ABI DenseSet< StringRef > getAssumptions(const Function &F)
Return the set of all assumptions for the function F.
Align assumeAligned(uint64_t Value)
Treats the value 0 as a 1, so Align is always at least 1.
Definition Alignment.h:100
LLVM_ABI Instruction * SplitBlockAndInsertIfThen(Value *Cond, BasicBlock::iterator SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, BasicBlock *ThenBlock=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...
@ OPTIONAL
The target may be valid if the source is not.
Definition Attributor.h:497
@ NONE
Do not track a dependence between source and target.
Definition Attributor.h:498
@ REQUIRED
The target cannot be valid if the source is not.
Definition Attributor.h:496
LLVM_ABI UseCaptureInfo DetermineUseCaptureKind(const Use &U, const Value *Base)
Determine what kind of capture behaviour U may exhibit.
LLVM_ABI Value * simplifyCmpInst(CmpPredicate Predicate, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for a CmpInst, fold the result or return null.
LLVM_ABI bool mayContainIrreducibleControl(const Function &F, const LoopInfo *LI)
BumpPtrAllocatorImpl<> BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
Definition Allocator.h:390
T bit_floor(T Value)
Returns the largest integral power of two no greater than Value if Value is nonzero.
Definition bit.h:347
LLVM_ABI const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=MaxLookupSearchDepth)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
bool capturesNothing(CaptureComponents CC)
Definition ModRef.h:375
LLVM_ABI bool isIdentifiedObject(const Value *V)
Return true if this pointer refers to a distinct and identifiable object.
bool capturesAnyProvenance(CaptureComponents CC)
Definition ModRef.h:400
constexpr StringRef AssumptionAttrKey
The key we use for assumption attributes.
Definition Assumptions.h:29
constexpr bool isCallableCC(CallingConv::ID CC)
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:862
A type to track pointer/struct usage and accesses for AAPointerInfo.
bool forallInterferingAccesses(AA::RangeTy Range, F CB) const
See AAPointerInfo::forallInterferingAccesses.
AAPointerInfo::const_bin_iterator end() const
ChangeStatus addAccess(Attributor &A, const AAPointerInfo::RangeList &Ranges, Instruction &I, std::optional< Value * > Content, AAPointerInfo::AccessKind Kind, Type *Ty, Instruction *RemoteI=nullptr)
Add a new Access to the state at offset Offset and with size Size.
DenseMap< const Instruction *, SmallVector< unsigned > > RemoteIMap
AAPointerInfo::const_bin_iterator begin() const
AAPointerInfo::OffsetInfo ReturnedOffsets
Flag to determine if the underlying pointer is reaching a return statement in the associated function...
State(State &&SIS)=default
const AAPointerInfo::Access & getAccess(unsigned Index) const
SmallVector< AAPointerInfo::Access > AccessList
bool isAtFixpoint() const override
See AbstractState::isAtFixpoint().
bool forallInterferingAccesses(Instruction &I, F CB, AA::RangeTy &Range) const
See AAPointerInfo::forallInterferingAccesses.
static State getWorstState(const State &SIS)
Return the worst possible representable state.
AAPointerInfo::OffsetBinsTy OffsetBins
ChangeStatus indicateOptimisticFixpoint() override
See AbstractState::indicateOptimisticFixpoint().
ChangeStatus indicatePessimisticFixpoint() override
See AbstractState::indicatePessimisticFixpoint().
static State getBestState(const State &SIS)
Return the best possible representable state.
bool isValidState() const override
See AbstractState::isValidState().
----------------—AAIntraFnReachability Attribute-----------------------—
ReachabilityQueryInfo(const ReachabilityQueryInfo &RQI)
unsigned Hash
Precomputed hash for this RQI.
const Instruction * From
Start here,.
Reachable Result
and remember if it worked:
ReachabilityQueryInfo(const Instruction *From, const ToTy *To)
ReachabilityQueryInfo(Attributor &A, const Instruction &From, const ToTy &To, const AA::InstExclusionSetTy *ES, bool MakeUnique)
Constructor replacement to ensure unique and stable sets are used for the cache.
const ToTy * To
reach this place,
const AA::InstExclusionSetTy * ExclusionSet
without going through any of these instructions,
An abstract interface for address space information.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for all align attributes.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
Align getKnownAlign() const
Return known alignment.
static LLVM_ABI const char ID
An abstract attribute for getting assumption information.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract state for querying live call edges.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract Attribute for specializing "dynamic" components of denormal_fpenv to a known denormal mod...
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for all dereferenceable attribute.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for llvm::GlobalValue information interference.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for indirect call information interference.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface to track if a value leaves it's defining function instance.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract Attribute for computing reachability between functions.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
bool canReach(Attributor &A, const Function &Fn) const
If the function represented by this possition can reach Fn.
virtual bool instructionCanReach(Attributor &A, const Instruction &Inst, const Function &Fn, const AA::InstExclusionSetTy *ExclusionSet=nullptr) const =0
Can Inst reach Fn.
An abstract interface to determine reachability of point A to B.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for identifying pointers from which loads can be marked invariant.
static LLVM_ABI const char ID
Unique ID (due to the unique address).
An abstract interface for liveness abstract attribute.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for memory access kind related attributes (readnone/readonly/writeonly).
bool isAssumedReadOnly() const
Return true if we assume that the underlying value is not accessed (=written) in its respective scope...
bool isKnownReadNone() const
Return true if we know that the underlying value is not read or accessed in its respective scope.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
bool isAssumedReadNone() const
Return true if we assume that the underlying value is not read or accessed in its respective scope.
An abstract interface for all memory location attributes (readnone/argmemonly/inaccessiblememonly/ina...
static LLVM_ABI std::string getMemoryLocationsAsStr(MemoryLocationsKind MLK)
Return the locations encoded by MLK as a readable string.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
StateType::base_t MemoryLocationsKind
An abstract interface for all nonnull attributes.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for potential address space information.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for all noalias attributes.
static LLVM_ABI bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
See IRAttribute::isImpliedByIR.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for all nocapture attributes.
@ NO_CAPTURE_MAYBE_RETURNED
If we do not capture the value in memory or through integers we can only communicate it back as a der...
@ NO_CAPTURE
If we do not capture the value in memory, through integers, or as a derived pointer we know it is not...
static LLVM_ABI const char ID
Unique ID (due to the unique address)
bool isAssumedNoCaptureMaybeReturned() const
Return true if we assume that the underlying value is not captured in its respective scope but we all...
static LLVM_ABI bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
See IRAttribute::isImpliedByIR.
static LLVM_ABI void determineFunctionCaptureCapabilities(const IRPosition &IRP, const Function &F, BitIntegerState &State)
Update State according to the capture capabilities of F for position IRP.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An AbstractAttribute for nofree.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract attribute for norecurse.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An AbstractAttribute for noreturn.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI bool isAlignedBarrier(const CallBase &CB, bool ExecutedAligned)
Helper function to determine if CB is an aligned (GPU) barrier.
static LLVM_ABI bool isNonRelaxedAtomic(const Instruction *I)
Helper function used to determine whether an instruction is non-relaxed atomic.
An abstract interface for all noundef attributes.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
See IRAttribute::isImpliedByIR.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract Attribute for determining the necessity of the convergent attribute.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for all nonnull attributes.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
See AbstractAttribute::isImpliedByIR(...).
An access description.
A helper containing a list of offsets computed for a Use.
A container for a list of ranges.
static void set_difference(const RangeList &L, const RangeList &R, RangeList &D)
Copy ranges from L that are not in R, into D.
An abstract interface for struct information.
virtual bool reachesReturn() const =0
OffsetBinsTy::const_iterator const_bin_iterator
virtual const_bin_iterator begin() const =0
DenseMap< AA::RangeTy, SmallSet< unsigned, 4 > > OffsetBinsTy
static LLVM_ABI const char ID
Unique ID (due to the unique address)
virtual int64_t numOffsetBins() const =0
An abstract interface for potential values analysis.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
friend struct Attributor
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI Value * getSingleValue(Attributor &A, const AbstractAttribute &AA, const IRPosition &IRP, SmallVectorImpl< AA::ValueAndContext > &Values)
Extract the single value in Values if any.
An abstract interface for privatizability.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract attribute for undefined behavior.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract attribute for getting all assumption underlying objects.
virtual bool forallUnderlyingObjects(function_ref< bool(Value &)> Pred, AA::ValueScope Scope=AA::Interprocedural) const =0
Check Pred on all underlying objects in Scope collected so far.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for range value analysis.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for value simplify abstract attribute.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract attribute for willreturn.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
Helper to represent an access offset and size, with logic to deal with uncertainty and check for over...
Definition Attributor.h:253
static constexpr int64_t Unknown
Definition Attributor.h:332
static RangeTy getUnknown()
Definition Attributor.h:259
Value * getValue() const
Definition Attributor.h:206
const Instruction * getCtxI() const
Definition Attributor.h:207
Base struct for all "concrete attribute" deductions.
void print(raw_ostream &OS) const
Helper functions, for debug purposes only.
virtual StateType & getState()=0
Return the internal abstract state for inspection.
AbstractState StateType
An interface to query the internal state of an abstract attribute.
virtual bool isAtFixpoint() const =0
Return if this abstract state is fixed, thus does not need to be updated if information changes as it...
virtual bool isValidState() const =0
Return if this abstract state is in a valid state.
Helper for AA::PointerInfo::Access DenseMap/Set usage ignoring everythign but the instruction.
static unsigned getHashValue(const Access &A)
DenseMapInfo< Instruction * > Base
static bool isEqual(const Access &LHS, const Access &RHS)
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
Definition Alignment.h:77
std::function< void( const ArgumentReplacementInfo &, Function &, Function::arg_iterator)> CalleeRepairCBTy
Callee repair callback type.
const Argument & getReplacedArg() const
std::function< void(const ArgumentReplacementInfo &, AbstractCallSite, SmallVectorImpl< Value * > &)> ACSRepairCBTy
Abstract call site (ACS) repair callback type.
The fixpoint analysis framework that orchestrates the attribute deduction.
std::function< std::optional< Value * >( const IRPosition &, const AbstractAttribute *, bool &)> SimplifictionCallbackTy
Register CB as a simplification callback.
Specialization of the integer state for a bit-wise encoding.
BitIntegerState & addKnownBits(base_t Bits)
Add the bits in BitsEncoding to the "known bits".
Simple wrapper for a single bit (boolean) state.
static constexpr DenormalFPEnv getDefault()
static unsigned getHashValue(const Access &A)
static bool isEqual(const Access &LHS, const Access &RHS)
static bool isEqual(const AA::RangeTy &A, const AA::RangeTy B)
static unsigned getHashValue(const AA::RangeTy &Range)
DenseMapInfo< std::pair< const Instruction *, const ToTy * > > PairDMI
static bool isEqual(const ReachabilityQueryInfo< ToTy > *LHS, const ReachabilityQueryInfo< ToTy > *RHS)
DenseMapInfo< const AA::InstExclusionSetTy * > InstSetDMI
static unsigned getHashValue(const ReachabilityQueryInfo< ToTy > *RQI)
An information struct used to provide DenseMap with the various necessary components for a given valu...
State for dereferenceable attribute.
IncIntegerState DerefBytesState
State representing for dereferenceable bytes.
ChangeStatus manifest(Attributor &A) override
See AbstractAttribute::manifest(...).
Helper to describe and deal with positions in the LLVM-IR.
Definition Attributor.h:582
Function * getAssociatedFunction() const
Return the associated function, if any.
Definition Attributor.h:713
static const IRPosition callsite_returned(const CallBase &CB)
Create a position describing the returned value of CB.
Definition Attributor.h:650
static const IRPosition returned(const Function &F, const CallBaseContext *CBContext=nullptr)
Create a position describing the returned value of F.
Definition Attributor.h:632
LLVM_ABI Argument * getAssociatedArgument() const
Return the associated argument, if any.
static const IRPosition value(const Value &V, const CallBaseContext *CBContext=nullptr)
Create a position describing the value of V.
Definition Attributor.h:606
CallBase CallBaseContext
Definition Attributor.h:585
int getCalleeArgNo() const
Return the callee argument number of the associated value if it is an argument or call site argument,...
Definition Attributor.h:800
static const IRPosition inst(const Instruction &I, const CallBaseContext *CBContext=nullptr)
Create a position describing the instruction I.
Definition Attributor.h:618
static const IRPosition callsite_argument(const CallBase &CB, unsigned ArgNo)
Create a position describing the argument of CB at position ArgNo.
Definition Attributor.h:655
@ IRP_ARGUMENT
An attribute for a function argument.
Definition Attributor.h:596
@ IRP_RETURNED
An attribute for the function return value.
Definition Attributor.h:592
@ IRP_CALL_SITE
An attribute for a call site (function scope).
Definition Attributor.h:595
@ IRP_CALL_SITE_RETURNED
An attribute for a call site return value.
Definition Attributor.h:593
@ IRP_FUNCTION
An attribute for a function (scope).
Definition Attributor.h:594
@ IRP_CALL_SITE_ARGUMENT
An attribute for a call site argument.
Definition Attributor.h:597
@ IRP_INVALID
An invalid position.
Definition Attributor.h:589
Instruction * getCtxI() const
Return the context instruction, if any.
Definition Attributor.h:766
static const IRPosition argument(const Argument &Arg, const CallBaseContext *CBContext=nullptr)
Create a position describing the argument Arg.
Definition Attributor.h:639
Type * getAssociatedType() const
Return the type this abstract attribute is associated with.
Definition Attributor.h:789
static const IRPosition function(const Function &F, const CallBaseContext *CBContext=nullptr)
Create a position describing the function scope of F.
Definition Attributor.h:625
const CallBaseContext * getCallBaseContext() const
Get the call base context from the position.
Definition Attributor.h:928
Value & getAssociatedValue() const
Return the value this abstract attribute is associated with.
Definition Attributor.h:780
Value & getAnchorValue() const
Return the value this abstract attribute is anchored with.
Definition Attributor.h:699
int getCallSiteArgNo() const
Return the call site argument number of the associated value if it is an argument or call site argume...
Definition Attributor.h:809
static const IRPosition function_scope(const IRPosition &IRP, const CallBaseContext *CBContext=nullptr)
Create a position with function scope matching the "context" of IRP.
Definition Attributor.h:678
Kind getPositionKind() const
Return the associated position kind.
Definition Attributor.h:878
bool isArgumentPosition() const
Return true if the position is an argument or call site argument.
Definition Attributor.h:910
static const IRPosition callsite_function(const CallBase &CB)
Create a position describing the function scope of CB.
Definition Attributor.h:645
Function * getAnchorScope() const
Return the Function surrounding the anchor value.
Definition Attributor.h:754
Data structure to hold cached (LLVM-IR) information.
TargetLibraryInfo * getTargetLibraryInfoForFunction(const Function &F)
Return TargetLibraryInfo for function F.
bool isOnlyUsedByAssume(const Instruction &I) const
AP::Result * getAnalysisResultForFunction(const Function &F, bool CachedOnly=false)
Return the analysis result from a pass AP for function F.
ConstantRange getKnown() const
Return the known state encoding.
ConstantRange getAssumed() const
Return the assumed state encoding.
base_t getAssumed() const
Return the assumed state encoding.
Helper that allows to insert a new assumption string in the known assumption set by creating a (stati...
Definition Assumptions.h:37
FPClassTest KnownFPClasses
Floating-point classes the value could be one of.
A "must be executed context" for a given program point PP is the set of instructions,...
iterator & end()
Return an universal end iterator.
bool findInContextOf(const Instruction *I, const Instruction *PP)
Helper to look for I in the context of PP.
iterator & begin(const Instruction *PP)
Return an iterator to explore the context around PP.
bool checkForAllContext(const Instruction *PP, function_ref< bool(const Instruction *)> Pred)
}
Helper to tie a abstract state implementation to an abstract attribute.
StateType & getState() override
See AbstractAttribute::getState(...).
CaptureComponents ResultCC
Components captured by the return value of the user of this Use.
LLVM_ABI bool unionAssumed(std::optional< Value * > Other)
Merge Other into the currently assumed simplified value.
std::optional< Value * > SimplifiedAssociatedValue
An assumed simplified value.
Type * Ty
The type of the original value.