LLVM 19.0.0git
AttributorAttributes.cpp
Go to the documentation of this file.
1//===- AttributorAttributes.cpp - Attributes for Attributor deduction -----===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// See the Attributor.h file comment and the class descriptions in that file for
10// more information.
11//
12//===----------------------------------------------------------------------===//
13
15
16#include "llvm/ADT/APInt.h"
17#include "llvm/ADT/ArrayRef.h"
19#include "llvm/ADT/MapVector.h"
21#include "llvm/ADT/STLExtras.h"
23#include "llvm/ADT/SetVector.h"
26#include "llvm/ADT/Statistic.h"
40#include "llvm/IR/Argument.h"
41#include "llvm/IR/Assumptions.h"
42#include "llvm/IR/Attributes.h"
43#include "llvm/IR/BasicBlock.h"
44#include "llvm/IR/Constant.h"
45#include "llvm/IR/Constants.h"
46#include "llvm/IR/DataLayout.h"
48#include "llvm/IR/GlobalValue.h"
49#include "llvm/IR/IRBuilder.h"
50#include "llvm/IR/InlineAsm.h"
51#include "llvm/IR/InstrTypes.h"
52#include "llvm/IR/Instruction.h"
55#include "llvm/IR/IntrinsicsAMDGPU.h"
56#include "llvm/IR/IntrinsicsNVPTX.h"
57#include "llvm/IR/LLVMContext.h"
58#include "llvm/IR/MDBuilder.h"
59#include "llvm/IR/NoFolder.h"
60#include "llvm/IR/Value.h"
61#include "llvm/IR/ValueHandle.h"
74#include <cassert>
75#include <numeric>
76#include <optional>
77#include <string>
78
79using namespace llvm;
80
81#define DEBUG_TYPE "attributor"
82
84 "attributor-manifest-internal", cl::Hidden,
85 cl::desc("Manifest Attributor internal string attributes."),
86 cl::init(false));
87
88static cl::opt<int> MaxHeapToStackSize("max-heap-to-stack-size", cl::init(128),
90
91template <>
93
95
97 "attributor-max-potential-values", cl::Hidden,
98 cl::desc("Maximum number of potential values to be "
99 "tracked for each position."),
101 cl::init(7));
102
104 "attributor-max-potential-values-iterations", cl::Hidden,
105 cl::desc(
106 "Maximum number of iterations we keep dismantling potential values."),
107 cl::init(64));
108
109STATISTIC(NumAAs, "Number of abstract attributes created");
110
111// Some helper macros to deal with statistics tracking.
112//
113// Usage:
114// For simple IR attribute tracking overload trackStatistics in the abstract
115// attribute and choose the right STATS_DECLTRACK_********* macro,
116// e.g.,:
117// void trackStatistics() const override {
118// STATS_DECLTRACK_ARG_ATTR(returned)
119// }
120// If there is a single "increment" side one can use the macro
121// STATS_DECLTRACK with a custom message. If there are multiple increment
122// sides, STATS_DECL and STATS_TRACK can also be used separately.
123//
124#define BUILD_STAT_MSG_IR_ATTR(TYPE, NAME) \
125 ("Number of " #TYPE " marked '" #NAME "'")
126#define BUILD_STAT_NAME(NAME, TYPE) NumIR##TYPE##_##NAME
127#define STATS_DECL_(NAME, MSG) STATISTIC(NAME, MSG);
128#define STATS_DECL(NAME, TYPE, MSG) \
129 STATS_DECL_(BUILD_STAT_NAME(NAME, TYPE), MSG);
130#define STATS_TRACK(NAME, TYPE) ++(BUILD_STAT_NAME(NAME, TYPE));
131#define STATS_DECLTRACK(NAME, TYPE, MSG) \
132 { \
133 STATS_DECL(NAME, TYPE, MSG) \
134 STATS_TRACK(NAME, TYPE) \
135 }
136#define STATS_DECLTRACK_ARG_ATTR(NAME) \
137 STATS_DECLTRACK(NAME, Arguments, BUILD_STAT_MSG_IR_ATTR(arguments, NAME))
138#define STATS_DECLTRACK_CSARG_ATTR(NAME) \
139 STATS_DECLTRACK(NAME, CSArguments, \
140 BUILD_STAT_MSG_IR_ATTR(call site arguments, NAME))
141#define STATS_DECLTRACK_FN_ATTR(NAME) \
142 STATS_DECLTRACK(NAME, Function, BUILD_STAT_MSG_IR_ATTR(functions, NAME))
143#define STATS_DECLTRACK_CS_ATTR(NAME) \
144 STATS_DECLTRACK(NAME, CS, BUILD_STAT_MSG_IR_ATTR(call site, NAME))
145#define STATS_DECLTRACK_FNRET_ATTR(NAME) \
146 STATS_DECLTRACK(NAME, FunctionReturn, \
147 BUILD_STAT_MSG_IR_ATTR(function returns, NAME))
148#define STATS_DECLTRACK_CSRET_ATTR(NAME) \
149 STATS_DECLTRACK(NAME, CSReturn, \
150 BUILD_STAT_MSG_IR_ATTR(call site returns, NAME))
151#define STATS_DECLTRACK_FLOATING_ATTR(NAME) \
152 STATS_DECLTRACK(NAME, Floating, \
153 ("Number of floating values known to be '" #NAME "'"))
154
155// Specialization of the operator<< for abstract attributes subclasses. This
156// disambiguates situations where multiple operators are applicable.
157namespace llvm {
158#define PIPE_OPERATOR(CLASS) \
159 raw_ostream &operator<<(raw_ostream &OS, const CLASS &AA) { \
160 return OS << static_cast<const AbstractAttribute &>(AA); \
161 }
162
200
201#undef PIPE_OPERATOR
202
203template <>
205 const DerefState &R) {
206 ChangeStatus CS0 =
207 clampStateAndIndicateChange(S.DerefBytesState, R.DerefBytesState);
208 ChangeStatus CS1 = clampStateAndIndicateChange(S.GlobalState, R.GlobalState);
209 return CS0 | CS1;
210}
211
212} // namespace llvm
213
214static bool mayBeInCycle(const CycleInfo *CI, const Instruction *I,
215 bool HeaderOnly, Cycle **CPtr = nullptr) {
216 if (!CI)
217 return true;
218 auto *BB = I->getParent();
219 auto *C = CI->getCycle(BB);
220 if (!C)
221 return false;
222 if (CPtr)
223 *CPtr = C;
224 return !HeaderOnly || BB == C->getHeader();
225}
226
227/// Checks if a type could have padding bytes.
228static bool isDenselyPacked(Type *Ty, const DataLayout &DL) {
229 // There is no size information, so be conservative.
230 if (!Ty->isSized())
231 return false;
232
233 // If the alloc size is not equal to the storage size, then there are padding
234 // bytes. For x86_fp80 on x86-64, size: 80 alloc size: 128.
235 if (DL.getTypeSizeInBits(Ty) != DL.getTypeAllocSizeInBits(Ty))
236 return false;
237
238 // FIXME: This isn't the right way to check for padding in vectors with
239 // non-byte-size elements.
240 if (VectorType *SeqTy = dyn_cast<VectorType>(Ty))
241 return isDenselyPacked(SeqTy->getElementType(), DL);
242
243 // For array types, check for padding within members.
244 if (ArrayType *SeqTy = dyn_cast<ArrayType>(Ty))
245 return isDenselyPacked(SeqTy->getElementType(), DL);
246
247 if (!isa<StructType>(Ty))
248 return true;
249
250 // Check for padding within and between elements of a struct.
251 StructType *StructTy = cast<StructType>(Ty);
252 const StructLayout *Layout = DL.getStructLayout(StructTy);
253 uint64_t StartPos = 0;
254 for (unsigned I = 0, E = StructTy->getNumElements(); I < E; ++I) {
255 Type *ElTy = StructTy->getElementType(I);
256 if (!isDenselyPacked(ElTy, DL))
257 return false;
258 if (StartPos != Layout->getElementOffsetInBits(I))
259 return false;
260 StartPos += DL.getTypeAllocSizeInBits(ElTy);
261 }
262
263 return true;
264}
265
266/// Get pointer operand of memory accessing instruction. If \p I is
267/// not a memory accessing instruction, return nullptr. If \p AllowVolatile,
268/// is set to false and the instruction is volatile, return nullptr.
270 bool AllowVolatile) {
271 if (!AllowVolatile && I->isVolatile())
272 return nullptr;
273
274 if (auto *LI = dyn_cast<LoadInst>(I)) {
275 return LI->getPointerOperand();
276 }
277
278 if (auto *SI = dyn_cast<StoreInst>(I)) {
279 return SI->getPointerOperand();
280 }
281
282 if (auto *CXI = dyn_cast<AtomicCmpXchgInst>(I)) {
283 return CXI->getPointerOperand();
284 }
285
286 if (auto *RMWI = dyn_cast<AtomicRMWInst>(I)) {
287 return RMWI->getPointerOperand();
288 }
289
290 return nullptr;
291}
292
293/// Helper function to create a pointer based on \p Ptr, and advanced by \p
294/// Offset bytes.
296 IRBuilder<NoFolder> &IRB) {
297 LLVM_DEBUG(dbgs() << "Construct pointer: " << *Ptr << " + " << Offset
298 << "-bytes\n");
299
300 if (Offset)
301 Ptr = IRB.CreatePtrAdd(Ptr, IRB.getInt64(Offset),
302 Ptr->getName() + ".b" + Twine(Offset));
303 return Ptr;
304}
305
306static const Value *
308 const Value *Val, const DataLayout &DL, APInt &Offset,
309 bool GetMinOffset, bool AllowNonInbounds,
310 bool UseAssumed = false) {
311
312 auto AttributorAnalysis = [&](Value &V, APInt &ROffset) -> bool {
313 const IRPosition &Pos = IRPosition::value(V);
314 // Only track dependence if we are going to use the assumed info.
315 const AAValueConstantRange *ValueConstantRangeAA =
316 A.getAAFor<AAValueConstantRange>(QueryingAA, Pos,
317 UseAssumed ? DepClassTy::OPTIONAL
318 : DepClassTy::NONE);
319 if (!ValueConstantRangeAA)
320 return false;
321 ConstantRange Range = UseAssumed ? ValueConstantRangeAA->getAssumed()
322 : ValueConstantRangeAA->getKnown();
323 if (Range.isFullSet())
324 return false;
325
326 // We can only use the lower part of the range because the upper part can
327 // be higher than what the value can really be.
328 if (GetMinOffset)
329 ROffset = Range.getSignedMin();
330 else
331 ROffset = Range.getSignedMax();
332 return true;
333 };
334
335 return Val->stripAndAccumulateConstantOffsets(DL, Offset, AllowNonInbounds,
336 /* AllowInvariant */ true,
337 AttributorAnalysis);
338}
339
340static const Value *
342 const Value *Ptr, int64_t &BytesOffset,
343 const DataLayout &DL, bool AllowNonInbounds = false) {
344 APInt OffsetAPInt(DL.getIndexTypeSizeInBits(Ptr->getType()), 0);
345 const Value *Base =
346 stripAndAccumulateOffsets(A, QueryingAA, Ptr, DL, OffsetAPInt,
347 /* GetMinOffset */ true, AllowNonInbounds);
348
349 BytesOffset = OffsetAPInt.getSExtValue();
350 return Base;
351}
352
353/// Clamp the information known for all returned values of a function
354/// (identified by \p QueryingAA) into \p S.
355template <typename AAType, typename StateType = typename AAType::StateType,
356 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind,
357 bool RecurseForSelectAndPHI = true>
359 Attributor &A, const AAType &QueryingAA, StateType &S,
360 const IRPosition::CallBaseContext *CBContext = nullptr) {
361 LLVM_DEBUG(dbgs() << "[Attributor] Clamp return value states for "
362 << QueryingAA << " into " << S << "\n");
363
364 assert((QueryingAA.getIRPosition().getPositionKind() ==
366 QueryingAA.getIRPosition().getPositionKind() ==
368 "Can only clamp returned value states for a function returned or call "
369 "site returned position!");
370
371 // Use an optional state as there might not be any return values and we want
372 // to join (IntegerState::operator&) the state of all there are.
373 std::optional<StateType> T;
374
375 // Callback for each possibly returned value.
376 auto CheckReturnValue = [&](Value &RV) -> bool {
377 const IRPosition &RVPos = IRPosition::value(RV, CBContext);
378 // If possible, use the hasAssumedIRAttr interface.
379 if (Attribute::isEnumAttrKind(IRAttributeKind)) {
380 bool IsKnown;
381 return AA::hasAssumedIRAttr<IRAttributeKind>(
382 A, &QueryingAA, RVPos, DepClassTy::REQUIRED, IsKnown);
383 }
384
385 const AAType *AA =
386 A.getAAFor<AAType>(QueryingAA, RVPos, DepClassTy::REQUIRED);
387 if (!AA)
388 return false;
389 LLVM_DEBUG(dbgs() << "[Attributor] RV: " << RV
390 << " AA: " << AA->getAsStr(&A) << " @ " << RVPos << "\n");
391 const StateType &AAS = AA->getState();
392 if (!T)
393 T = StateType::getBestState(AAS);
394 *T &= AAS;
395 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS << " RV State: " << T
396 << "\n");
397 return T->isValidState();
398 };
399
400 if (!A.checkForAllReturnedValues(CheckReturnValue, QueryingAA,
401 AA::ValueScope::Intraprocedural,
402 RecurseForSelectAndPHI))
403 S.indicatePessimisticFixpoint();
404 else if (T)
405 S ^= *T;
406}
407
408namespace {
409/// Helper class for generic deduction: return value -> returned position.
410template <typename AAType, typename BaseType,
411 typename StateType = typename BaseType::StateType,
412 bool PropagateCallBaseContext = false,
413 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind,
414 bool RecurseForSelectAndPHI = true>
415struct AAReturnedFromReturnedValues : public BaseType {
416 AAReturnedFromReturnedValues(const IRPosition &IRP, Attributor &A)
417 : BaseType(IRP, A) {}
418
419 /// See AbstractAttribute::updateImpl(...).
420 ChangeStatus updateImpl(Attributor &A) override {
421 StateType S(StateType::getBestState(this->getState()));
422 clampReturnedValueStates<AAType, StateType, IRAttributeKind,
423 RecurseForSelectAndPHI>(
424 A, *this, S,
425 PropagateCallBaseContext ? this->getCallBaseContext() : nullptr);
426 // TODO: If we know we visited all returned values, thus no are assumed
427 // dead, we can take the known information from the state T.
428 return clampStateAndIndicateChange<StateType>(this->getState(), S);
429 }
430};
431
432/// Clamp the information known at all call sites for a given argument
433/// (identified by \p QueryingAA) into \p S.
434template <typename AAType, typename StateType = typename AAType::StateType,
435 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind>
436static void clampCallSiteArgumentStates(Attributor &A, const AAType &QueryingAA,
437 StateType &S) {
438 LLVM_DEBUG(dbgs() << "[Attributor] Clamp call site argument states for "
439 << QueryingAA << " into " << S << "\n");
440
441 assert(QueryingAA.getIRPosition().getPositionKind() ==
443 "Can only clamp call site argument states for an argument position!");
444
445 // Use an optional state as there might not be any return values and we want
446 // to join (IntegerState::operator&) the state of all there are.
447 std::optional<StateType> T;
448
449 // The argument number which is also the call site argument number.
450 unsigned ArgNo = QueryingAA.getIRPosition().getCallSiteArgNo();
451
452 auto CallSiteCheck = [&](AbstractCallSite ACS) {
453 const IRPosition &ACSArgPos = IRPosition::callsite_argument(ACS, ArgNo);
454 // Check if a coresponding argument was found or if it is on not associated
455 // (which can happen for callback calls).
456 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
457 return false;
458
459 // If possible, use the hasAssumedIRAttr interface.
460 if (Attribute::isEnumAttrKind(IRAttributeKind)) {
461 bool IsKnown;
462 return AA::hasAssumedIRAttr<IRAttributeKind>(
463 A, &QueryingAA, ACSArgPos, DepClassTy::REQUIRED, IsKnown);
464 }
465
466 const AAType *AA =
467 A.getAAFor<AAType>(QueryingAA, ACSArgPos, DepClassTy::REQUIRED);
468 if (!AA)
469 return false;
470 LLVM_DEBUG(dbgs() << "[Attributor] ACS: " << *ACS.getInstruction()
471 << " AA: " << AA->getAsStr(&A) << " @" << ACSArgPos
472 << "\n");
473 const StateType &AAS = AA->getState();
474 if (!T)
475 T = StateType::getBestState(AAS);
476 *T &= AAS;
477 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS << " CSA State: " << T
478 << "\n");
479 return T->isValidState();
480 };
481
482 bool UsedAssumedInformation = false;
483 if (!A.checkForAllCallSites(CallSiteCheck, QueryingAA, true,
484 UsedAssumedInformation))
485 S.indicatePessimisticFixpoint();
486 else if (T)
487 S ^= *T;
488}
489
490/// This function is the bridge between argument position and the call base
491/// context.
492template <typename AAType, typename BaseType,
493 typename StateType = typename AAType::StateType,
494 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind>
495bool getArgumentStateFromCallBaseContext(Attributor &A,
496 BaseType &QueryingAttribute,
497 IRPosition &Pos, StateType &State) {
499 "Expected an 'argument' position !");
500 const CallBase *CBContext = Pos.getCallBaseContext();
501 if (!CBContext)
502 return false;
503
504 int ArgNo = Pos.getCallSiteArgNo();
505 assert(ArgNo >= 0 && "Invalid Arg No!");
506 const IRPosition CBArgPos = IRPosition::callsite_argument(*CBContext, ArgNo);
507
508 // If possible, use the hasAssumedIRAttr interface.
509 if (Attribute::isEnumAttrKind(IRAttributeKind)) {
510 bool IsKnown;
511 return AA::hasAssumedIRAttr<IRAttributeKind>(
512 A, &QueryingAttribute, CBArgPos, DepClassTy::REQUIRED, IsKnown);
513 }
514
515 const auto *AA =
516 A.getAAFor<AAType>(QueryingAttribute, CBArgPos, DepClassTy::REQUIRED);
517 if (!AA)
518 return false;
519 const StateType &CBArgumentState =
520 static_cast<const StateType &>(AA->getState());
521
522 LLVM_DEBUG(dbgs() << "[Attributor] Briding Call site context to argument"
523 << "Position:" << Pos << "CB Arg state:" << CBArgumentState
524 << "\n");
525
526 // NOTE: If we want to do call site grouping it should happen here.
527 State ^= CBArgumentState;
528 return true;
529}
530
531/// Helper class for generic deduction: call site argument -> argument position.
532template <typename AAType, typename BaseType,
533 typename StateType = typename AAType::StateType,
534 bool BridgeCallBaseContext = false,
535 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind>
536struct AAArgumentFromCallSiteArguments : public BaseType {
537 AAArgumentFromCallSiteArguments(const IRPosition &IRP, Attributor &A)
538 : BaseType(IRP, A) {}
539
540 /// See AbstractAttribute::updateImpl(...).
541 ChangeStatus updateImpl(Attributor &A) override {
542 StateType S = StateType::getBestState(this->getState());
543
544 if (BridgeCallBaseContext) {
545 bool Success =
546 getArgumentStateFromCallBaseContext<AAType, BaseType, StateType,
547 IRAttributeKind>(
548 A, *this, this->getIRPosition(), S);
549 if (Success)
550 return clampStateAndIndicateChange<StateType>(this->getState(), S);
551 }
552 clampCallSiteArgumentStates<AAType, StateType, IRAttributeKind>(A, *this,
553 S);
554
555 // TODO: If we know we visited all incoming values, thus no are assumed
556 // dead, we can take the known information from the state T.
557 return clampStateAndIndicateChange<StateType>(this->getState(), S);
558 }
559};
560
561/// Helper class for generic replication: function returned -> cs returned.
562template <typename AAType, typename BaseType,
563 typename StateType = typename BaseType::StateType,
564 bool IntroduceCallBaseContext = false,
565 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind>
566struct AACalleeToCallSite : public BaseType {
567 AACalleeToCallSite(const IRPosition &IRP, Attributor &A) : BaseType(IRP, A) {}
568
569 /// See AbstractAttribute::updateImpl(...).
570 ChangeStatus updateImpl(Attributor &A) override {
571 auto IRPKind = this->getIRPosition().getPositionKind();
573 IRPKind == IRPosition::IRP_CALL_SITE) &&
574 "Can only wrap function returned positions for call site "
575 "returned positions!");
576 auto &S = this->getState();
577
578 CallBase &CB = cast<CallBase>(this->getAnchorValue());
579 if (IntroduceCallBaseContext)
580 LLVM_DEBUG(dbgs() << "[Attributor] Introducing call base context:" << CB
581 << "\n");
582
583 ChangeStatus Changed = ChangeStatus::UNCHANGED;
584 auto CalleePred = [&](ArrayRef<const Function *> Callees) {
585 for (const Function *Callee : Callees) {
586 IRPosition FnPos =
588 ? IRPosition::returned(*Callee,
589 IntroduceCallBaseContext ? &CB : nullptr)
591 *Callee, IntroduceCallBaseContext ? &CB : nullptr);
592 // If possible, use the hasAssumedIRAttr interface.
593 if (Attribute::isEnumAttrKind(IRAttributeKind)) {
594 bool IsKnown;
595 if (!AA::hasAssumedIRAttr<IRAttributeKind>(
596 A, this, FnPos, DepClassTy::REQUIRED, IsKnown))
597 return false;
598 continue;
599 }
600
601 const AAType *AA =
602 A.getAAFor<AAType>(*this, FnPos, DepClassTy::REQUIRED);
603 if (!AA)
604 return false;
605 Changed |= clampStateAndIndicateChange(S, AA->getState());
606 if (S.isAtFixpoint())
607 return S.isValidState();
608 }
609 return true;
610 };
611 if (!A.checkForAllCallees(CalleePred, *this, CB))
612 return S.indicatePessimisticFixpoint();
613 return Changed;
614 }
615};
616
617/// Helper function to accumulate uses.
618template <class AAType, typename StateType = typename AAType::StateType>
619static void followUsesInContext(AAType &AA, Attributor &A,
621 const Instruction *CtxI,
623 StateType &State) {
624 auto EIt = Explorer.begin(CtxI), EEnd = Explorer.end(CtxI);
625 for (unsigned u = 0; u < Uses.size(); ++u) {
626 const Use *U = Uses[u];
627 if (const Instruction *UserI = dyn_cast<Instruction>(U->getUser())) {
628 bool Found = Explorer.findInContextOf(UserI, EIt, EEnd);
629 if (Found && AA.followUseInMBEC(A, U, UserI, State))
630 for (const Use &Us : UserI->uses())
631 Uses.insert(&Us);
632 }
633 }
634}
635
636/// Use the must-be-executed-context around \p I to add information into \p S.
637/// The AAType class is required to have `followUseInMBEC` method with the
638/// following signature and behaviour:
639///
640/// bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I)
641/// U - Underlying use.
642/// I - The user of the \p U.
643/// Returns true if the value should be tracked transitively.
644///
645template <class AAType, typename StateType = typename AAType::StateType>
646static void followUsesInMBEC(AAType &AA, Attributor &A, StateType &S,
647 Instruction &CtxI) {
649 A.getInfoCache().getMustBeExecutedContextExplorer();
650 if (!Explorer)
651 return;
652
653 // Container for (transitive) uses of the associated value.
655 for (const Use &U : AA.getIRPosition().getAssociatedValue().uses())
656 Uses.insert(&U);
657
658 followUsesInContext<AAType>(AA, A, *Explorer, &CtxI, Uses, S);
659
660 if (S.isAtFixpoint())
661 return;
662
664 auto Pred = [&](const Instruction *I) {
665 if (const BranchInst *Br = dyn_cast<BranchInst>(I))
666 if (Br->isConditional())
667 BrInsts.push_back(Br);
668 return true;
669 };
670
671 // Here, accumulate conditional branch instructions in the context. We
672 // explore the child paths and collect the known states. The disjunction of
673 // those states can be merged to its own state. Let ParentState_i be a state
674 // to indicate the known information for an i-th branch instruction in the
675 // context. ChildStates are created for its successors respectively.
676 //
677 // ParentS_1 = ChildS_{1, 1} /\ ChildS_{1, 2} /\ ... /\ ChildS_{1, n_1}
678 // ParentS_2 = ChildS_{2, 1} /\ ChildS_{2, 2} /\ ... /\ ChildS_{2, n_2}
679 // ...
680 // ParentS_m = ChildS_{m, 1} /\ ChildS_{m, 2} /\ ... /\ ChildS_{m, n_m}
681 //
682 // Known State |= ParentS_1 \/ ParentS_2 \/... \/ ParentS_m
683 //
684 // FIXME: Currently, recursive branches are not handled. For example, we
685 // can't deduce that ptr must be dereferenced in below function.
686 //
687 // void f(int a, int c, int *ptr) {
688 // if(a)
689 // if (b) {
690 // *ptr = 0;
691 // } else {
692 // *ptr = 1;
693 // }
694 // else {
695 // if (b) {
696 // *ptr = 0;
697 // } else {
698 // *ptr = 1;
699 // }
700 // }
701 // }
702
703 Explorer->checkForAllContext(&CtxI, Pred);
704 for (const BranchInst *Br : BrInsts) {
705 StateType ParentState;
706
707 // The known state of the parent state is a conjunction of children's
708 // known states so it is initialized with a best state.
709 ParentState.indicateOptimisticFixpoint();
710
711 for (const BasicBlock *BB : Br->successors()) {
712 StateType ChildState;
713
714 size_t BeforeSize = Uses.size();
715 followUsesInContext(AA, A, *Explorer, &BB->front(), Uses, ChildState);
716
717 // Erase uses which only appear in the child.
718 for (auto It = Uses.begin() + BeforeSize; It != Uses.end();)
719 It = Uses.erase(It);
720
721 ParentState &= ChildState;
722 }
723
724 // Use only known state.
725 S += ParentState;
726 }
727}
728} // namespace
729
730/// ------------------------ PointerInfo ---------------------------------------
731
732namespace llvm {
733namespace AA {
734namespace PointerInfo {
735
736struct State;
737
738} // namespace PointerInfo
739} // namespace AA
740
741/// Helper for AA::PointerInfo::Access DenseMap/Set usage.
742template <>
745 static inline Access getEmptyKey();
746 static inline Access getTombstoneKey();
747 static unsigned getHashValue(const Access &A);
748 static bool isEqual(const Access &LHS, const Access &RHS);
749};
750
751/// Helper that allows RangeTy as a key in a DenseMap.
752template <> struct DenseMapInfo<AA::RangeTy> {
753 static inline AA::RangeTy getEmptyKey() {
754 auto EmptyKey = DenseMapInfo<int64_t>::getEmptyKey();
755 return AA::RangeTy{EmptyKey, EmptyKey};
756 }
757
758 static inline AA::RangeTy getTombstoneKey() {
759 auto TombstoneKey = DenseMapInfo<int64_t>::getTombstoneKey();
760 return AA::RangeTy{TombstoneKey, TombstoneKey};
761 }
762
763 static unsigned getHashValue(const AA::RangeTy &Range) {
767 }
768
769 static bool isEqual(const AA::RangeTy &A, const AA::RangeTy B) {
770 return A == B;
771 }
772};
773
774/// Helper for AA::PointerInfo::Access DenseMap/Set usage ignoring everythign
775/// but the instruction
776struct AccessAsInstructionInfo : DenseMapInfo<Instruction *> {
779 static inline Access getEmptyKey();
780 static inline Access getTombstoneKey();
781 static unsigned getHashValue(const Access &A);
782 static bool isEqual(const Access &LHS, const Access &RHS);
783};
784
785} // namespace llvm
786
787/// A type to track pointer/struct usage and accesses for AAPointerInfo.
789 /// Return the best possible representable state.
790 static State getBestState(const State &SIS) { return State(); }
791
792 /// Return the worst possible representable state.
793 static State getWorstState(const State &SIS) {
794 State R;
795 R.indicatePessimisticFixpoint();
796 return R;
797 }
798
799 State() = default;
800 State(State &&SIS) = default;
801
802 const State &getAssumed() const { return *this; }
803
804 /// See AbstractState::isValidState().
805 bool isValidState() const override { return BS.isValidState(); }
806
807 /// See AbstractState::isAtFixpoint().
808 bool isAtFixpoint() const override { return BS.isAtFixpoint(); }
809
810 /// See AbstractState::indicateOptimisticFixpoint().
814 }
815
816 /// See AbstractState::indicatePessimisticFixpoint().
820 }
821
822 State &operator=(const State &R) {
823 if (this == &R)
824 return *this;
825 BS = R.BS;
826 AccessList = R.AccessList;
827 OffsetBins = R.OffsetBins;
828 RemoteIMap = R.RemoteIMap;
829 return *this;
830 }
831
833 if (this == &R)
834 return *this;
835 std::swap(BS, R.BS);
836 std::swap(AccessList, R.AccessList);
837 std::swap(OffsetBins, R.OffsetBins);
838 std::swap(RemoteIMap, R.RemoteIMap);
839 return *this;
840 }
841
842 /// Add a new Access to the state at offset \p Offset and with size \p Size.
843 /// The access is associated with \p I, writes \p Content (if anything), and
844 /// is of kind \p Kind. If an Access already exists for the same \p I and same
845 /// \p RemoteI, the two are combined, potentially losing information about
846 /// offset and size. The resulting access must now be moved from its original
847 /// OffsetBin to the bin for its new offset.
848 ///
849 /// \Returns CHANGED, if the state changed, UNCHANGED otherwise.
851 Instruction &I, std::optional<Value *> Content,
853 Instruction *RemoteI = nullptr);
854
857 int64_t numOffsetBins() const { return OffsetBins.size(); }
858
859 const AAPointerInfo::Access &getAccess(unsigned Index) const {
860 return AccessList[Index];
861 }
862
863protected:
864 // Every memory instruction results in an Access object. We maintain a list of
865 // all Access objects that we own, along with the following maps:
866 //
867 // - OffsetBins: RangeTy -> { Access }
868 // - RemoteIMap: RemoteI x LocalI -> Access
869 //
870 // A RemoteI is any instruction that accesses memory. RemoteI is different
871 // from LocalI if and only if LocalI is a call; then RemoteI is some
872 // instruction in the callgraph starting from LocalI. Multiple paths in the
873 // callgraph from LocalI to RemoteI may produce multiple accesses, but these
874 // are all combined into a single Access object. This may result in loss of
875 // information in RangeTy in the Access object.
879
880 /// See AAPointerInfo::forallInterferingAccesses.
883 function_ref<bool(const AAPointerInfo::Access &, bool)> CB) const {
884 if (!isValidState())
885 return false;
886
887 for (const auto &It : OffsetBins) {
888 AA::RangeTy ItRange = It.getFirst();
889 if (!Range.mayOverlap(ItRange))
890 continue;
891 bool IsExact = Range == ItRange && !Range.offsetOrSizeAreUnknown();
892 for (auto Index : It.getSecond()) {
893 auto &Access = AccessList[Index];
894 if (!CB(Access, IsExact))
895 return false;
896 }
897 }
898 return true;
899 }
900
901 /// See AAPointerInfo::forallInterferingAccesses.
903 Instruction &I,
904 function_ref<bool(const AAPointerInfo::Access &, bool)> CB,
905 AA::RangeTy &Range) const {
906 if (!isValidState())
907 return false;
908
909 auto LocalList = RemoteIMap.find(&I);
910 if (LocalList == RemoteIMap.end()) {
911 return true;
912 }
913
914 for (unsigned Index : LocalList->getSecond()) {
915 for (auto &R : AccessList[Index]) {
916 Range &= R;
917 if (Range.offsetAndSizeAreUnknown())
918 break;
919 }
920 }
922 }
923
924private:
925 /// State to track fixpoint and validity.
926 BooleanState BS;
927};
928
931 std::optional<Value *> Content, AAPointerInfo::AccessKind Kind, Type *Ty,
932 Instruction *RemoteI) {
933 RemoteI = RemoteI ? RemoteI : &I;
934
935 // Check if we have an access for this instruction, if not, simply add it.
936 auto &LocalList = RemoteIMap[RemoteI];
937 bool AccExists = false;
938 unsigned AccIndex = AccessList.size();
939 for (auto Index : LocalList) {
940 auto &A = AccessList[Index];
941 if (A.getLocalInst() == &I) {
942 AccExists = true;
943 AccIndex = Index;
944 break;
945 }
946 }
947
948 auto AddToBins = [&](const AAPointerInfo::RangeList &ToAdd) {
949 LLVM_DEBUG(if (ToAdd.size()) dbgs()
950 << "[AAPointerInfo] Inserting access in new offset bins\n";);
951
952 for (auto Key : ToAdd) {
953 LLVM_DEBUG(dbgs() << " key " << Key << "\n");
954 OffsetBins[Key].insert(AccIndex);
955 }
956 };
957
958 if (!AccExists) {
959 AccessList.emplace_back(&I, RemoteI, Ranges, Content, Kind, Ty);
960 assert((AccessList.size() == AccIndex + 1) &&
961 "New Access should have been at AccIndex");
962 LocalList.push_back(AccIndex);
963 AddToBins(AccessList[AccIndex].getRanges());
965 }
966
967 // Combine the new Access with the existing Access, and then update the
968 // mapping in the offset bins.
969 AAPointerInfo::Access Acc(&I, RemoteI, Ranges, Content, Kind, Ty);
970 auto &Current = AccessList[AccIndex];
971 auto Before = Current;
972 Current &= Acc;
973 if (Current == Before)
975
976 auto &ExistingRanges = Before.getRanges();
977 auto &NewRanges = Current.getRanges();
978
979 // Ranges that are in the old access but not the new access need to be removed
980 // from the offset bins.
982 AAPointerInfo::RangeList::set_difference(ExistingRanges, NewRanges, ToRemove);
983 LLVM_DEBUG(if (ToRemove.size()) dbgs()
984 << "[AAPointerInfo] Removing access from old offset bins\n";);
985
986 for (auto Key : ToRemove) {
987 LLVM_DEBUG(dbgs() << " key " << Key << "\n");
988 assert(OffsetBins.count(Key) && "Existing Access must be in some bin.");
989 auto &Bin = OffsetBins[Key];
990 assert(Bin.count(AccIndex) &&
991 "Expected bin to actually contain the Access.");
992 Bin.erase(AccIndex);
993 }
994
995 // Ranges that are in the new access but not the old access need to be added
996 // to the offset bins.
998 AAPointerInfo::RangeList::set_difference(NewRanges, ExistingRanges, ToAdd);
999 AddToBins(ToAdd);
1000 return ChangeStatus::CHANGED;
1001}
1002
1003namespace {
1004
1005/// A helper containing a list of offsets computed for a Use. Ideally this
1006/// list should be strictly ascending, but we ensure that only when we
1007/// actually translate the list of offsets to a RangeList.
1008struct OffsetInfo {
1009 using VecTy = SmallVector<int64_t>;
1010 using const_iterator = VecTy::const_iterator;
1011 VecTy Offsets;
1012
1013 const_iterator begin() const { return Offsets.begin(); }
1014 const_iterator end() const { return Offsets.end(); }
1015
1016 bool operator==(const OffsetInfo &RHS) const {
1017 return Offsets == RHS.Offsets;
1018 }
1019
1020 bool operator!=(const OffsetInfo &RHS) const { return !(*this == RHS); }
1021
1022 void insert(int64_t Offset) { Offsets.push_back(Offset); }
1023 bool isUnassigned() const { return Offsets.size() == 0; }
1024
1025 bool isUnknown() const {
1026 if (isUnassigned())
1027 return false;
1028 if (Offsets.size() == 1)
1029 return Offsets.front() == AA::RangeTy::Unknown;
1030 return false;
1031 }
1032
1033 void setUnknown() {
1034 Offsets.clear();
1035 Offsets.push_back(AA::RangeTy::Unknown);
1036 }
1037
1038 void addToAll(int64_t Inc) {
1039 for (auto &Offset : Offsets) {
1040 Offset += Inc;
1041 }
1042 }
1043
1044 /// Copy offsets from \p R into the current list.
1045 ///
1046 /// Ideally all lists should be strictly ascending, but we defer that to the
1047 /// actual use of the list. So we just blindly append here.
1048 void merge(const OffsetInfo &R) { Offsets.append(R.Offsets); }
1049};
1050
1051#ifndef NDEBUG
1052static raw_ostream &operator<<(raw_ostream &OS, const OffsetInfo &OI) {
1053 ListSeparator LS;
1054 OS << "[";
1055 for (auto Offset : OI) {
1056 OS << LS << Offset;
1057 }
1058 OS << "]";
1059 return OS;
1060}
1061#endif // NDEBUG
1062
1063struct AAPointerInfoImpl
1064 : public StateWrapper<AA::PointerInfo::State, AAPointerInfo> {
1066 AAPointerInfoImpl(const IRPosition &IRP, Attributor &A) : BaseTy(IRP) {}
1067
1068 /// See AbstractAttribute::getAsStr().
1069 const std::string getAsStr(Attributor *A) const override {
1070 return std::string("PointerInfo ") +
1071 (isValidState() ? (std::string("#") +
1072 std::to_string(OffsetBins.size()) + " bins")
1073 : "<invalid>");
1074 }
1075
1076 /// See AbstractAttribute::manifest(...).
1077 ChangeStatus manifest(Attributor &A) override {
1078 return AAPointerInfo::manifest(A);
1079 }
1080
1081 virtual const_bin_iterator begin() const override { return State::begin(); }
1082 virtual const_bin_iterator end() const override { return State::end(); }
1083 virtual int64_t numOffsetBins() const override {
1084 return State::numOffsetBins();
1085 }
1086
1087 bool forallInterferingAccesses(
1089 function_ref<bool(const AAPointerInfo::Access &, bool)> CB)
1090 const override {
1091 return State::forallInterferingAccesses(Range, CB);
1092 }
1093
1094 bool forallInterferingAccesses(
1095 Attributor &A, const AbstractAttribute &QueryingAA, Instruction &I,
1096 bool FindInterferingWrites, bool FindInterferingReads,
1097 function_ref<bool(const Access &, bool)> UserCB, bool &HasBeenWrittenTo,
1099 function_ref<bool(const Access &)> SkipCB) const override {
1100 HasBeenWrittenTo = false;
1101
1102 SmallPtrSet<const Access *, 8> DominatingWrites;
1103 SmallVector<std::pair<const Access *, bool>, 8> InterferingAccesses;
1104
1105 Function &Scope = *I.getFunction();
1106 bool IsKnownNoSync;
1107 bool IsAssumedNoSync = AA::hasAssumedIRAttr<Attribute::NoSync>(
1108 A, &QueryingAA, IRPosition::function(Scope), DepClassTy::OPTIONAL,
1109 IsKnownNoSync);
1110 const auto *ExecDomainAA = A.lookupAAFor<AAExecutionDomain>(
1111 IRPosition::function(Scope), &QueryingAA, DepClassTy::NONE);
1112 bool AllInSameNoSyncFn = IsAssumedNoSync;
1113 bool InstIsExecutedByInitialThreadOnly =
1114 ExecDomainAA && ExecDomainAA->isExecutedByInitialThreadOnly(I);
1115
1116 // If the function is not ending in aligned barriers, we need the stores to
1117 // be in aligned barriers. The load being in one is not sufficient since the
1118 // store might be executed by a thread that disappears after, causing the
1119 // aligned barrier guarding the load to unblock and the load to read a value
1120 // that has no CFG path to the load.
1121 bool InstIsExecutedInAlignedRegion =
1122 FindInterferingReads && ExecDomainAA &&
1123 ExecDomainAA->isExecutedInAlignedRegion(A, I);
1124
1125 if (InstIsExecutedInAlignedRegion || InstIsExecutedByInitialThreadOnly)
1126 A.recordDependence(*ExecDomainAA, QueryingAA, DepClassTy::OPTIONAL);
1127
1128 InformationCache &InfoCache = A.getInfoCache();
1129 bool IsThreadLocalObj =
1130 AA::isAssumedThreadLocalObject(A, getAssociatedValue(), *this);
1131
1132 // Helper to determine if we need to consider threading, which we cannot
1133 // right now. However, if the function is (assumed) nosync or the thread
1134 // executing all instructions is the main thread only we can ignore
1135 // threading. Also, thread-local objects do not require threading reasoning.
1136 // Finally, we can ignore threading if either access is executed in an
1137 // aligned region.
1138 auto CanIgnoreThreadingForInst = [&](const Instruction &I) -> bool {
1139 if (IsThreadLocalObj || AllInSameNoSyncFn)
1140 return true;
1141 const auto *FnExecDomainAA =
1142 I.getFunction() == &Scope
1143 ? ExecDomainAA
1144 : A.lookupAAFor<AAExecutionDomain>(
1145 IRPosition::function(*I.getFunction()), &QueryingAA,
1146 DepClassTy::NONE);
1147 if (!FnExecDomainAA)
1148 return false;
1149 if (InstIsExecutedInAlignedRegion ||
1150 (FindInterferingWrites &&
1151 FnExecDomainAA->isExecutedInAlignedRegion(A, I))) {
1152 A.recordDependence(*FnExecDomainAA, QueryingAA, DepClassTy::OPTIONAL);
1153 return true;
1154 }
1155 if (InstIsExecutedByInitialThreadOnly &&
1156 FnExecDomainAA->isExecutedByInitialThreadOnly(I)) {
1157 A.recordDependence(*FnExecDomainAA, QueryingAA, DepClassTy::OPTIONAL);
1158 return true;
1159 }
1160 return false;
1161 };
1162
1163 // Helper to determine if the access is executed by the same thread as the
1164 // given instruction, for now it is sufficient to avoid any potential
1165 // threading effects as we cannot deal with them anyway.
1166 auto CanIgnoreThreading = [&](const Access &Acc) -> bool {
1167 return CanIgnoreThreadingForInst(*Acc.getRemoteInst()) ||
1168 (Acc.getRemoteInst() != Acc.getLocalInst() &&
1169 CanIgnoreThreadingForInst(*Acc.getLocalInst()));
1170 };
1171
1172 // TODO: Use inter-procedural reachability and dominance.
1173 bool IsKnownNoRecurse;
1174 AA::hasAssumedIRAttr<Attribute::NoRecurse>(
1175 A, this, IRPosition::function(Scope), DepClassTy::OPTIONAL,
1176 IsKnownNoRecurse);
1177
1178 // TODO: Use reaching kernels from AAKernelInfo (or move it to
1179 // AAExecutionDomain) such that we allow scopes other than kernels as long
1180 // as the reaching kernels are disjoint.
1181 bool InstInKernel = Scope.hasFnAttribute("kernel");
1182 bool ObjHasKernelLifetime = false;
1183 const bool UseDominanceReasoning =
1184 FindInterferingWrites && IsKnownNoRecurse;
1185 const DominatorTree *DT =
1187
1188 // Helper to check if a value has "kernel lifetime", that is it will not
1189 // outlive a GPU kernel. This is true for shared, constant, and local
1190 // globals on AMD and NVIDIA GPUs.
1191 auto HasKernelLifetime = [&](Value *V, Module &M) {
1192 if (!AA::isGPU(M))
1193 return false;
1194 switch (AA::GPUAddressSpace(V->getType()->getPointerAddressSpace())) {
1195 case AA::GPUAddressSpace::Shared:
1196 case AA::GPUAddressSpace::Constant:
1197 case AA::GPUAddressSpace::Local:
1198 return true;
1199 default:
1200 return false;
1201 };
1202 };
1203
1204 // The IsLiveInCalleeCB will be used by the AA::isPotentiallyReachable query
1205 // to determine if we should look at reachability from the callee. For
1206 // certain pointers we know the lifetime and we do not have to step into the
1207 // callee to determine reachability as the pointer would be dead in the
1208 // callee. See the conditional initialization below.
1209 std::function<bool(const Function &)> IsLiveInCalleeCB;
1210
1211 if (auto *AI = dyn_cast<AllocaInst>(&getAssociatedValue())) {
1212 // If the alloca containing function is not recursive the alloca
1213 // must be dead in the callee.
1214 const Function *AIFn = AI->getFunction();
1215 ObjHasKernelLifetime = AIFn->hasFnAttribute("kernel");
1216 bool IsKnownNoRecurse;
1217 if (AA::hasAssumedIRAttr<Attribute::NoRecurse>(
1218 A, this, IRPosition::function(*AIFn), DepClassTy::OPTIONAL,
1219 IsKnownNoRecurse)) {
1220 IsLiveInCalleeCB = [AIFn](const Function &Fn) { return AIFn != &Fn; };
1221 }
1222 } else if (auto *GV = dyn_cast<GlobalValue>(&getAssociatedValue())) {
1223 // If the global has kernel lifetime we can stop if we reach a kernel
1224 // as it is "dead" in the (unknown) callees.
1225 ObjHasKernelLifetime = HasKernelLifetime(GV, *GV->getParent());
1226 if (ObjHasKernelLifetime)
1227 IsLiveInCalleeCB = [](const Function &Fn) {
1228 return !Fn.hasFnAttribute("kernel");
1229 };
1230 }
1231
1232 // Set of accesses/instructions that will overwrite the result and are
1233 // therefore blockers in the reachability traversal.
1234 AA::InstExclusionSetTy ExclusionSet;
1235
1236 auto AccessCB = [&](const Access &Acc, bool Exact) {
1237 Function *AccScope = Acc.getRemoteInst()->getFunction();
1238 bool AccInSameScope = AccScope == &Scope;
1239
1240 // If the object has kernel lifetime we can ignore accesses only reachable
1241 // by other kernels. For now we only skip accesses *in* other kernels.
1242 if (InstInKernel && ObjHasKernelLifetime && !AccInSameScope &&
1243 AccScope->hasFnAttribute("kernel"))
1244 return true;
1245
1246 if (Exact && Acc.isMustAccess() && Acc.getRemoteInst() != &I) {
1247 if (Acc.isWrite() || (isa<LoadInst>(I) && Acc.isWriteOrAssumption()))
1248 ExclusionSet.insert(Acc.getRemoteInst());
1249 }
1250
1251 if ((!FindInterferingWrites || !Acc.isWriteOrAssumption()) &&
1252 (!FindInterferingReads || !Acc.isRead()))
1253 return true;
1254
1255 bool Dominates = FindInterferingWrites && DT && Exact &&
1256 Acc.isMustAccess() && AccInSameScope &&
1257 DT->dominates(Acc.getRemoteInst(), &I);
1258 if (Dominates)
1259 DominatingWrites.insert(&Acc);
1260
1261 // Track if all interesting accesses are in the same `nosync` function as
1262 // the given instruction.
1263 AllInSameNoSyncFn &= Acc.getRemoteInst()->getFunction() == &Scope;
1264
1265 InterferingAccesses.push_back({&Acc, Exact});
1266 return true;
1267 };
1268 if (!State::forallInterferingAccesses(I, AccessCB, Range))
1269 return false;
1270
1271 HasBeenWrittenTo = !DominatingWrites.empty();
1272
1273 // Dominating writes form a chain, find the least/lowest member.
1274 Instruction *LeastDominatingWriteInst = nullptr;
1275 for (const Access *Acc : DominatingWrites) {
1276 if (!LeastDominatingWriteInst) {
1277 LeastDominatingWriteInst = Acc->getRemoteInst();
1278 } else if (DT->dominates(LeastDominatingWriteInst,
1279 Acc->getRemoteInst())) {
1280 LeastDominatingWriteInst = Acc->getRemoteInst();
1281 }
1282 }
1283
1284 // Helper to determine if we can skip a specific write access.
1285 auto CanSkipAccess = [&](const Access &Acc, bool Exact) {
1286 if (SkipCB && SkipCB(Acc))
1287 return true;
1288 if (!CanIgnoreThreading(Acc))
1289 return false;
1290
1291 // Check read (RAW) dependences and write (WAR) dependences as necessary.
1292 // If we successfully excluded all effects we are interested in, the
1293 // access can be skipped.
1294 bool ReadChecked = !FindInterferingReads;
1295 bool WriteChecked = !FindInterferingWrites;
1296
1297 // If the instruction cannot reach the access, the former does not
1298 // interfere with what the access reads.
1299 if (!ReadChecked) {
1300 if (!AA::isPotentiallyReachable(A, I, *Acc.getRemoteInst(), QueryingAA,
1301 &ExclusionSet, IsLiveInCalleeCB))
1302 ReadChecked = true;
1303 }
1304 // If the instruction cannot be reach from the access, the latter does not
1305 // interfere with what the instruction reads.
1306 if (!WriteChecked) {
1307 if (!AA::isPotentiallyReachable(A, *Acc.getRemoteInst(), I, QueryingAA,
1308 &ExclusionSet, IsLiveInCalleeCB))
1309 WriteChecked = true;
1310 }
1311
1312 // If we still might be affected by the write of the access but there are
1313 // dominating writes in the function of the instruction
1314 // (HasBeenWrittenTo), we can try to reason that the access is overwritten
1315 // by them. This would have happend above if they are all in the same
1316 // function, so we only check the inter-procedural case. Effectively, we
1317 // want to show that there is no call after the dominting write that might
1318 // reach the access, and when it returns reach the instruction with the
1319 // updated value. To this end, we iterate all call sites, check if they
1320 // might reach the instruction without going through another access
1321 // (ExclusionSet) and at the same time might reach the access. However,
1322 // that is all part of AAInterFnReachability.
1323 if (!WriteChecked && HasBeenWrittenTo &&
1324 Acc.getRemoteInst()->getFunction() != &Scope) {
1325
1326 const auto *FnReachabilityAA = A.getAAFor<AAInterFnReachability>(
1327 QueryingAA, IRPosition::function(Scope), DepClassTy::OPTIONAL);
1328
1329 // Without going backwards in the call tree, can we reach the access
1330 // from the least dominating write. Do not allow to pass the instruction
1331 // itself either.
1332 bool Inserted = ExclusionSet.insert(&I).second;
1333
1334 if (!FnReachabilityAA ||
1335 !FnReachabilityAA->instructionCanReach(
1336 A, *LeastDominatingWriteInst,
1337 *Acc.getRemoteInst()->getFunction(), &ExclusionSet))
1338 WriteChecked = true;
1339
1340 if (Inserted)
1341 ExclusionSet.erase(&I);
1342 }
1343
1344 if (ReadChecked && WriteChecked)
1345 return true;
1346
1347 if (!DT || !UseDominanceReasoning)
1348 return false;
1349 if (!DominatingWrites.count(&Acc))
1350 return false;
1351 return LeastDominatingWriteInst != Acc.getRemoteInst();
1352 };
1353
1354 // Run the user callback on all accesses we cannot skip and return if
1355 // that succeeded for all or not.
1356 for (auto &It : InterferingAccesses) {
1357 if ((!AllInSameNoSyncFn && !IsThreadLocalObj && !ExecDomainAA) ||
1358 !CanSkipAccess(*It.first, It.second)) {
1359 if (!UserCB(*It.first, It.second))
1360 return false;
1361 }
1362 }
1363 return true;
1364 }
1365
1366 ChangeStatus translateAndAddStateFromCallee(Attributor &A,
1367 const AAPointerInfo &OtherAA,
1368 CallBase &CB) {
1369 using namespace AA::PointerInfo;
1370 if (!OtherAA.getState().isValidState() || !isValidState())
1371 return indicatePessimisticFixpoint();
1372
1373 const auto &OtherAAImpl = static_cast<const AAPointerInfoImpl &>(OtherAA);
1374 bool IsByval = OtherAAImpl.getAssociatedArgument()->hasByValAttr();
1375
1376 // Combine the accesses bin by bin.
1377 ChangeStatus Changed = ChangeStatus::UNCHANGED;
1378 const auto &State = OtherAAImpl.getState();
1379 for (const auto &It : State) {
1380 for (auto Index : It.getSecond()) {
1381 const auto &RAcc = State.getAccess(Index);
1382 if (IsByval && !RAcc.isRead())
1383 continue;
1384 bool UsedAssumedInformation = false;
1385 AccessKind AK = RAcc.getKind();
1386 auto Content = A.translateArgumentToCallSiteContent(
1387 RAcc.getContent(), CB, *this, UsedAssumedInformation);
1388 AK = AccessKind(AK & (IsByval ? AccessKind::AK_R : AccessKind::AK_RW));
1389 AK = AccessKind(AK | (RAcc.isMayAccess() ? AK_MAY : AK_MUST));
1390
1391 Changed |= addAccess(A, RAcc.getRanges(), CB, Content, AK,
1392 RAcc.getType(), RAcc.getRemoteInst());
1393 }
1394 }
1395 return Changed;
1396 }
1397
1398 ChangeStatus translateAndAddState(Attributor &A, const AAPointerInfo &OtherAA,
1399 const OffsetInfo &Offsets, CallBase &CB) {
1400 using namespace AA::PointerInfo;
1401 if (!OtherAA.getState().isValidState() || !isValidState())
1402 return indicatePessimisticFixpoint();
1403
1404 const auto &OtherAAImpl = static_cast<const AAPointerInfoImpl &>(OtherAA);
1405
1406 // Combine the accesses bin by bin.
1407 ChangeStatus Changed = ChangeStatus::UNCHANGED;
1408 const auto &State = OtherAAImpl.getState();
1409 for (const auto &It : State) {
1410 for (auto Index : It.getSecond()) {
1411 const auto &RAcc = State.getAccess(Index);
1412 for (auto Offset : Offsets) {
1413 auto NewRanges = Offset == AA::RangeTy::Unknown
1415 : RAcc.getRanges();
1416 if (!NewRanges.isUnknown()) {
1417 NewRanges.addToAllOffsets(Offset);
1418 }
1419 Changed |=
1420 addAccess(A, NewRanges, CB, RAcc.getContent(), RAcc.getKind(),
1421 RAcc.getType(), RAcc.getRemoteInst());
1422 }
1423 }
1424 }
1425 return Changed;
1426 }
1427
1428 /// Statistic tracking for all AAPointerInfo implementations.
1429 /// See AbstractAttribute::trackStatistics().
1430 void trackPointerInfoStatistics(const IRPosition &IRP) const {}
1431
1432 /// Dump the state into \p O.
1433 void dumpState(raw_ostream &O) {
1434 for (auto &It : OffsetBins) {
1435 O << "[" << It.first.Offset << "-" << It.first.Offset + It.first.Size
1436 << "] : " << It.getSecond().size() << "\n";
1437 for (auto AccIndex : It.getSecond()) {
1438 auto &Acc = AccessList[AccIndex];
1439 O << " - " << Acc.getKind() << " - " << *Acc.getLocalInst() << "\n";
1440 if (Acc.getLocalInst() != Acc.getRemoteInst())
1441 O << " --> " << *Acc.getRemoteInst()
1442 << "\n";
1443 if (!Acc.isWrittenValueYetUndetermined()) {
1444 if (isa_and_nonnull<Function>(Acc.getWrittenValue()))
1445 O << " - c: func " << Acc.getWrittenValue()->getName()
1446 << "\n";
1447 else if (Acc.getWrittenValue())
1448 O << " - c: " << *Acc.getWrittenValue() << "\n";
1449 else
1450 O << " - c: <unknown>\n";
1451 }
1452 }
1453 }
1454 }
1455};
1456
1457struct AAPointerInfoFloating : public AAPointerInfoImpl {
1459 AAPointerInfoFloating(const IRPosition &IRP, Attributor &A)
1460 : AAPointerInfoImpl(IRP, A) {}
1461
1462 /// Deal with an access and signal if it was handled successfully.
1463 bool handleAccess(Attributor &A, Instruction &I,
1464 std::optional<Value *> Content, AccessKind Kind,
1465 SmallVectorImpl<int64_t> &Offsets, ChangeStatus &Changed,
1466 Type &Ty) {
1467 using namespace AA::PointerInfo;
1469 const DataLayout &DL = A.getDataLayout();
1470 TypeSize AccessSize = DL.getTypeStoreSize(&Ty);
1471 if (!AccessSize.isScalable())
1472 Size = AccessSize.getFixedValue();
1473
1474 // Make a strictly ascending list of offsets as required by addAccess()
1475 llvm::sort(Offsets);
1476 auto *Last = llvm::unique(Offsets);
1477 Offsets.erase(Last, Offsets.end());
1478
1479 VectorType *VT = dyn_cast<VectorType>(&Ty);
1480 if (!VT || VT->getElementCount().isScalable() ||
1481 !Content.value_or(nullptr) || !isa<Constant>(*Content) ||
1482 (*Content)->getType() != VT ||
1483 DL.getTypeStoreSize(VT->getElementType()).isScalable()) {
1484 Changed = Changed | addAccess(A, {Offsets, Size}, I, Content, Kind, &Ty);
1485 } else {
1486 // Handle vector stores with constant content element-wise.
1487 // TODO: We could look for the elements or create instructions
1488 // representing them.
1489 // TODO: We need to push the Content into the range abstraction
1490 // (AA::RangeTy) to allow different content values for different
1491 // ranges. ranges. Hence, support vectors storing different values.
1492 Type *ElementType = VT->getElementType();
1493 int64_t ElementSize = DL.getTypeStoreSize(ElementType).getFixedValue();
1494 auto *ConstContent = cast<Constant>(*Content);
1495 Type *Int32Ty = Type::getInt32Ty(ElementType->getContext());
1496 SmallVector<int64_t> ElementOffsets(Offsets.begin(), Offsets.end());
1497
1498 for (int i = 0, e = VT->getElementCount().getFixedValue(); i != e; ++i) {
1499 Value *ElementContent = ConstantExpr::getExtractElement(
1500 ConstContent, ConstantInt::get(Int32Ty, i));
1501
1502 // Add the element access.
1503 Changed = Changed | addAccess(A, {ElementOffsets, ElementSize}, I,
1504 ElementContent, Kind, ElementType);
1505
1506 // Advance the offsets for the next element.
1507 for (auto &ElementOffset : ElementOffsets)
1508 ElementOffset += ElementSize;
1509 }
1510 }
1511 return true;
1512 };
1513
1514 /// See AbstractAttribute::updateImpl(...).
1515 ChangeStatus updateImpl(Attributor &A) override;
1516
1517 /// If the indices to \p GEP can be traced to constants, incorporate all
1518 /// of these into \p UsrOI.
1519 ///
1520 /// \return true iff \p UsrOI is updated.
1521 bool collectConstantsForGEP(Attributor &A, const DataLayout &DL,
1522 OffsetInfo &UsrOI, const OffsetInfo &PtrOI,
1523 const GEPOperator *GEP);
1524
1525 /// See AbstractAttribute::trackStatistics()
1526 void trackStatistics() const override {
1527 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
1528 }
1529};
1530
1531bool AAPointerInfoFloating::collectConstantsForGEP(Attributor &A,
1532 const DataLayout &DL,
1533 OffsetInfo &UsrOI,
1534 const OffsetInfo &PtrOI,
1535 const GEPOperator *GEP) {
1536 unsigned BitWidth = DL.getIndexTypeSizeInBits(GEP->getType());
1537 MapVector<Value *, APInt> VariableOffsets;
1538 APInt ConstantOffset(BitWidth, 0);
1539
1540 assert(!UsrOI.isUnknown() && !PtrOI.isUnknown() &&
1541 "Don't look for constant values if the offset has already been "
1542 "determined to be unknown.");
1543
1544 if (!GEP->collectOffset(DL, BitWidth, VariableOffsets, ConstantOffset)) {
1545 UsrOI.setUnknown();
1546 return true;
1547 }
1548
1549 LLVM_DEBUG(dbgs() << "[AAPointerInfo] GEP offset is "
1550 << (VariableOffsets.empty() ? "" : "not") << " constant "
1551 << *GEP << "\n");
1552
1553 auto Union = PtrOI;
1554 Union.addToAll(ConstantOffset.getSExtValue());
1555
1556 // Each VI in VariableOffsets has a set of potential constant values. Every
1557 // combination of elements, picked one each from these sets, is separately
1558 // added to the original set of offsets, thus resulting in more offsets.
1559 for (const auto &VI : VariableOffsets) {
1560 auto *PotentialConstantsAA = A.getAAFor<AAPotentialConstantValues>(
1561 *this, IRPosition::value(*VI.first), DepClassTy::OPTIONAL);
1562 if (!PotentialConstantsAA || !PotentialConstantsAA->isValidState()) {
1563 UsrOI.setUnknown();
1564 return true;
1565 }
1566
1567 // UndefValue is treated as a zero, which leaves Union as is.
1568 if (PotentialConstantsAA->undefIsContained())
1569 continue;
1570
1571 // We need at least one constant in every set to compute an actual offset.
1572 // Otherwise, we end up pessimizing AAPointerInfo by respecting offsets that
1573 // don't actually exist. In other words, the absence of constant values
1574 // implies that the operation can be assumed dead for now.
1575 auto &AssumedSet = PotentialConstantsAA->getAssumedSet();
1576 if (AssumedSet.empty())
1577 return false;
1578
1579 OffsetInfo Product;
1580 for (const auto &ConstOffset : AssumedSet) {
1581 auto CopyPerOffset = Union;
1582 CopyPerOffset.addToAll(ConstOffset.getSExtValue() *
1583 VI.second.getZExtValue());
1584 Product.merge(CopyPerOffset);
1585 }
1586 Union = Product;
1587 }
1588
1589 UsrOI = std::move(Union);
1590 return true;
1591}
1592
1593ChangeStatus AAPointerInfoFloating::updateImpl(Attributor &A) {
1594 using namespace AA::PointerInfo;
1596 const DataLayout &DL = A.getDataLayout();
1597 Value &AssociatedValue = getAssociatedValue();
1598
1599 DenseMap<Value *, OffsetInfo> OffsetInfoMap;
1600 OffsetInfoMap[&AssociatedValue].insert(0);
1601
1602 auto HandlePassthroughUser = [&](Value *Usr, Value *CurPtr, bool &Follow) {
1603 // One does not simply walk into a map and assign a reference to a possibly
1604 // new location. That can cause an invalidation before the assignment
1605 // happens, like so:
1606 //
1607 // OffsetInfoMap[Usr] = OffsetInfoMap[CurPtr]; /* bad idea! */
1608 //
1609 // The RHS is a reference that may be invalidated by an insertion caused by
1610 // the LHS. So we ensure that the side-effect of the LHS happens first.
1611
1612 assert(OffsetInfoMap.contains(CurPtr) &&
1613 "CurPtr does not exist in the map!");
1614
1615 auto &UsrOI = OffsetInfoMap[Usr];
1616 auto &PtrOI = OffsetInfoMap[CurPtr];
1617 assert(!PtrOI.isUnassigned() &&
1618 "Cannot pass through if the input Ptr was not visited!");
1619 UsrOI.merge(PtrOI);
1620 Follow = true;
1621 return true;
1622 };
1623
1624 const auto *F = getAnchorScope();
1625 const auto *CI =
1626 F ? A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>(*F)
1627 : nullptr;
1628 const auto *TLI =
1629 F ? A.getInfoCache().getTargetLibraryInfoForFunction(*F) : nullptr;
1630
1631 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
1632 Value *CurPtr = U.get();
1633 User *Usr = U.getUser();
1634 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Analyze " << *CurPtr << " in " << *Usr
1635 << "\n");
1636 assert(OffsetInfoMap.count(CurPtr) &&
1637 "The current pointer offset should have been seeded!");
1638
1639 if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Usr)) {
1640 if (CE->isCast())
1641 return HandlePassthroughUser(Usr, CurPtr, Follow);
1642 if (!isa<GEPOperator>(CE)) {
1643 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Unhandled constant user " << *CE
1644 << "\n");
1645 return false;
1646 }
1647 }
1648 if (auto *GEP = dyn_cast<GEPOperator>(Usr)) {
1649 // Note the order here, the Usr access might change the map, CurPtr is
1650 // already in it though.
1651 auto &UsrOI = OffsetInfoMap[Usr];
1652 auto &PtrOI = OffsetInfoMap[CurPtr];
1653
1654 if (UsrOI.isUnknown())
1655 return true;
1656
1657 if (PtrOI.isUnknown()) {
1658 Follow = true;
1659 UsrOI.setUnknown();
1660 return true;
1661 }
1662
1663 Follow = collectConstantsForGEP(A, DL, UsrOI, PtrOI, GEP);
1664 return true;
1665 }
1666 if (isa<PtrToIntInst>(Usr))
1667 return false;
1668 if (isa<CastInst>(Usr) || isa<SelectInst>(Usr) || isa<ReturnInst>(Usr))
1669 return HandlePassthroughUser(Usr, CurPtr, Follow);
1670
1671 // For PHIs we need to take care of the recurrence explicitly as the value
1672 // might change while we iterate through a loop. For now, we give up if
1673 // the PHI is not invariant.
1674 if (isa<PHINode>(Usr)) {
1675 // Note the order here, the Usr access might change the map, CurPtr is
1676 // already in it though.
1677 bool IsFirstPHIUser = !OffsetInfoMap.count(Usr);
1678 auto &UsrOI = OffsetInfoMap[Usr];
1679 auto &PtrOI = OffsetInfoMap[CurPtr];
1680
1681 // Check if the PHI operand has already an unknown offset as we can't
1682 // improve on that anymore.
1683 if (PtrOI.isUnknown()) {
1684 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI operand offset unknown "
1685 << *CurPtr << " in " << *Usr << "\n");
1686 Follow = !UsrOI.isUnknown();
1687 UsrOI.setUnknown();
1688 return true;
1689 }
1690
1691 // Check if the PHI is invariant (so far).
1692 if (UsrOI == PtrOI) {
1693 assert(!PtrOI.isUnassigned() &&
1694 "Cannot assign if the current Ptr was not visited!");
1695 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI is invariant (so far)");
1696 return true;
1697 }
1698
1699 // Check if the PHI operand can be traced back to AssociatedValue.
1700 APInt Offset(
1701 DL.getIndexSizeInBits(CurPtr->getType()->getPointerAddressSpace()),
1702 0);
1703 Value *CurPtrBase = CurPtr->stripAndAccumulateConstantOffsets(
1704 DL, Offset, /* AllowNonInbounds */ true);
1705 auto It = OffsetInfoMap.find(CurPtrBase);
1706 if (It == OffsetInfoMap.end()) {
1707 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI operand is too complex "
1708 << *CurPtr << " in " << *Usr << "\n");
1709 UsrOI.setUnknown();
1710 Follow = true;
1711 return true;
1712 }
1713
1714 // Check if the PHI operand is not dependent on the PHI itself. Every
1715 // recurrence is a cyclic net of PHIs in the data flow, and has an
1716 // equivalent Cycle in the control flow. One of those PHIs must be in the
1717 // header of that control flow Cycle. This is independent of the choice of
1718 // Cycles reported by CycleInfo. It is sufficient to check the PHIs in
1719 // every Cycle header; if such a node is marked unknown, this will
1720 // eventually propagate through the whole net of PHIs in the recurrence.
1721 if (mayBeInCycle(CI, cast<Instruction>(Usr), /* HeaderOnly */ true)) {
1722 auto BaseOI = It->getSecond();
1723 BaseOI.addToAll(Offset.getZExtValue());
1724 if (IsFirstPHIUser || BaseOI == UsrOI) {
1725 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI is invariant " << *CurPtr
1726 << " in " << *Usr << "\n");
1727 return HandlePassthroughUser(Usr, CurPtr, Follow);
1728 }
1729
1730 LLVM_DEBUG(
1731 dbgs() << "[AAPointerInfo] PHI operand pointer offset mismatch "
1732 << *CurPtr << " in " << *Usr << "\n");
1733 UsrOI.setUnknown();
1734 Follow = true;
1735 return true;
1736 }
1737
1738 UsrOI.merge(PtrOI);
1739 Follow = true;
1740 return true;
1741 }
1742
1743 if (auto *LoadI = dyn_cast<LoadInst>(Usr)) {
1744 // If the access is to a pointer that may or may not be the associated
1745 // value, e.g. due to a PHI, we cannot assume it will be read.
1746 AccessKind AK = AccessKind::AK_R;
1747 if (getUnderlyingObject(CurPtr) == &AssociatedValue)
1748 AK = AccessKind(AK | AccessKind::AK_MUST);
1749 else
1750 AK = AccessKind(AK | AccessKind::AK_MAY);
1751 if (!handleAccess(A, *LoadI, /* Content */ nullptr, AK,
1752 OffsetInfoMap[CurPtr].Offsets, Changed,
1753 *LoadI->getType()))
1754 return false;
1755
1756 auto IsAssumption = [](Instruction &I) {
1757 if (auto *II = dyn_cast<IntrinsicInst>(&I))
1758 return II->isAssumeLikeIntrinsic();
1759 return false;
1760 };
1761
1762 auto IsImpactedInRange = [&](Instruction *FromI, Instruction *ToI) {
1763 // Check if the assumption and the load are executed together without
1764 // memory modification.
1765 do {
1766 if (FromI->mayWriteToMemory() && !IsAssumption(*FromI))
1767 return true;
1768 FromI = FromI->getNextNonDebugInstruction();
1769 } while (FromI && FromI != ToI);
1770 return false;
1771 };
1772
1773 BasicBlock *BB = LoadI->getParent();
1774 auto IsValidAssume = [&](IntrinsicInst &IntrI) {
1775 if (IntrI.getIntrinsicID() != Intrinsic::assume)
1776 return false;
1777 BasicBlock *IntrBB = IntrI.getParent();
1778 if (IntrI.getParent() == BB) {
1779 if (IsImpactedInRange(LoadI->getNextNonDebugInstruction(), &IntrI))
1780 return false;
1781 } else {
1782 auto PredIt = pred_begin(IntrBB);
1783 if (PredIt == pred_end(IntrBB))
1784 return false;
1785 if ((*PredIt) != BB)
1786 return false;
1787 if (++PredIt != pred_end(IntrBB))
1788 return false;
1789 for (auto *SuccBB : successors(BB)) {
1790 if (SuccBB == IntrBB)
1791 continue;
1792 if (isa<UnreachableInst>(SuccBB->getTerminator()))
1793 continue;
1794 return false;
1795 }
1796 if (IsImpactedInRange(LoadI->getNextNonDebugInstruction(),
1797 BB->getTerminator()))
1798 return false;
1799 if (IsImpactedInRange(&IntrBB->front(), &IntrI))
1800 return false;
1801 }
1802 return true;
1803 };
1804
1805 std::pair<Value *, IntrinsicInst *> Assumption;
1806 for (const Use &LoadU : LoadI->uses()) {
1807 if (auto *CmpI = dyn_cast<CmpInst>(LoadU.getUser())) {
1808 if (!CmpI->isEquality() || !CmpI->isTrueWhenEqual())
1809 continue;
1810 for (const Use &CmpU : CmpI->uses()) {
1811 if (auto *IntrI = dyn_cast<IntrinsicInst>(CmpU.getUser())) {
1812 if (!IsValidAssume(*IntrI))
1813 continue;
1814 int Idx = CmpI->getOperandUse(0) == LoadU;
1815 Assumption = {CmpI->getOperand(Idx), IntrI};
1816 break;
1817 }
1818 }
1819 }
1820 if (Assumption.first)
1821 break;
1822 }
1823
1824 // Check if we found an assumption associated with this load.
1825 if (!Assumption.first || !Assumption.second)
1826 return true;
1827
1828 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Assumption found "
1829 << *Assumption.second << ": " << *LoadI
1830 << " == " << *Assumption.first << "\n");
1831 bool UsedAssumedInformation = false;
1832 std::optional<Value *> Content = nullptr;
1833 if (Assumption.first)
1834 Content =
1835 A.getAssumedSimplified(*Assumption.first, *this,
1836 UsedAssumedInformation, AA::Interprocedural);
1837 return handleAccess(
1838 A, *Assumption.second, Content, AccessKind::AK_ASSUMPTION,
1839 OffsetInfoMap[CurPtr].Offsets, Changed, *LoadI->getType());
1840 }
1841
1842 auto HandleStoreLike = [&](Instruction &I, Value *ValueOp, Type &ValueTy,
1843 ArrayRef<Value *> OtherOps, AccessKind AK) {
1844 for (auto *OtherOp : OtherOps) {
1845 if (OtherOp == CurPtr) {
1846 LLVM_DEBUG(
1847 dbgs()
1848 << "[AAPointerInfo] Escaping use in store like instruction " << I
1849 << "\n");
1850 return false;
1851 }
1852 }
1853
1854 // If the access is to a pointer that may or may not be the associated
1855 // value, e.g. due to a PHI, we cannot assume it will be written.
1856 if (getUnderlyingObject(CurPtr) == &AssociatedValue)
1857 AK = AccessKind(AK | AccessKind::AK_MUST);
1858 else
1859 AK = AccessKind(AK | AccessKind::AK_MAY);
1860 bool UsedAssumedInformation = false;
1861 std::optional<Value *> Content = nullptr;
1862 if (ValueOp)
1863 Content = A.getAssumedSimplified(
1864 *ValueOp, *this, UsedAssumedInformation, AA::Interprocedural);
1865 return handleAccess(A, I, Content, AK, OffsetInfoMap[CurPtr].Offsets,
1866 Changed, ValueTy);
1867 };
1868
1869 if (auto *StoreI = dyn_cast<StoreInst>(Usr))
1870 return HandleStoreLike(*StoreI, StoreI->getValueOperand(),
1871 *StoreI->getValueOperand()->getType(),
1872 {StoreI->getValueOperand()}, AccessKind::AK_W);
1873 if (auto *RMWI = dyn_cast<AtomicRMWInst>(Usr))
1874 return HandleStoreLike(*RMWI, nullptr, *RMWI->getValOperand()->getType(),
1875 {RMWI->getValOperand()}, AccessKind::AK_RW);
1876 if (auto *CXI = dyn_cast<AtomicCmpXchgInst>(Usr))
1877 return HandleStoreLike(
1878 *CXI, nullptr, *CXI->getNewValOperand()->getType(),
1879 {CXI->getCompareOperand(), CXI->getNewValOperand()},
1880 AccessKind::AK_RW);
1881
1882 if (auto *CB = dyn_cast<CallBase>(Usr)) {
1883 if (CB->isLifetimeStartOrEnd())
1884 return true;
1885 if (getFreedOperand(CB, TLI) == U)
1886 return true;
1887 if (CB->isArgOperand(&U)) {
1888 unsigned ArgNo = CB->getArgOperandNo(&U);
1889 const auto *CSArgPI = A.getAAFor<AAPointerInfo>(
1890 *this, IRPosition::callsite_argument(*CB, ArgNo),
1892 if (!CSArgPI)
1893 return false;
1894 Changed =
1895 translateAndAddState(A, *CSArgPI, OffsetInfoMap[CurPtr], *CB) |
1896 Changed;
1897 return isValidState();
1898 }
1899 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Call user not handled " << *CB
1900 << "\n");
1901 // TODO: Allow some call uses
1902 return false;
1903 }
1904
1905 LLVM_DEBUG(dbgs() << "[AAPointerInfo] User not handled " << *Usr << "\n");
1906 return false;
1907 };
1908 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) {
1909 assert(OffsetInfoMap.count(OldU) && "Old use should be known already!");
1910 if (OffsetInfoMap.count(NewU)) {
1911 LLVM_DEBUG({
1912 if (!(OffsetInfoMap[NewU] == OffsetInfoMap[OldU])) {
1913 dbgs() << "[AAPointerInfo] Equivalent use callback failed: "
1914 << OffsetInfoMap[NewU] << " vs " << OffsetInfoMap[OldU]
1915 << "\n";
1916 }
1917 });
1918 return OffsetInfoMap[NewU] == OffsetInfoMap[OldU];
1919 }
1920 OffsetInfoMap[NewU] = OffsetInfoMap[OldU];
1921 return true;
1922 };
1923 if (!A.checkForAllUses(UsePred, *this, AssociatedValue,
1924 /* CheckBBLivenessOnly */ true, DepClassTy::OPTIONAL,
1925 /* IgnoreDroppableUses */ true, EquivalentUseCB)) {
1926 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Check for all uses failed, abort!\n");
1927 return indicatePessimisticFixpoint();
1928 }
1929
1930 LLVM_DEBUG({
1931 dbgs() << "Accesses by bin after update:\n";
1932 dumpState(dbgs());
1933 });
1934
1935 return Changed;
1936}
1937
1938struct AAPointerInfoReturned final : AAPointerInfoImpl {
1939 AAPointerInfoReturned(const IRPosition &IRP, Attributor &A)
1940 : AAPointerInfoImpl(IRP, A) {}
1941
1942 /// See AbstractAttribute::updateImpl(...).
1943 ChangeStatus updateImpl(Attributor &A) override {
1944 return indicatePessimisticFixpoint();
1945 }
1946
1947 /// See AbstractAttribute::trackStatistics()
1948 void trackStatistics() const override {
1949 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
1950 }
1951};
1952
1953struct AAPointerInfoArgument final : AAPointerInfoFloating {
1954 AAPointerInfoArgument(const IRPosition &IRP, Attributor &A)
1955 : AAPointerInfoFloating(IRP, A) {}
1956
1957 /// See AbstractAttribute::trackStatistics()
1958 void trackStatistics() const override {
1959 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
1960 }
1961};
1962
1963struct AAPointerInfoCallSiteArgument final : AAPointerInfoFloating {
1964 AAPointerInfoCallSiteArgument(const IRPosition &IRP, Attributor &A)
1965 : AAPointerInfoFloating(IRP, A) {}
1966
1967 /// See AbstractAttribute::updateImpl(...).
1968 ChangeStatus updateImpl(Attributor &A) override {
1969 using namespace AA::PointerInfo;
1970 // We handle memory intrinsics explicitly, at least the first (=
1971 // destination) and second (=source) arguments as we know how they are
1972 // accessed.
1973 if (auto *MI = dyn_cast_or_null<MemIntrinsic>(getCtxI())) {
1974 ConstantInt *Length = dyn_cast<ConstantInt>(MI->getLength());
1975 int64_t LengthVal = AA::RangeTy::Unknown;
1976 if (Length)
1977 LengthVal = Length->getSExtValue();
1978 unsigned ArgNo = getIRPosition().getCallSiteArgNo();
1979 ChangeStatus Changed = ChangeStatus::UNCHANGED;
1980 if (ArgNo > 1) {
1981 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Unhandled memory intrinsic "
1982 << *MI << "\n");
1983 return indicatePessimisticFixpoint();
1984 } else {
1985 auto Kind =
1986 ArgNo == 0 ? AccessKind::AK_MUST_WRITE : AccessKind::AK_MUST_READ;
1987 Changed =
1988 Changed | addAccess(A, {0, LengthVal}, *MI, nullptr, Kind, nullptr);
1989 }
1990 LLVM_DEBUG({
1991 dbgs() << "Accesses by bin after update:\n";
1992 dumpState(dbgs());
1993 });
1994
1995 return Changed;
1996 }
1997
1998 // TODO: Once we have call site specific value information we can provide
1999 // call site specific liveness information and then it makes
2000 // sense to specialize attributes for call sites arguments instead of
2001 // redirecting requests to the callee argument.
2002 Argument *Arg = getAssociatedArgument();
2003 if (Arg) {
2004 const IRPosition &ArgPos = IRPosition::argument(*Arg);
2005 auto *ArgAA =
2006 A.getAAFor<AAPointerInfo>(*this, ArgPos, DepClassTy::REQUIRED);
2007 if (ArgAA && ArgAA->getState().isValidState())
2008 return translateAndAddStateFromCallee(A, *ArgAA,
2009 *cast<CallBase>(getCtxI()));
2010 if (!Arg->getParent()->isDeclaration())
2011 return indicatePessimisticFixpoint();
2012 }
2013
2014 bool IsKnownNoCapture;
2015 if (!AA::hasAssumedIRAttr<Attribute::NoCapture>(
2016 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNoCapture))
2017 return indicatePessimisticFixpoint();
2018
2019 bool IsKnown = false;
2020 if (AA::isAssumedReadNone(A, getIRPosition(), *this, IsKnown))
2021 return ChangeStatus::UNCHANGED;
2022 bool ReadOnly = AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown);
2023 auto Kind =
2024 ReadOnly ? AccessKind::AK_MAY_READ : AccessKind::AK_MAY_READ_WRITE;
2025 return addAccess(A, AA::RangeTy::getUnknown(), *getCtxI(), nullptr, Kind,
2026 nullptr);
2027 }
2028
2029 /// See AbstractAttribute::trackStatistics()
2030 void trackStatistics() const override {
2031 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
2032 }
2033};
2034
2035struct AAPointerInfoCallSiteReturned final : AAPointerInfoFloating {
2036 AAPointerInfoCallSiteReturned(const IRPosition &IRP, Attributor &A)
2037 : AAPointerInfoFloating(IRP, A) {}
2038
2039 /// See AbstractAttribute::trackStatistics()
2040 void trackStatistics() const override {
2041 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
2042 }
2043};
2044} // namespace
2045
2046/// -----------------------NoUnwind Function Attribute--------------------------
2047
2048namespace {
2049struct AANoUnwindImpl : AANoUnwind {
2050 AANoUnwindImpl(const IRPosition &IRP, Attributor &A) : AANoUnwind(IRP, A) {}
2051
2052 /// See AbstractAttribute::initialize(...).
2053 void initialize(Attributor &A) override {
2054 bool IsKnown;
2055 assert(!AA::hasAssumedIRAttr<Attribute::NoUnwind>(
2056 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
2057 (void)IsKnown;
2058 }
2059
2060 const std::string getAsStr(Attributor *A) const override {
2061 return getAssumed() ? "nounwind" : "may-unwind";
2062 }
2063
2064 /// See AbstractAttribute::updateImpl(...).
2065 ChangeStatus updateImpl(Attributor &A) override {
2066 auto Opcodes = {
2067 (unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,
2068 (unsigned)Instruction::Call, (unsigned)Instruction::CleanupRet,
2069 (unsigned)Instruction::CatchSwitch, (unsigned)Instruction::Resume};
2070
2071 auto CheckForNoUnwind = [&](Instruction &I) {
2072 if (!I.mayThrow(/* IncludePhaseOneUnwind */ true))
2073 return true;
2074
2075 if (const auto *CB = dyn_cast<CallBase>(&I)) {
2076 bool IsKnownNoUnwind;
2077 return AA::hasAssumedIRAttr<Attribute::NoUnwind>(
2078 A, this, IRPosition::callsite_function(*CB), DepClassTy::REQUIRED,
2079 IsKnownNoUnwind);
2080 }
2081 return false;
2082 };
2083
2084 bool UsedAssumedInformation = false;
2085 if (!A.checkForAllInstructions(CheckForNoUnwind, *this, Opcodes,
2086 UsedAssumedInformation))
2087 return indicatePessimisticFixpoint();
2088
2089 return ChangeStatus::UNCHANGED;
2090 }
2091};
2092
2093struct AANoUnwindFunction final : public AANoUnwindImpl {
2094 AANoUnwindFunction(const IRPosition &IRP, Attributor &A)
2095 : AANoUnwindImpl(IRP, A) {}
2096
2097 /// See AbstractAttribute::trackStatistics()
2098 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nounwind) }
2099};
2100
2101/// NoUnwind attribute deduction for a call sites.
2102struct AANoUnwindCallSite final
2103 : AACalleeToCallSite<AANoUnwind, AANoUnwindImpl> {
2104 AANoUnwindCallSite(const IRPosition &IRP, Attributor &A)
2105 : AACalleeToCallSite<AANoUnwind, AANoUnwindImpl>(IRP, A) {}
2106
2107 /// See AbstractAttribute::trackStatistics()
2108 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nounwind); }
2109};
2110} // namespace
2111
2112/// ------------------------ NoSync Function Attribute -------------------------
2113
2114bool AANoSync::isAlignedBarrier(const CallBase &CB, bool ExecutedAligned) {
2115 switch (CB.getIntrinsicID()) {
2116 case Intrinsic::nvvm_barrier0:
2117 case Intrinsic::nvvm_barrier0_and:
2118 case Intrinsic::nvvm_barrier0_or:
2119 case Intrinsic::nvvm_barrier0_popc:
2120 return true;
2121 case Intrinsic::amdgcn_s_barrier:
2122 if (ExecutedAligned)
2123 return true;
2124 break;
2125 default:
2126 break;
2127 }
2128 return hasAssumption(CB, KnownAssumptionString("ompx_aligned_barrier"));
2129}
2130
2132 if (!I->isAtomic())
2133 return false;
2134
2135 if (auto *FI = dyn_cast<FenceInst>(I))
2136 // All legal orderings for fence are stronger than monotonic.
2137 return FI->getSyncScopeID() != SyncScope::SingleThread;
2138 if (auto *AI = dyn_cast<AtomicCmpXchgInst>(I)) {
2139 // Unordered is not a legal ordering for cmpxchg.
2140 return (AI->getSuccessOrdering() != AtomicOrdering::Monotonic ||
2141 AI->getFailureOrdering() != AtomicOrdering::Monotonic);
2142 }
2143
2144 AtomicOrdering Ordering;
2145 switch (I->getOpcode()) {
2146 case Instruction::AtomicRMW:
2147 Ordering = cast<AtomicRMWInst>(I)->getOrdering();
2148 break;
2149 case Instruction::Store:
2150 Ordering = cast<StoreInst>(I)->getOrdering();
2151 break;
2152 case Instruction::Load:
2153 Ordering = cast<LoadInst>(I)->getOrdering();
2154 break;
2155 default:
2157 "New atomic operations need to be known in the attributor.");
2158 }
2159
2160 return (Ordering != AtomicOrdering::Unordered &&
2161 Ordering != AtomicOrdering::Monotonic);
2162}
2163
2164/// Return true if this intrinsic is nosync. This is only used for intrinsics
2165/// which would be nosync except that they have a volatile flag. All other
2166/// intrinsics are simply annotated with the nosync attribute in Intrinsics.td.
2168 if (auto *MI = dyn_cast<MemIntrinsic>(I))
2169 return !MI->isVolatile();
2170 return false;
2171}
2172
2173namespace {
2174struct AANoSyncImpl : AANoSync {
2175 AANoSyncImpl(const IRPosition &IRP, Attributor &A) : AANoSync(IRP, A) {}
2176
2177 /// See AbstractAttribute::initialize(...).
2178 void initialize(Attributor &A) override {
2179 bool IsKnown;
2180 assert(!AA::hasAssumedIRAttr<Attribute::NoSync>(A, nullptr, getIRPosition(),
2181 DepClassTy::NONE, IsKnown));
2182 (void)IsKnown;
2183 }
2184
2185 const std::string getAsStr(Attributor *A) const override {
2186 return getAssumed() ? "nosync" : "may-sync";
2187 }
2188
2189 /// See AbstractAttribute::updateImpl(...).
2190 ChangeStatus updateImpl(Attributor &A) override;
2191};
2192
2193ChangeStatus AANoSyncImpl::updateImpl(Attributor &A) {
2194
2195 auto CheckRWInstForNoSync = [&](Instruction &I) {
2196 return AA::isNoSyncInst(A, I, *this);
2197 };
2198
2199 auto CheckForNoSync = [&](Instruction &I) {
2200 // At this point we handled all read/write effects and they are all
2201 // nosync, so they can be skipped.
2202 if (I.mayReadOrWriteMemory())
2203 return true;
2204
2205 bool IsKnown;
2206 CallBase &CB = cast<CallBase>(I);
2207 if (AA::hasAssumedIRAttr<Attribute::NoSync>(
2209 IsKnown))
2210 return true;
2211
2212 // non-convergent and readnone imply nosync.
2213 return !CB.isConvergent();
2214 };
2215
2216 bool UsedAssumedInformation = false;
2217 if (!A.checkForAllReadWriteInstructions(CheckRWInstForNoSync, *this,
2218 UsedAssumedInformation) ||
2219 !A.checkForAllCallLikeInstructions(CheckForNoSync, *this,
2220 UsedAssumedInformation))
2221 return indicatePessimisticFixpoint();
2222
2224}
2225
2226struct AANoSyncFunction final : public AANoSyncImpl {
2227 AANoSyncFunction(const IRPosition &IRP, Attributor &A)
2228 : AANoSyncImpl(IRP, A) {}
2229
2230 /// See AbstractAttribute::trackStatistics()
2231 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nosync) }
2232};
2233
2234/// NoSync attribute deduction for a call sites.
2235struct AANoSyncCallSite final : AACalleeToCallSite<AANoSync, AANoSyncImpl> {
2236 AANoSyncCallSite(const IRPosition &IRP, Attributor &A)
2237 : AACalleeToCallSite<AANoSync, AANoSyncImpl>(IRP, A) {}
2238
2239 /// See AbstractAttribute::trackStatistics()
2240 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nosync); }
2241};
2242} // namespace
2243
2244/// ------------------------ No-Free Attributes ----------------------------
2245
2246namespace {
2247struct AANoFreeImpl : public AANoFree {
2248 AANoFreeImpl(const IRPosition &IRP, Attributor &A) : AANoFree(IRP, A) {}
2249
2250 /// See AbstractAttribute::initialize(...).
2251 void initialize(Attributor &A) override {
2252 bool IsKnown;
2253 assert(!AA::hasAssumedIRAttr<Attribute::NoFree>(A, nullptr, getIRPosition(),
2254 DepClassTy::NONE, IsKnown));
2255 (void)IsKnown;
2256 }
2257
2258 /// See AbstractAttribute::updateImpl(...).
2259 ChangeStatus updateImpl(Attributor &A) override {
2260 auto CheckForNoFree = [&](Instruction &I) {
2261 bool IsKnown;
2262 return AA::hasAssumedIRAttr<Attribute::NoFree>(
2263 A, this, IRPosition::callsite_function(cast<CallBase>(I)),
2264 DepClassTy::REQUIRED, IsKnown);
2265 };
2266
2267 bool UsedAssumedInformation = false;
2268 if (!A.checkForAllCallLikeInstructions(CheckForNoFree, *this,
2269 UsedAssumedInformation))
2270 return indicatePessimisticFixpoint();
2271 return ChangeStatus::UNCHANGED;
2272 }
2273
2274 /// See AbstractAttribute::getAsStr().
2275 const std::string getAsStr(Attributor *A) const override {
2276 return getAssumed() ? "nofree" : "may-free";
2277 }
2278};
2279
2280struct AANoFreeFunction final : public AANoFreeImpl {
2281 AANoFreeFunction(const IRPosition &IRP, Attributor &A)
2282 : AANoFreeImpl(IRP, A) {}
2283
2284 /// See AbstractAttribute::trackStatistics()
2285 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nofree) }
2286};
2287
2288/// NoFree attribute deduction for a call sites.
2289struct AANoFreeCallSite final : AACalleeToCallSite<AANoFree, AANoFreeImpl> {
2290 AANoFreeCallSite(const IRPosition &IRP, Attributor &A)
2291 : AACalleeToCallSite<AANoFree, AANoFreeImpl>(IRP, A) {}
2292
2293 /// See AbstractAttribute::trackStatistics()
2294 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nofree); }
2295};
2296
2297/// NoFree attribute for floating values.
2298struct AANoFreeFloating : AANoFreeImpl {
2299 AANoFreeFloating(const IRPosition &IRP, Attributor &A)
2300 : AANoFreeImpl(IRP, A) {}
2301
2302 /// See AbstractAttribute::trackStatistics()
2303 void trackStatistics() const override{STATS_DECLTRACK_FLOATING_ATTR(nofree)}
2304
2305 /// See Abstract Attribute::updateImpl(...).
2306 ChangeStatus updateImpl(Attributor &A) override {
2307 const IRPosition &IRP = getIRPosition();
2308
2309 bool IsKnown;
2310 if (AA::hasAssumedIRAttr<Attribute::NoFree>(A, this,
2312 DepClassTy::OPTIONAL, IsKnown))
2313 return ChangeStatus::UNCHANGED;
2314
2315 Value &AssociatedValue = getIRPosition().getAssociatedValue();
2316 auto Pred = [&](const Use &U, bool &Follow) -> bool {
2317 Instruction *UserI = cast<Instruction>(U.getUser());
2318 if (auto *CB = dyn_cast<CallBase>(UserI)) {
2319 if (CB->isBundleOperand(&U))
2320 return false;
2321 if (!CB->isArgOperand(&U))
2322 return true;
2323 unsigned ArgNo = CB->getArgOperandNo(&U);
2324
2325 bool IsKnown;
2326 return AA::hasAssumedIRAttr<Attribute::NoFree>(
2327 A, this, IRPosition::callsite_argument(*CB, ArgNo),
2328 DepClassTy::REQUIRED, IsKnown);
2329 }
2330
2331 if (isa<GetElementPtrInst>(UserI) || isa<BitCastInst>(UserI) ||
2332 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) {
2333 Follow = true;
2334 return true;
2335 }
2336 if (isa<StoreInst>(UserI) || isa<LoadInst>(UserI) ||
2337 isa<ReturnInst>(UserI))
2338 return true;
2339
2340 // Unknown user.
2341 return false;
2342 };
2343 if (!A.checkForAllUses(Pred, *this, AssociatedValue))
2344 return indicatePessimisticFixpoint();
2345
2346 return ChangeStatus::UNCHANGED;
2347 }
2348};
2349
2350/// NoFree attribute for a call site argument.
2351struct AANoFreeArgument final : AANoFreeFloating {
2352 AANoFreeArgument(const IRPosition &IRP, Attributor &A)
2353 : AANoFreeFloating(IRP, A) {}
2354
2355 /// See AbstractAttribute::trackStatistics()
2356 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nofree) }
2357};
2358
2359/// NoFree attribute for call site arguments.
2360struct AANoFreeCallSiteArgument final : AANoFreeFloating {
2361 AANoFreeCallSiteArgument(const IRPosition &IRP, Attributor &A)
2362 : AANoFreeFloating(IRP, A) {}
2363
2364 /// See AbstractAttribute::updateImpl(...).
2365 ChangeStatus updateImpl(Attributor &A) override {
2366 // TODO: Once we have call site specific value information we can provide
2367 // call site specific liveness information and then it makes
2368 // sense to specialize attributes for call sites arguments instead of
2369 // redirecting requests to the callee argument.
2370 Argument *Arg = getAssociatedArgument();
2371 if (!Arg)
2372 return indicatePessimisticFixpoint();
2373 const IRPosition &ArgPos = IRPosition::argument(*Arg);
2374 bool IsKnown;
2375 if (AA::hasAssumedIRAttr<Attribute::NoFree>(A, this, ArgPos,
2376 DepClassTy::REQUIRED, IsKnown))
2377 return ChangeStatus::UNCHANGED;
2378 return indicatePessimisticFixpoint();
2379 }
2380
2381 /// See AbstractAttribute::trackStatistics()
2382 void trackStatistics() const override{STATS_DECLTRACK_CSARG_ATTR(nofree)};
2383};
2384
2385/// NoFree attribute for function return value.
2386struct AANoFreeReturned final : AANoFreeFloating {
2387 AANoFreeReturned(const IRPosition &IRP, Attributor &A)
2388 : AANoFreeFloating(IRP, A) {
2389 llvm_unreachable("NoFree is not applicable to function returns!");
2390 }
2391
2392 /// See AbstractAttribute::initialize(...).
2393 void initialize(Attributor &A) override {
2394 llvm_unreachable("NoFree is not applicable to function returns!");
2395 }
2396
2397 /// See AbstractAttribute::updateImpl(...).
2398 ChangeStatus updateImpl(Attributor &A) override {
2399 llvm_unreachable("NoFree is not applicable to function returns!");
2400 }
2401
2402 /// See AbstractAttribute::trackStatistics()
2403 void trackStatistics() const override {}
2404};
2405
2406/// NoFree attribute deduction for a call site return value.
2407struct AANoFreeCallSiteReturned final : AANoFreeFloating {
2408 AANoFreeCallSiteReturned(const IRPosition &IRP, Attributor &A)
2409 : AANoFreeFloating(IRP, A) {}
2410
2411 ChangeStatus manifest(Attributor &A) override {
2412 return ChangeStatus::UNCHANGED;
2413 }
2414 /// See AbstractAttribute::trackStatistics()
2415 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(nofree) }
2416};
2417} // namespace
2418
2419/// ------------------------ NonNull Argument Attribute ------------------------
2420
2422 Attribute::AttrKind ImpliedAttributeKind,
2423 bool IgnoreSubsumingPositions) {
2425 AttrKinds.push_back(Attribute::NonNull);
2428 AttrKinds.push_back(Attribute::Dereferenceable);
2429 if (A.hasAttr(IRP, AttrKinds, IgnoreSubsumingPositions, Attribute::NonNull))
2430 return true;
2431
2432 DominatorTree *DT = nullptr;
2433 AssumptionCache *AC = nullptr;
2434 InformationCache &InfoCache = A.getInfoCache();
2435 if (const Function *Fn = IRP.getAnchorScope()) {
2436 if (!Fn->isDeclaration()) {
2439 }
2440 }
2441
2443 if (IRP.getPositionKind() != IRP_RETURNED) {
2444 Worklist.push_back({IRP.getAssociatedValue(), IRP.getCtxI()});
2445 } else {
2446 bool UsedAssumedInformation = false;
2447 if (!A.checkForAllInstructions(
2448 [&](Instruction &I) {
2449 Worklist.push_back({*cast<ReturnInst>(I).getReturnValue(), &I});
2450 return true;
2451 },
2452 IRP.getAssociatedFunction(), nullptr, {Instruction::Ret},
2453 UsedAssumedInformation, false, /*CheckPotentiallyDead=*/true))
2454 return false;
2455 }
2456
2457 if (llvm::any_of(Worklist, [&](AA::ValueAndContext VAC) {
2458 return !isKnownNonZero(
2459 VAC.getValue(),
2460 SimplifyQuery(A.getDataLayout(), DT, AC, VAC.getCtxI()));
2461 }))
2462 return false;
2463
2464 A.manifestAttrs(IRP, {Attribute::get(IRP.getAnchorValue().getContext(),
2465 Attribute::NonNull)});
2466 return true;
2467}
2468
2469namespace {
2470static int64_t getKnownNonNullAndDerefBytesForUse(
2471 Attributor &A, const AbstractAttribute &QueryingAA, Value &AssociatedValue,
2472 const Use *U, const Instruction *I, bool &IsNonNull, bool &TrackUse) {
2473 TrackUse = false;
2474
2475 const Value *UseV = U->get();
2476 if (!UseV->getType()->isPointerTy())
2477 return 0;
2478
2479 // We need to follow common pointer manipulation uses to the accesses they
2480 // feed into. We can try to be smart to avoid looking through things we do not
2481 // like for now, e.g., non-inbounds GEPs.
2482 if (isa<CastInst>(I)) {
2483 TrackUse = true;
2484 return 0;
2485 }
2486
2487 if (isa<GetElementPtrInst>(I)) {
2488 TrackUse = true;
2489 return 0;
2490 }
2491
2492 Type *PtrTy = UseV->getType();
2493 const Function *F = I->getFunction();
2496 const DataLayout &DL = A.getInfoCache().getDL();
2497 if (const auto *CB = dyn_cast<CallBase>(I)) {
2498 if (CB->isBundleOperand(U)) {
2500 U, {Attribute::NonNull, Attribute::Dereferenceable})) {
2501 IsNonNull |=
2502 (RK.AttrKind == Attribute::NonNull || !NullPointerIsDefined);
2503 return RK.ArgValue;
2504 }
2505 return 0;
2506 }
2507
2508 if (CB->isCallee(U)) {
2509 IsNonNull |= !NullPointerIsDefined;
2510 return 0;
2511 }
2512
2513 unsigned ArgNo = CB->getArgOperandNo(U);
2514 IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo);
2515 // As long as we only use known information there is no need to track
2516 // dependences here.
2517 bool IsKnownNonNull;
2518 AA::hasAssumedIRAttr<Attribute::NonNull>(A, &QueryingAA, IRP,
2519 DepClassTy::NONE, IsKnownNonNull);
2520 IsNonNull |= IsKnownNonNull;
2521 auto *DerefAA =
2522 A.getAAFor<AADereferenceable>(QueryingAA, IRP, DepClassTy::NONE);
2523 return DerefAA ? DerefAA->getKnownDereferenceableBytes() : 0;
2524 }
2525
2526 std::optional<MemoryLocation> Loc = MemoryLocation::getOrNone(I);
2527 if (!Loc || Loc->Ptr != UseV || !Loc->Size.isPrecise() ||
2528 Loc->Size.isScalable() || I->isVolatile())
2529 return 0;
2530
2531 int64_t Offset;
2532 const Value *Base =
2533 getMinimalBaseOfPointer(A, QueryingAA, Loc->Ptr, Offset, DL);
2534 if (Base && Base == &AssociatedValue) {
2535 int64_t DerefBytes = Loc->Size.getValue() + Offset;
2536 IsNonNull |= !NullPointerIsDefined;
2537 return std::max(int64_t(0), DerefBytes);
2538 }
2539
2540 /// Corner case when an offset is 0.
2542 /*AllowNonInbounds*/ true);
2543 if (Base && Base == &AssociatedValue && Offset == 0) {
2544 int64_t DerefBytes = Loc->Size.getValue();
2545 IsNonNull |= !NullPointerIsDefined;
2546 return std::max(int64_t(0), DerefBytes);
2547 }
2548
2549 return 0;
2550}
2551
2552struct AANonNullImpl : AANonNull {
2553 AANonNullImpl(const IRPosition &IRP, Attributor &A) : AANonNull(IRP, A) {}
2554
2555 /// See AbstractAttribute::initialize(...).
2556 void initialize(Attributor &A) override {
2557 Value &V = *getAssociatedValue().stripPointerCasts();
2558 if (isa<ConstantPointerNull>(V)) {
2559 indicatePessimisticFixpoint();
2560 return;
2561 }
2562
2563 if (Instruction *CtxI = getCtxI())
2564 followUsesInMBEC(*this, A, getState(), *CtxI);
2565 }
2566
2567 /// See followUsesInMBEC
2568 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
2569 AANonNull::StateType &State) {
2570 bool IsNonNull = false;
2571 bool TrackUse = false;
2572 getKnownNonNullAndDerefBytesForUse(A, *this, getAssociatedValue(), U, I,
2573 IsNonNull, TrackUse);
2574 State.setKnown(IsNonNull);
2575 return TrackUse;
2576 }
2577
2578 /// See AbstractAttribute::getAsStr().
2579 const std::string getAsStr(Attributor *A) const override {
2580 return getAssumed() ? "nonnull" : "may-null";
2581 }
2582};
2583
2584/// NonNull attribute for a floating value.
2585struct AANonNullFloating : public AANonNullImpl {
2586 AANonNullFloating(const IRPosition &IRP, Attributor &A)
2587 : AANonNullImpl(IRP, A) {}
2588
2589 /// See AbstractAttribute::updateImpl(...).
2590 ChangeStatus updateImpl(Attributor &A) override {
2591 auto CheckIRP = [&](const IRPosition &IRP) {
2592 bool IsKnownNonNull;
2593 return AA::hasAssumedIRAttr<Attribute::NonNull>(
2594 A, *this, IRP, DepClassTy::OPTIONAL, IsKnownNonNull);
2595 };
2596
2597 bool Stripped;
2598 bool UsedAssumedInformation = false;
2599 Value *AssociatedValue = &getAssociatedValue();
2601 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
2602 AA::AnyScope, UsedAssumedInformation))
2603 Stripped = false;
2604 else
2605 Stripped =
2606 Values.size() != 1 || Values.front().getValue() != AssociatedValue;
2607
2608 if (!Stripped) {
2609 bool IsKnown;
2610 if (auto *PHI = dyn_cast<PHINode>(AssociatedValue))
2611 if (llvm::all_of(PHI->incoming_values(), [&](Value *Op) {
2612 return AA::hasAssumedIRAttr<Attribute::NonNull>(
2613 A, this, IRPosition::value(*Op), DepClassTy::OPTIONAL,
2614 IsKnown);
2615 }))
2616 return ChangeStatus::UNCHANGED;
2617 if (auto *Select = dyn_cast<SelectInst>(AssociatedValue))
2618 if (AA::hasAssumedIRAttr<Attribute::NonNull>(
2619 A, this, IRPosition::value(*Select->getFalseValue()),
2620 DepClassTy::OPTIONAL, IsKnown) &&
2621 AA::hasAssumedIRAttr<Attribute::NonNull>(
2622 A, this, IRPosition::value(*Select->getTrueValue()),
2623 DepClassTy::OPTIONAL, IsKnown))
2624 return ChangeStatus::UNCHANGED;
2625
2626 // If we haven't stripped anything we might still be able to use a
2627 // different AA, but only if the IRP changes. Effectively when we
2628 // interpret this not as a call site value but as a floating/argument
2629 // value.
2630 const IRPosition AVIRP = IRPosition::value(*AssociatedValue);
2631 if (AVIRP == getIRPosition() || !CheckIRP(AVIRP))
2632 return indicatePessimisticFixpoint();
2633 return ChangeStatus::UNCHANGED;
2634 }
2635
2636 for (const auto &VAC : Values)
2637 if (!CheckIRP(IRPosition::value(*VAC.getValue())))
2638 return indicatePessimisticFixpoint();
2639
2640 return ChangeStatus::UNCHANGED;
2641 }
2642
2643 /// See AbstractAttribute::trackStatistics()
2644 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
2645};
2646
2647/// NonNull attribute for function return value.
2648struct AANonNullReturned final
2649 : AAReturnedFromReturnedValues<AANonNull, AANonNull, AANonNull::StateType,
2650 false, AANonNull::IRAttributeKind, false> {
2651 AANonNullReturned(const IRPosition &IRP, Attributor &A)
2652 : AAReturnedFromReturnedValues<AANonNull, AANonNull, AANonNull::StateType,
2653 false, Attribute::NonNull, false>(IRP, A) {
2654 }
2655
2656 /// See AbstractAttribute::getAsStr().
2657 const std::string getAsStr(Attributor *A) const override {
2658 return getAssumed() ? "nonnull" : "may-null";
2659 }
2660
2661 /// See AbstractAttribute::trackStatistics()
2662 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
2663};
2664
2665/// NonNull attribute for function argument.
2666struct AANonNullArgument final
2667 : AAArgumentFromCallSiteArguments<AANonNull, AANonNullImpl> {
2668 AANonNullArgument(const IRPosition &IRP, Attributor &A)
2669 : AAArgumentFromCallSiteArguments<AANonNull, AANonNullImpl>(IRP, A) {}
2670
2671 /// See AbstractAttribute::trackStatistics()
2672 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nonnull) }
2673};
2674
2675struct AANonNullCallSiteArgument final : AANonNullFloating {
2676 AANonNullCallSiteArgument(const IRPosition &IRP, Attributor &A)
2677 : AANonNullFloating(IRP, A) {}
2678
2679 /// See AbstractAttribute::trackStatistics()
2680 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(nonnull) }
2681};
2682
2683/// NonNull attribute for a call site return position.
2684struct AANonNullCallSiteReturned final
2685 : AACalleeToCallSite<AANonNull, AANonNullImpl> {
2686 AANonNullCallSiteReturned(const IRPosition &IRP, Attributor &A)
2687 : AACalleeToCallSite<AANonNull, AANonNullImpl>(IRP, A) {}
2688
2689 /// See AbstractAttribute::trackStatistics()
2690 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(nonnull) }
2691};
2692} // namespace
2693
2694/// ------------------------ Must-Progress Attributes --------------------------
2695namespace {
2696struct AAMustProgressImpl : public AAMustProgress {
2697 AAMustProgressImpl(const IRPosition &IRP, Attributor &A)
2698 : AAMustProgress(IRP, A) {}
2699
2700 /// See AbstractAttribute::initialize(...).
2701 void initialize(Attributor &A) override {
2702 bool IsKnown;
2703 assert(!AA::hasAssumedIRAttr<Attribute::MustProgress>(
2704 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
2705 (void)IsKnown;
2706 }
2707
2708 /// See AbstractAttribute::getAsStr()
2709 const std::string getAsStr(Attributor *A) const override {
2710 return getAssumed() ? "mustprogress" : "may-not-progress";
2711 }
2712};
2713
2714struct AAMustProgressFunction final : AAMustProgressImpl {
2715 AAMustProgressFunction(const IRPosition &IRP, Attributor &A)
2716 : AAMustProgressImpl(IRP, A) {}
2717
2718 /// See AbstractAttribute::updateImpl(...).
2719 ChangeStatus updateImpl(Attributor &A) override {
2720 bool IsKnown;
2721 if (AA::hasAssumedIRAttr<Attribute::WillReturn>(
2722 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnown)) {
2723 if (IsKnown)
2724 return indicateOptimisticFixpoint();
2725 return ChangeStatus::UNCHANGED;
2726 }
2727
2728 auto CheckForMustProgress = [&](AbstractCallSite ACS) {
2729 IRPosition IPos = IRPosition::callsite_function(*ACS.getInstruction());
2730 bool IsKnownMustProgress;
2731 return AA::hasAssumedIRAttr<Attribute::MustProgress>(
2732 A, this, IPos, DepClassTy::REQUIRED, IsKnownMustProgress,
2733 /* IgnoreSubsumingPositions */ true);
2734 };
2735
2736 bool AllCallSitesKnown = true;
2737 if (!A.checkForAllCallSites(CheckForMustProgress, *this,
2738 /* RequireAllCallSites */ true,
2739 AllCallSitesKnown))
2740 return indicatePessimisticFixpoint();
2741
2742 return ChangeStatus::UNCHANGED;
2743 }
2744
2745 /// See AbstractAttribute::trackStatistics()
2746 void trackStatistics() const override {
2747 STATS_DECLTRACK_FN_ATTR(mustprogress)
2748 }
2749};
2750
2751/// MustProgress attribute deduction for a call sites.
2752struct AAMustProgressCallSite final : AAMustProgressImpl {
2753 AAMustProgressCallSite(const IRPosition &IRP, Attributor &A)
2754 : AAMustProgressImpl(IRP, A) {}
2755
2756 /// See AbstractAttribute::updateImpl(...).
2757 ChangeStatus updateImpl(Attributor &A) override {
2758 // TODO: Once we have call site specific value information we can provide
2759 // call site specific liveness information and then it makes
2760 // sense to specialize attributes for call sites arguments instead of
2761 // redirecting requests to the callee argument.
2762 const IRPosition &FnPos = IRPosition::function(*getAnchorScope());
2763 bool IsKnownMustProgress;
2764 if (!AA::hasAssumedIRAttr<Attribute::MustProgress>(
2765 A, this, FnPos, DepClassTy::REQUIRED, IsKnownMustProgress))
2766 return indicatePessimisticFixpoint();
2767 return ChangeStatus::UNCHANGED;
2768 }
2769
2770 /// See AbstractAttribute::trackStatistics()
2771 void trackStatistics() const override {
2772 STATS_DECLTRACK_CS_ATTR(mustprogress);
2773 }
2774};
2775} // namespace
2776
2777/// ------------------------ No-Recurse Attributes ----------------------------
2778
2779namespace {
2780struct AANoRecurseImpl : public AANoRecurse {
2781 AANoRecurseImpl(const IRPosition &IRP, Attributor &A) : AANoRecurse(IRP, A) {}
2782
2783 /// See AbstractAttribute::initialize(...).
2784 void initialize(Attributor &A) override {
2785 bool IsKnown;
2786 assert(!AA::hasAssumedIRAttr<Attribute::NoRecurse>(
2787 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
2788 (void)IsKnown;
2789 }
2790
2791 /// See AbstractAttribute::getAsStr()
2792 const std::string getAsStr(Attributor *A) const override {
2793 return getAssumed() ? "norecurse" : "may-recurse";
2794 }
2795};
2796
2797struct AANoRecurseFunction final : AANoRecurseImpl {
2798 AANoRecurseFunction(const IRPosition &IRP, Attributor &A)
2799 : AANoRecurseImpl(IRP, A) {}
2800
2801 /// See AbstractAttribute::updateImpl(...).
2802 ChangeStatus updateImpl(Attributor &A) override {
2803
2804 // If all live call sites are known to be no-recurse, we are as well.
2805 auto CallSitePred = [&](AbstractCallSite ACS) {
2806 bool IsKnownNoRecurse;
2807 if (!AA::hasAssumedIRAttr<Attribute::NoRecurse>(
2808 A, this,
2809 IRPosition::function(*ACS.getInstruction()->getFunction()),
2810 DepClassTy::NONE, IsKnownNoRecurse))
2811 return false;
2812 return IsKnownNoRecurse;
2813 };
2814 bool UsedAssumedInformation = false;
2815 if (A.checkForAllCallSites(CallSitePred, *this, true,
2816 UsedAssumedInformation)) {
2817 // If we know all call sites and all are known no-recurse, we are done.
2818 // If all known call sites, which might not be all that exist, are known
2819 // to be no-recurse, we are not done but we can continue to assume
2820 // no-recurse. If one of the call sites we have not visited will become
2821 // live, another update is triggered.
2822 if (!UsedAssumedInformation)
2823 indicateOptimisticFixpoint();
2824 return ChangeStatus::UNCHANGED;
2825 }
2826
2827 const AAInterFnReachability *EdgeReachability =
2828 A.getAAFor<AAInterFnReachability>(*this, getIRPosition(),
2829 DepClassTy::REQUIRED);
2830 if (EdgeReachability && EdgeReachability->canReach(A, *getAnchorScope()))
2831 return indicatePessimisticFixpoint();
2832 return ChangeStatus::UNCHANGED;
2833 }
2834
2835 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(norecurse) }
2836};
2837
2838/// NoRecurse attribute deduction for a call sites.
2839struct AANoRecurseCallSite final
2840 : AACalleeToCallSite<AANoRecurse, AANoRecurseImpl> {
2841 AANoRecurseCallSite(const IRPosition &IRP, Attributor &A)
2842 : AACalleeToCallSite<AANoRecurse, AANoRecurseImpl>(IRP, A) {}
2843
2844 /// See AbstractAttribute::trackStatistics()
2845 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(norecurse); }
2846};
2847} // namespace
2848
2849/// ------------------------ No-Convergent Attribute --------------------------
2850
2851namespace {
2852struct AANonConvergentImpl : public AANonConvergent {
2853 AANonConvergentImpl(const IRPosition &IRP, Attributor &A)
2854 : AANonConvergent(IRP, A) {}
2855
2856 /// See AbstractAttribute::getAsStr()
2857 const std::string getAsStr(Attributor *A) const override {
2858 return getAssumed() ? "non-convergent" : "may-be-convergent";
2859 }
2860};
2861
2862struct AANonConvergentFunction final : AANonConvergentImpl {
2863 AANonConvergentFunction(const IRPosition &IRP, Attributor &A)
2864 : AANonConvergentImpl(IRP, A) {}
2865
2866 /// See AbstractAttribute::updateImpl(...).
2867 ChangeStatus updateImpl(Attributor &A) override {
2868 // If all function calls are known to not be convergent, we are not
2869 // convergent.
2870 auto CalleeIsNotConvergent = [&](Instruction &Inst) {
2871 CallBase &CB = cast<CallBase>(Inst);
2872 auto *Callee = dyn_cast_if_present<Function>(CB.getCalledOperand());
2873 if (!Callee || Callee->isIntrinsic()) {
2874 return false;
2875 }
2876 if (Callee->isDeclaration()) {
2877 return !Callee->hasFnAttribute(Attribute::Convergent);
2878 }
2879 const auto *ConvergentAA = A.getAAFor<AANonConvergent>(
2880 *this, IRPosition::function(*Callee), DepClassTy::REQUIRED);
2881 return ConvergentAA && ConvergentAA->isAssumedNotConvergent();
2882 };
2883
2884 bool UsedAssumedInformation = false;
2885 if (!A.checkForAllCallLikeInstructions(CalleeIsNotConvergent, *this,
2886 UsedAssumedInformation)) {
2887 return indicatePessimisticFixpoint();
2888 }
2889 return ChangeStatus::UNCHANGED;
2890 }
2891
2892 ChangeStatus manifest(Attributor &A) override {
2893 if (isKnownNotConvergent() &&
2894 A.hasAttr(getIRPosition(), Attribute::Convergent)) {
2895 A.removeAttrs(getIRPosition(), {Attribute::Convergent});
2896 return ChangeStatus::CHANGED;
2897 }
2898 return ChangeStatus::UNCHANGED;
2899 }
2900
2901 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(convergent) }
2902};
2903} // namespace
2904
2905/// -------------------- Undefined-Behavior Attributes ------------------------
2906
2907namespace {
2908struct AAUndefinedBehaviorImpl : public AAUndefinedBehavior {
2909 AAUndefinedBehaviorImpl(const IRPosition &IRP, Attributor &A)
2910 : AAUndefinedBehavior(IRP, A) {}
2911
2912 /// See AbstractAttribute::updateImpl(...).
2913 // through a pointer (i.e. also branches etc.)
2914 ChangeStatus updateImpl(Attributor &A) override {
2915 const size_t UBPrevSize = KnownUBInsts.size();
2916 const size_t NoUBPrevSize = AssumedNoUBInsts.size();
2917
2918 auto InspectMemAccessInstForUB = [&](Instruction &I) {
2919 // Lang ref now states volatile store is not UB, let's skip them.
2920 if (I.isVolatile() && I.mayWriteToMemory())
2921 return true;
2922
2923 // Skip instructions that are already saved.
2924 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
2925 return true;
2926
2927 // If we reach here, we know we have an instruction
2928 // that accesses memory through a pointer operand,
2929 // for which getPointerOperand() should give it to us.
2930 Value *PtrOp =
2931 const_cast<Value *>(getPointerOperand(&I, /* AllowVolatile */ true));
2932 assert(PtrOp &&
2933 "Expected pointer operand of memory accessing instruction");
2934
2935 // Either we stopped and the appropriate action was taken,
2936 // or we got back a simplified value to continue.
2937 std::optional<Value *> SimplifiedPtrOp =
2938 stopOnUndefOrAssumed(A, PtrOp, &I);
2939 if (!SimplifiedPtrOp || !*SimplifiedPtrOp)
2940 return true;
2941 const Value *PtrOpVal = *SimplifiedPtrOp;
2942
2943 // A memory access through a pointer is considered UB
2944 // only if the pointer has constant null value.
2945 // TODO: Expand it to not only check constant values.
2946 if (!isa<ConstantPointerNull>(PtrOpVal)) {
2947 AssumedNoUBInsts.insert(&I);
2948 return true;
2949 }
2950 const Type *PtrTy = PtrOpVal->getType();
2951
2952 // Because we only consider instructions inside functions,
2953 // assume that a parent function exists.
2954 const Function *F = I.getFunction();
2955
2956 // A memory access using constant null pointer is only considered UB
2957 // if null pointer is _not_ defined for the target platform.
2959 AssumedNoUBInsts.insert(&I);
2960 else
2961 KnownUBInsts.insert(&I);
2962 return true;
2963 };
2964
2965 auto InspectBrInstForUB = [&](Instruction &I) {
2966 // A conditional branch instruction is considered UB if it has `undef`
2967 // condition.
2968
2969 // Skip instructions that are already saved.
2970 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
2971 return true;
2972
2973 // We know we have a branch instruction.
2974 auto *BrInst = cast<BranchInst>(&I);
2975
2976 // Unconditional branches are never considered UB.
2977 if (BrInst->isUnconditional())
2978 return true;
2979
2980 // Either we stopped and the appropriate action was taken,
2981 // or we got back a simplified value to continue.
2982 std::optional<Value *> SimplifiedCond =
2983 stopOnUndefOrAssumed(A, BrInst->getCondition(), BrInst);
2984 if (!SimplifiedCond || !*SimplifiedCond)
2985 return true;
2986 AssumedNoUBInsts.insert(&I);
2987 return true;
2988 };
2989
2990 auto InspectCallSiteForUB = [&](Instruction &I) {
2991 // Check whether a callsite always cause UB or not
2992
2993 // Skip instructions that are already saved.
2994 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
2995 return true;
2996
2997 // Check nonnull and noundef argument attribute violation for each
2998 // callsite.
2999 CallBase &CB = cast<CallBase>(I);
3000 auto *Callee = dyn_cast_if_present<Function>(CB.getCalledOperand());
3001 if (!Callee)
3002 return true;
3003 for (unsigned idx = 0; idx < CB.arg_size(); idx++) {
3004 // If current argument is known to be simplified to null pointer and the
3005 // corresponding argument position is known to have nonnull attribute,
3006 // the argument is poison. Furthermore, if the argument is poison and
3007 // the position is known to have noundef attriubte, this callsite is
3008 // considered UB.
3009 if (idx >= Callee->arg_size())
3010 break;
3011 Value *ArgVal = CB.getArgOperand(idx);
3012 if (!ArgVal)
3013 continue;
3014 // Here, we handle three cases.
3015 // (1) Not having a value means it is dead. (we can replace the value
3016 // with undef)
3017 // (2) Simplified to undef. The argument violate noundef attriubte.
3018 // (3) Simplified to null pointer where known to be nonnull.
3019 // The argument is a poison value and violate noundef attribute.
3020 IRPosition CalleeArgumentIRP = IRPosition::callsite_argument(CB, idx);
3021 bool IsKnownNoUndef;
3022 AA::hasAssumedIRAttr<Attribute::NoUndef>(
3023 A, this, CalleeArgumentIRP, DepClassTy::NONE, IsKnownNoUndef);
3024 if (!IsKnownNoUndef)
3025 continue;
3026 bool UsedAssumedInformation = false;
3027 std::optional<Value *> SimplifiedVal =
3028 A.getAssumedSimplified(IRPosition::value(*ArgVal), *this,
3029 UsedAssumedInformation, AA::Interprocedural);
3030 if (UsedAssumedInformation)
3031 continue;
3032 if (SimplifiedVal && !*SimplifiedVal)
3033 return true;
3034 if (!SimplifiedVal || isa<UndefValue>(**SimplifiedVal)) {
3035 KnownUBInsts.insert(&I);
3036 continue;
3037 }
3038 if (!ArgVal->getType()->isPointerTy() ||
3039 !isa<ConstantPointerNull>(**SimplifiedVal))
3040 continue;
3041 bool IsKnownNonNull;
3042 AA::hasAssumedIRAttr<Attribute::NonNull>(
3043 A, this, CalleeArgumentIRP, DepClassTy::NONE, IsKnownNonNull);
3044 if (IsKnownNonNull)
3045 KnownUBInsts.insert(&I);
3046 }
3047 return true;
3048 };
3049
3050 auto InspectReturnInstForUB = [&](Instruction &I) {
3051 auto &RI = cast<ReturnInst>(I);
3052 // Either we stopped and the appropriate action was taken,
3053 // or we got back a simplified return value to continue.
3054 std::optional<Value *> SimplifiedRetValue =
3055 stopOnUndefOrAssumed(A, RI.getReturnValue(), &I);
3056 if (!SimplifiedRetValue || !*SimplifiedRetValue)
3057 return true;
3058
3059 // Check if a return instruction always cause UB or not
3060 // Note: It is guaranteed that the returned position of the anchor
3061 // scope has noundef attribute when this is called.
3062 // We also ensure the return position is not "assumed dead"
3063 // because the returned value was then potentially simplified to
3064 // `undef` in AAReturnedValues without removing the `noundef`
3065 // attribute yet.
3066
3067 // When the returned position has noundef attriubte, UB occurs in the
3068 // following cases.
3069 // (1) Returned value is known to be undef.
3070 // (2) The value is known to be a null pointer and the returned
3071 // position has nonnull attribute (because the returned value is
3072 // poison).
3073 if (isa<ConstantPointerNull>(*SimplifiedRetValue)) {
3074 bool IsKnownNonNull;
3075 AA::hasAssumedIRAttr<Attribute::NonNull>(
3076 A, this, IRPosition::returned(*getAnchorScope()), DepClassTy::NONE,
3077 IsKnownNonNull);
3078 if (IsKnownNonNull)
3079 KnownUBInsts.insert(&I);
3080 }
3081
3082 return true;
3083 };
3084
3085 bool UsedAssumedInformation = false;
3086 A.checkForAllInstructions(InspectMemAccessInstForUB, *this,
3087 {Instruction::Load, Instruction::Store,
3088 Instruction::AtomicCmpXchg,
3089 Instruction::AtomicRMW},
3090 UsedAssumedInformation,
3091 /* CheckBBLivenessOnly */ true);
3092 A.checkForAllInstructions(InspectBrInstForUB, *this, {Instruction::Br},
3093 UsedAssumedInformation,
3094 /* CheckBBLivenessOnly */ true);
3095 A.checkForAllCallLikeInstructions(InspectCallSiteForUB, *this,
3096 UsedAssumedInformation);
3097
3098 // If the returned position of the anchor scope has noundef attriubte, check
3099 // all returned instructions.
3100 if (!getAnchorScope()->getReturnType()->isVoidTy()) {
3101 const IRPosition &ReturnIRP = IRPosition::returned(*getAnchorScope());
3102 if (!A.isAssumedDead(ReturnIRP, this, nullptr, UsedAssumedInformation)) {
3103 bool IsKnownNoUndef;
3104 AA::hasAssumedIRAttr<Attribute::NoUndef>(
3105 A, this, ReturnIRP, DepClassTy::NONE, IsKnownNoUndef);
3106 if (IsKnownNoUndef)
3107 A.checkForAllInstructions(InspectReturnInstForUB, *this,
3108 {Instruction::Ret}, UsedAssumedInformation,
3109 /* CheckBBLivenessOnly */ true);
3110 }
3111 }
3112
3113 if (NoUBPrevSize != AssumedNoUBInsts.size() ||
3114 UBPrevSize != KnownUBInsts.size())
3115 return ChangeStatus::CHANGED;
3116 return ChangeStatus::UNCHANGED;
3117 }
3118
3119 bool isKnownToCauseUB(Instruction *I) const override {
3120 return KnownUBInsts.count(I);
3121 }
3122
3123 bool isAssumedToCauseUB(Instruction *I) const override {
3124 // In simple words, if an instruction is not in the assumed to _not_
3125 // cause UB, then it is assumed UB (that includes those
3126 // in the KnownUBInsts set). The rest is boilerplate
3127 // is to ensure that it is one of the instructions we test
3128 // for UB.
3129
3130 switch (I->getOpcode()) {
3131 case Instruction::Load:
3132 case Instruction::Store:
3133 case Instruction::AtomicCmpXchg:
3134 case Instruction::AtomicRMW:
3135 return !AssumedNoUBInsts.count(I);
3136 case Instruction::Br: {
3137 auto *BrInst = cast<BranchInst>(I);
3138 if (BrInst->isUnconditional())
3139 return false;
3140 return !AssumedNoUBInsts.count(I);
3141 } break;
3142 default:
3143 return false;
3144 }
3145 return false;
3146 }
3147
3148 ChangeStatus manifest(Attributor &A) override {
3149 if (KnownUBInsts.empty())
3150 return ChangeStatus::UNCHANGED;
3151 for (Instruction *I : KnownUBInsts)
3152 A.changeToUnreachableAfterManifest(I);
3153 return ChangeStatus::CHANGED;
3154 }
3155
3156 /// See AbstractAttribute::getAsStr()
3157 const std::string getAsStr(Attributor *A) const override {
3158 return getAssumed() ? "undefined-behavior" : "no-ub";
3159 }
3160
3161 /// Note: The correctness of this analysis depends on the fact that the
3162 /// following 2 sets will stop changing after some point.
3163 /// "Change" here means that their size changes.
3164 /// The size of each set is monotonically increasing
3165 /// (we only add items to them) and it is upper bounded by the number of
3166 /// instructions in the processed function (we can never save more
3167 /// elements in either set than this number). Hence, at some point,
3168 /// they will stop increasing.
3169 /// Consequently, at some point, both sets will have stopped
3170 /// changing, effectively making the analysis reach a fixpoint.
3171
3172 /// Note: These 2 sets are disjoint and an instruction can be considered
3173 /// one of 3 things:
3174 /// 1) Known to cause UB (AAUndefinedBehavior could prove it) and put it in
3175 /// the KnownUBInsts set.
3176 /// 2) Assumed to cause UB (in every updateImpl, AAUndefinedBehavior
3177 /// has a reason to assume it).
3178 /// 3) Assumed to not cause UB. very other instruction - AAUndefinedBehavior
3179 /// could not find a reason to assume or prove that it can cause UB,
3180 /// hence it assumes it doesn't. We have a set for these instructions
3181 /// so that we don't reprocess them in every update.
3182 /// Note however that instructions in this set may cause UB.
3183
3184protected:
3185 /// A set of all live instructions _known_ to cause UB.
3186 SmallPtrSet<Instruction *, 8> KnownUBInsts;
3187
3188private:
3189 /// A set of all the (live) instructions that are assumed to _not_ cause UB.
3190 SmallPtrSet<Instruction *, 8> AssumedNoUBInsts;
3191
3192 // Should be called on updates in which if we're processing an instruction
3193 // \p I that depends on a value \p V, one of the following has to happen:
3194 // - If the value is assumed, then stop.
3195 // - If the value is known but undef, then consider it UB.
3196 // - Otherwise, do specific processing with the simplified value.
3197 // We return std::nullopt in the first 2 cases to signify that an appropriate
3198 // action was taken and the caller should stop.
3199 // Otherwise, we return the simplified value that the caller should
3200 // use for specific processing.
3201 std::optional<Value *> stopOnUndefOrAssumed(Attributor &A, Value *V,
3202 Instruction *I) {
3203 bool UsedAssumedInformation = false;
3204 std::optional<Value *> SimplifiedV =
3205 A.getAssumedSimplified(IRPosition::value(*V), *this,
3206 UsedAssumedInformation, AA::Interprocedural);
3207 if (!UsedAssumedInformation) {
3208 // Don't depend on assumed values.
3209 if (!SimplifiedV) {
3210 // If it is known (which we tested above) but it doesn't have a value,
3211 // then we can assume `undef` and hence the instruction is UB.
3212 KnownUBInsts.insert(I);
3213 return std::nullopt;
3214 }
3215 if (!*SimplifiedV)
3216 return nullptr;
3217 V = *SimplifiedV;
3218 }
3219 if (isa<UndefValue>(V)) {
3220 KnownUBInsts.insert(I);
3221 return std::nullopt;
3222 }
3223 return V;
3224 }
3225};
3226
3227struct AAUndefinedBehaviorFunction final : AAUndefinedBehaviorImpl {
3228 AAUndefinedBehaviorFunction(const IRPosition &IRP, Attributor &A)
3229 : AAUndefinedBehaviorImpl(IRP, A) {}
3230
3231 /// See AbstractAttribute::trackStatistics()
3232 void trackStatistics() const override {
3233 STATS_DECL(UndefinedBehaviorInstruction, Instruction,
3234 "Number of instructions known to have UB");
3235 BUILD_STAT_NAME(UndefinedBehaviorInstruction, Instruction) +=
3236 KnownUBInsts.size();
3237 }
3238};
3239} // namespace
3240
3241/// ------------------------ Will-Return Attributes ----------------------------
3242
3243namespace {
3244// Helper function that checks whether a function has any cycle which we don't
3245// know if it is bounded or not.
3246// Loops with maximum trip count are considered bounded, any other cycle not.
3247static bool mayContainUnboundedCycle(Function &F, Attributor &A) {
3248 ScalarEvolution *SE =
3249 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(F);
3250 LoopInfo *LI = A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(F);
3251 // If either SCEV or LoopInfo is not available for the function then we assume
3252 // any cycle to be unbounded cycle.
3253 // We use scc_iterator which uses Tarjan algorithm to find all the maximal
3254 // SCCs.To detect if there's a cycle, we only need to find the maximal ones.
3255 if (!SE || !LI) {
3256 for (scc_iterator<Function *> SCCI = scc_begin(&F); !SCCI.isAtEnd(); ++SCCI)
3257 if (SCCI.hasCycle())
3258 return true;
3259 return false;
3260 }
3261
3262 // If there's irreducible control, the function may contain non-loop cycles.
3264 return true;
3265
3266 // Any loop that does not have a max trip count is considered unbounded cycle.
3267 for (auto *L : LI->getLoopsInPreorder()) {
3268 if (!SE->getSmallConstantMaxTripCount(L))
3269 return true;
3270 }
3271 return false;
3272}
3273
3274struct AAWillReturnImpl : public AAWillReturn {
3275 AAWillReturnImpl(const IRPosition &IRP, Attributor &A)
3276 : AAWillReturn(IRP, A) {}
3277
3278 /// See AbstractAttribute::initialize(...).
3279 void initialize(Attributor &A) override {
3280 bool IsKnown;
3281 assert(!AA::hasAssumedIRAttr<Attribute::WillReturn>(
3282 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
3283 (void)IsKnown;
3284 }
3285
3286 /// Check for `mustprogress` and `readonly` as they imply `willreturn`.
3287 bool isImpliedByMustprogressAndReadonly(Attributor &A, bool KnownOnly) {
3288 if (!A.hasAttr(getIRPosition(), {Attribute::MustProgress}))
3289 return false;
3290
3291 bool IsKnown;
3292 if (AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown))
3293 return IsKnown || !KnownOnly;
3294 return false;
3295 }
3296
3297 /// See AbstractAttribute::updateImpl(...).
3298 ChangeStatus updateImpl(Attributor &A) override {
3299 if (isImpliedByMustprogressAndReadonly(A, /* KnownOnly */ false))
3300 return ChangeStatus::UNCHANGED;
3301
3302 auto CheckForWillReturn = [&](Instruction &I) {
3303 IRPosition IPos = IRPosition::callsite_function(cast<CallBase>(I));
3304 bool IsKnown;
3305 if (AA::hasAssumedIRAttr<Attribute::WillReturn>(
3306 A, this, IPos, DepClassTy::REQUIRED, IsKnown)) {
3307 if (IsKnown)
3308 return true;
3309 } else {
3310 return false;
3311 }
3312 bool IsKnownNoRecurse;
3313 return AA::hasAssumedIRAttr<Attribute::NoRecurse>(
3314 A, this, IPos, DepClassTy::REQUIRED, IsKnownNoRecurse);
3315 };
3316
3317 bool UsedAssumedInformation = false;
3318 if (!A.checkForAllCallLikeInstructions(CheckForWillReturn, *this,
3319 UsedAssumedInformation))
3320 return indicatePessimisticFixpoint();
3321
3322 return ChangeStatus::UNCHANGED;
3323 }
3324
3325 /// See AbstractAttribute::getAsStr()
3326 const std::string getAsStr(Attributor *A) const override {
3327 return getAssumed() ? "willreturn" : "may-noreturn";
3328 }
3329};
3330
3331struct AAWillReturnFunction final : AAWillReturnImpl {
3332 AAWillReturnFunction(const IRPosition &IRP, Attributor &A)
3333 : AAWillReturnImpl(IRP, A) {}
3334
3335 /// See AbstractAttribute::initialize(...).
3336 void initialize(Attributor &A) override {
3337 AAWillReturnImpl::initialize(A);
3338
3339 Function *F = getAnchorScope();
3340 assert(F && "Did expect an anchor function");
3341 if (F->isDeclaration() || mayContainUnboundedCycle(*F, A))
3342 indicatePessimisticFixpoint();
3343 }
3344
3345 /// See AbstractAttribute::trackStatistics()
3346 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(willreturn) }
3347};
3348
3349/// WillReturn attribute deduction for a call sites.
3350struct AAWillReturnCallSite final
3351 : AACalleeToCallSite<AAWillReturn, AAWillReturnImpl> {
3352 AAWillReturnCallSite(const IRPosition &IRP, Attributor &A)
3353 : AACalleeToCallSite<AAWillReturn, AAWillReturnImpl>(IRP, A) {}
3354
3355 /// See AbstractAttribute::updateImpl(...).
3356 ChangeStatus updateImpl(Attributor &A) override {
3357 if (isImpliedByMustprogressAndReadonly(A, /* KnownOnly */ false))
3358 return ChangeStatus::UNCHANGED;
3359
3360 return AACalleeToCallSite::updateImpl(A);
3361 }
3362
3363 /// See AbstractAttribute::trackStatistics()
3364 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(willreturn); }
3365};
3366} // namespace
3367
3368/// -------------------AAIntraFnReachability Attribute--------------------------
3369
3370/// All information associated with a reachability query. This boilerplate code
3371/// is used by both AAIntraFnReachability and AAInterFnReachability, with
3372/// different \p ToTy values.
3373template <typename ToTy> struct ReachabilityQueryInfo {
3374 enum class Reachable {
3375 No,
3376 Yes,
3377 };
3378
3379 /// Start here,
3380 const Instruction *From = nullptr;
3381 /// reach this place,
3382 const ToTy *To = nullptr;
3383 /// without going through any of these instructions,
3384 const AA::InstExclusionSetTy *ExclusionSet = nullptr;
3385 /// and remember if it worked:
3386 Reachable Result = Reachable::No;
3387
3388 /// Precomputed hash for this RQI.
3389 unsigned Hash = 0;
3390
3391 unsigned computeHashValue() const {
3392 assert(Hash == 0 && "Computed hash twice!");
3395 return const_cast<ReachabilityQueryInfo<ToTy> *>(this)->Hash =
3396 detail::combineHashValue(PairDMI ::getHashValue({From, To}),
3397 InstSetDMI::getHashValue(ExclusionSet));
3398 }
3399
3401 : From(From), To(To) {}
3402
3403 /// Constructor replacement to ensure unique and stable sets are used for the
3404 /// cache.
3406 const AA::InstExclusionSetTy *ES, bool MakeUnique)
3407 : From(&From), To(&To), ExclusionSet(ES) {
3408
3409 if (!ES || ES->empty()) {
3410 ExclusionSet = nullptr;
3411 } else if (MakeUnique) {
3412 ExclusionSet = A.getInfoCache().getOrCreateUniqueBlockExecutionSet(ES);
3413 }
3414 }
3415
3417 : From(RQI.From), To(RQI.To), ExclusionSet(RQI.ExclusionSet) {}
3418};
3419
3420namespace llvm {
3421template <typename ToTy> struct DenseMapInfo<ReachabilityQueryInfo<ToTy> *> {
3424
3427
3428 static inline ReachabilityQueryInfo<ToTy> *getEmptyKey() { return &EmptyKey; }
3430 return &TombstoneKey;
3431 }
3432 static unsigned getHashValue(const ReachabilityQueryInfo<ToTy> *RQI) {
3433 return RQI->Hash ? RQI->Hash : RQI->computeHashValue();
3434 }
3437 if (!PairDMI::isEqual({LHS->From, LHS->To}, {RHS->From, RHS->To}))
3438 return false;
3439 return InstSetDMI::isEqual(LHS->ExclusionSet, RHS->ExclusionSet);
3440 }
3441};
3442
3443#define DefineKeys(ToTy) \
3444 template <> \
3445 ReachabilityQueryInfo<ToTy> \
3446 DenseMapInfo<ReachabilityQueryInfo<ToTy> *>::EmptyKey = \
3447 ReachabilityQueryInfo<ToTy>( \
3448 DenseMapInfo<const Instruction *>::getEmptyKey(), \
3449 DenseMapInfo<const ToTy *>::getEmptyKey()); \
3450 template <> \
3451 ReachabilityQueryInfo<ToTy> \
3452 DenseMapInfo<ReachabilityQueryInfo<ToTy> *>::TombstoneKey = \
3453 ReachabilityQueryInfo<ToTy>( \
3454 DenseMapInfo<const Instruction *>::getTombstoneKey(), \
3455 DenseMapInfo<const ToTy *>::getTombstoneKey());
3456
3458#undef DefineKeys
3459
3460} // namespace llvm
3461
3462namespace {
3463
3464template <typename BaseTy, typename ToTy>
3465struct CachedReachabilityAA : public BaseTy {
3466 using RQITy = ReachabilityQueryInfo<ToTy>;
3467
3468 CachedReachabilityAA(const IRPosition &IRP, Attributor &A) : BaseTy(IRP, A) {}
3469
3470 /// See AbstractAttribute::isQueryAA.
3471 bool isQueryAA() const override { return true; }
3472
3473 /// See AbstractAttribute::updateImpl(...).
3474 ChangeStatus updateImpl(Attributor &A) override {
3475 ChangeStatus Changed = ChangeStatus::UNCHANGED;
3476 for (unsigned u = 0, e = QueryVector.size(); u < e; ++u) {
3477 RQITy *RQI = QueryVector[u];
3478 if (RQI->Result == RQITy::Reachable::No &&
3479 isReachableImpl(A, *RQI, /*IsTemporaryRQI=*/false))
3480 Changed = ChangeStatus::CHANGED;
3481 }
3482 return Changed;
3483 }
3484
3485 virtual bool isReachableImpl(Attributor &A, RQITy &RQI,
3486 bool IsTemporaryRQI) = 0;
3487
3488 bool rememberResult(Attributor &A, typename RQITy::Reachable Result,
3489 RQITy &RQI, bool UsedExclusionSet, bool IsTemporaryRQI) {
3490 RQI.Result = Result;
3491
3492 // Remove the temporary RQI from the cache.
3493 if (IsTemporaryRQI)
3494 QueryCache.erase(&RQI);
3495
3496 // Insert a plain RQI (w/o exclusion set) if that makes sense. Two options:
3497 // 1) If it is reachable, it doesn't matter if we have an exclusion set for
3498 // this query. 2) We did not use the exclusion set, potentially because
3499 // there is none.
3500 if (Result == RQITy::Reachable::Yes || !UsedExclusionSet) {
3501 RQITy PlainRQI(RQI.From, RQI.To);
3502 if (!QueryCache.count(&PlainRQI)) {
3503 RQITy *RQIPtr = new (A.Allocator) RQITy(RQI.From, RQI.To);
3504 RQIPtr->Result = Result;
3505 QueryVector.push_back(RQIPtr);
3506 QueryCache.insert(RQIPtr);
3507 }
3508 }
3509
3510 // Check if we need to insert a new permanent RQI with the exclusion set.
3511 if (IsTemporaryRQI && Result != RQITy::Reachable::Yes && UsedExclusionSet) {
3512 assert((!RQI.ExclusionSet || !RQI.ExclusionSet->empty()) &&
3513 "Did not expect empty set!");
3514 RQITy *RQIPtr = new (A.Allocator)
3515 RQITy(A, *RQI.From, *RQI.To, RQI.ExclusionSet, true);
3516 assert(RQIPtr->Result == RQITy::Reachable::No && "Already reachable?");
3517 RQIPtr->Result = Result;
3518 assert(!QueryCache.count(RQIPtr));
3519 QueryVector.push_back(RQIPtr);
3520 QueryCache.insert(RQIPtr);
3521 }
3522
3523 if (Result == RQITy::Reachable::No && IsTemporaryRQI)
3524 A.registerForUpdate(*this);
3525 return Result == RQITy::Reachable::Yes;
3526 }
3527
3528 const std::string getAsStr(Attributor *A) const override {
3529 // TODO: Return the number of reachable queries.
3530 return "#queries(" + std::to_string(QueryVector.size()) + ")";
3531 }
3532
3533 bool checkQueryCache(Attributor &A, RQITy &StackRQI,
3534 typename RQITy::Reachable &Result) {
3535 if (!this->getState().isValidState()) {
3536 Result = RQITy::Reachable::Yes;
3537 return true;
3538 }
3539
3540 // If we have an exclusion set we might be able to find our answer by
3541 // ignoring it first.
3542 if (StackRQI.ExclusionSet) {
3543 RQITy PlainRQI(StackRQI.From, StackRQI.To);
3544 auto It = QueryCache.find(&PlainRQI);
3545 if (It != QueryCache.end() && (*It)->Result == RQITy::Reachable::No) {
3546 Result = RQITy::Reachable::No;
3547 return true;
3548 }
3549 }
3550
3551 auto It = QueryCache.find(&StackRQI);
3552 if (It != QueryCache.end()) {
3553 Result = (*It)->Result;
3554 return true;
3555 }
3556
3557 // Insert a temporary for recursive queries. We will replace it with a
3558 // permanent entry later.
3559 QueryCache.insert(&StackRQI);
3560 return false;
3561 }
3562
3563private:
3564 SmallVector<RQITy *> QueryVector;
3565 DenseSet<RQITy *> QueryCache;
3566};
3567
3568struct AAIntraFnReachabilityFunction final
3569 : public CachedReachabilityAA<AAIntraFnReachability, Instruction> {
3570 using Base = CachedReachabilityAA<AAIntraFnReachability, Instruction>;
3571 AAIntraFnReachabilityFunction(const IRPosition &IRP, Attributor &A)
3572 : Base(IRP, A) {
3573 DT = A.getInfoCache().getAnalysisResultForFunction<DominatorTreeAnalysis>(
3574 *IRP.getAssociatedFunction());
3575 }
3576
3577 bool isAssumedReachable(
3578 Attributor &A, const Instruction &From, const Instruction &To,
3579 const AA::InstExclusionSetTy *ExclusionSet) const override {
3580 auto *NonConstThis = const_cast<AAIntraFnReachabilityFunction *>(this);
3581 if (&From == &To)
3582 return true;
3583
3584 RQITy StackRQI(A, From, To, ExclusionSet, false);
3585 typename RQITy::Reachable Result;
3586 if (!NonConstThis->checkQueryCache(A, StackRQI, Result))
3587 return NonConstThis->isReachableImpl(A, StackRQI,
3588 /*IsTemporaryRQI=*/true);
3589 return Result == RQITy::Reachable::Yes;
3590 }
3591
3592 ChangeStatus updateImpl(Attributor &A) override {
3593 // We only depend on liveness. DeadEdges is all we care about, check if any
3594 // of them changed.
3595 auto *LivenessAA =
3596 A.getAAFor<AAIsDead>(*this, getIRPosition(), DepClassTy::OPTIONAL);
3597 if (LivenessAA &&
3598 llvm::all_of(DeadEdges,
3599 [&](const auto &DeadEdge) {
3600 return LivenessAA->isEdgeDead(DeadEdge.first,
3601 DeadEdge.second);
3602 }) &&
3603 llvm::all_of(DeadBlocks, [&](const BasicBlock *BB) {
3604 return LivenessAA->isAssumedDead(BB);
3605 })) {
3606 return ChangeStatus::UNCHANGED;
3607 }
3608 DeadEdges.clear();
3609 DeadBlocks.clear();
3610 return Base::updateImpl(A);
3611 }
3612
3613 bool isReachableImpl(Attributor &A, RQITy &RQI,
3614 bool IsTemporaryRQI) override {
3615 const Instruction *Origin = RQI.From;
3616 bool UsedExclusionSet = false;
3617
3618 auto WillReachInBlock = [&](const Instruction &From, const Instruction &To,
3619 const AA::InstExclusionSetTy *ExclusionSet) {
3620 const Instruction *IP = &From;
3621 while (IP && IP != &To) {
3622 if (ExclusionSet && IP != Origin && ExclusionSet->count(IP)) {
3623 UsedExclusionSet = true;
3624 break;
3625 }
3626 IP = IP->getNextNode();
3627 }
3628 return IP == &To;
3629 };
3630
3631 const BasicBlock *FromBB = RQI.From->getParent();
3632 const BasicBlock *ToBB = RQI.To->getParent();
3633 assert(FromBB->getParent() == ToBB->getParent() &&
3634 "Not an intra-procedural query!");
3635
3636 // Check intra-block reachability, however, other reaching paths are still
3637 // possible.
3638 if (FromBB == ToBB &&
3639 WillReachInBlock(*RQI.From, *RQI.To, RQI.ExclusionSet))
3640 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
3641 IsTemporaryRQI);
3642
3643 // Check if reaching the ToBB block is sufficient or if even that would not
3644 // ensure reaching the target. In the latter case we are done.
3645 if (!WillReachInBlock(ToBB->front(), *RQI.To, RQI.ExclusionSet))
3646 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
3647 IsTemporaryRQI);
3648
3649 const Function *Fn = FromBB->getParent();
3651 if (RQI.ExclusionSet)
3652 for (auto *I : *RQI.ExclusionSet)
3653 if (I->getFunction() == Fn)
3654 ExclusionBlocks.insert(I->getParent());
3655
3656 // Check if we make it out of the FromBB block at all.
3657 if (ExclusionBlocks.count(FromBB) &&
3658 !WillReachInBlock(*RQI.From, *FromBB->getTerminator(),
3659 RQI.ExclusionSet))
3660 return rememberResult(A, RQITy::Reachable::No, RQI, true, IsTemporaryRQI);
3661
3662 auto *LivenessAA =
3663 A.getAAFor<AAIsDead>(*this, getIRPosition(), DepClassTy::OPTIONAL);
3664 if (LivenessAA && LivenessAA->isAssumedDead(ToBB)) {
3665 DeadBlocks.insert(ToBB);
3666 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
3667 IsTemporaryRQI);
3668 }
3669
3672 Worklist.push_back(FromBB);
3673
3675 while (!Worklist.empty()) {
3676 const BasicBlock *BB = Worklist.pop_back_val();
3677 if (!Visited.insert(BB).second)
3678 continue;
3679 for (const BasicBlock *SuccBB : successors(BB)) {
3680 if (LivenessAA && LivenessAA->isEdgeDead(BB, SuccBB)) {
3681 LocalDeadEdges.insert({BB, SuccBB});
3682 continue;
3683 }
3684 // We checked before if we just need to reach the ToBB block.
3685 if (SuccBB == ToBB)
3686 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
3687 IsTemporaryRQI);
3688 if (DT && ExclusionBlocks.empty() && DT->dominates(BB, ToBB))
3689 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
3690 IsTemporaryRQI);
3691
3692 if (ExclusionBlocks.count(SuccBB)) {
3693 UsedExclusionSet = true;
3694 continue;
3695 }
3696 Worklist.push_back(SuccBB);
3697 }
3698 }
3699
3700 DeadEdges.insert(LocalDeadEdges.begin(), LocalDeadEdges.end());
3701 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
3702 IsTemporaryRQI);
3703 }
3704
3705 /// See AbstractAttribute::trackStatistics()
3706 void trackStatistics() const override {}
3707
3708private:
3709 // Set of assumed dead blocks we used in the last query. If any changes we
3710 // update the state.
3712
3713 // Set of assumed dead edges we used in the last query. If any changes we
3714 // update the state.
3716
3717 /// The dominator tree of the function to short-circuit reasoning.
3718 const DominatorTree *DT = nullptr;
3719};
3720} // namespace
3721
3722/// ------------------------ NoAlias Argument Attribute ------------------------
3723
3725 Attribute::AttrKind ImpliedAttributeKind,
3726 bool IgnoreSubsumingPositions) {
3727 assert(ImpliedAttributeKind == Attribute::NoAlias &&
3728 "Unexpected attribute kind");
3729 Value *Val = &IRP.getAssociatedValue();
3730 if (IRP.getPositionKind() != IRP_CALL_SITE_ARGUMENT) {
3731 if (isa<AllocaInst>(Val))
3732 return true;
3733 } else {
3734 IgnoreSubsumingPositions = true;
3735 }
3736
3737 if (isa<UndefValue>(Val))
3738 return true;
3739
3740 if (isa<ConstantPointerNull>(Val) &&
3743 return true;
3744
3745 if (A.hasAttr(IRP, {Attribute::ByVal, Attribute::NoAlias},
3746 IgnoreSubsumingPositions, Attribute::NoAlias))
3747 return true;
3748
3749 return false;
3750}
3751
3752namespace {
3753struct AANoAliasImpl : AANoAlias {
3754 AANoAliasImpl(const IRPosition &IRP, Attributor &A) : AANoAlias(IRP, A) {
3755 assert(getAssociatedType()->isPointerTy() &&
3756 "Noalias is a pointer attribute");
3757 }
3758
3759 const std::string getAsStr(Attributor *A) const override {
3760 return getAssumed() ? "noalias" : "may-alias";
3761 }
3762};
3763
3764/// NoAlias attribute for a floating value.
3765struct AANoAliasFloating final : AANoAliasImpl {
3766 AANoAliasFloating(const IRPosition &IRP, Attributor &A)
3767 : AANoAliasImpl(IRP, A) {}
3768
3769 /// See AbstractAttribute::updateImpl(...).
3770 ChangeStatus updateImpl(Attributor &A) override {
3771 // TODO: Implement this.
3772 return indicatePessimisticFixpoint();
3773 }
3774
3775 /// See AbstractAttribute::trackStatistics()
3776 void trackStatistics() const override {
3778 }
3779};
3780
3781/// NoAlias attribute for an argument.
3782struct AANoAliasArgument final
3783 : AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl> {
3784 using Base = AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl>;
3785 AANoAliasArgument(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {}
3786
3787 /// See AbstractAttribute::update(...).
3788 ChangeStatus updateImpl(Attributor &A) override {
3789 // We have to make sure no-alias on the argument does not break
3790 // synchronization when this is a callback argument, see also [1] below.
3791 // If synchronization cannot be affected, we delegate to the base updateImpl
3792 // function, otherwise we give up for now.
3793
3794 // If the function is no-sync, no-alias cannot break synchronization.
3795 bool IsKnownNoSycn;
3796 if (AA::hasAssumedIRAttr<Attribute::NoSync>(
3797 A, this, IRPosition::function_scope(getIRPosition()),
3798 DepClassTy::OPTIONAL, IsKnownNoSycn))
3799 return Base::updateImpl(A);
3800
3801 // If the argument is read-only, no-alias cannot break synchronization.
3802 bool IsKnown;
3803 if (AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown))
3804 return Base::updateImpl(A);
3805
3806 // If the argument is never passed through callbacks, no-alias cannot break
3807 // synchronization.
3808 bool UsedAssumedInformation = false;
3809 if (A.checkForAllCallSites(
3810 [](AbstractCallSite ACS) { return !ACS.isCallbackCall(); }, *this,
3811 true, UsedAssumedInformation))
3812 return Base::updateImpl(A);
3813
3814 // TODO: add no-alias but make sure it doesn't break synchronization by
3815 // introducing fake uses. See:
3816 // [1] Compiler Optimizations for OpenMP, J. Doerfert and H. Finkel,
3817 // International Workshop on OpenMP 2018,
3818 // http://compilers.cs.uni-saarland.de/people/doerfert/par_opt18.pdf
3819
3820 return indicatePessimisticFixpoint();
3821 }
3822
3823 /// See AbstractAttribute::trackStatistics()
3824 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noalias) }
3825};
3826
3827struct AANoAliasCallSiteArgument final : AANoAliasImpl {
3828 AANoAliasCallSiteArgument(const IRPosition &IRP, Attributor &A)
3829 : AANoAliasImpl(IRP, A) {}
3830
3831 /// Determine if the underlying value may alias with the call site argument
3832 /// \p OtherArgNo of \p ICS (= the underlying call site).
3833 bool mayAliasWithArgument(Attributor &A, AAResults *&AAR,
3834 const AAMemoryBehavior &MemBehaviorAA,
3835 const CallBase &CB, unsigned OtherArgNo) {
3836 // We do not need to worry about aliasing with the underlying IRP.
3837 if (this->getCalleeArgNo() == (int)OtherArgNo)
3838 return false;
3839
3840 // If it is not a pointer or pointer vector we do not alias.
3841 const Value *ArgOp = CB.getArgOperand(OtherArgNo);
3842 if (!ArgOp->getType()->isPtrOrPtrVectorTy())
3843 return false;
3844
3845 auto *CBArgMemBehaviorAA = A.getAAFor<AAMemoryBehavior>(
3846 *this, IRPosition::callsite_argument(CB, OtherArgNo), DepClassTy::NONE);
3847
3848 // If the argument is readnone, there is no read-write aliasing.
3849 if (CBArgMemBehaviorAA && CBArgMemBehaviorAA->isAssumedReadNone()) {
3850 A.recordDependence(*CBArgMemBehaviorAA, *this, DepClassTy::OPTIONAL);
3851 return false;
3852 }
3853
3854 // If the argument is readonly and the underlying value is readonly, there
3855 // is no read-write aliasing.
3856 bool IsReadOnly = MemBehaviorAA.isAssumedReadOnly();
3857 if (CBArgMemBehaviorAA && CBArgMemBehaviorAA->isAssumedReadOnly() &&
3858 IsReadOnly) {
3859 A.recordDependence(MemBehaviorAA, *this, DepClassTy::OPTIONAL);
3860 A.recordDependence(*CBArgMemBehaviorAA, *this, DepClassTy::OPTIONAL);
3861 return false;
3862 }
3863
3864 // We have to utilize actual alias analysis queries so we need the object.
3865 if (!AAR)
3866 AAR = A.getInfoCache().getAnalysisResultForFunction<AAManager>(
3867 *getAnchorScope());
3868
3869 // Try to rule it out at the call site.
3870 bool IsAliasing = !AAR || !AAR->isNoAlias(&getAssociatedValue(), ArgOp);
3871 LLVM_DEBUG(dbgs() << "[NoAliasCSArg] Check alias between "
3872 "callsite arguments: "
3873 << getAssociatedValue() << " " << *ArgOp << " => "
3874 << (IsAliasing ? "" : "no-") << "alias \n");
3875
3876 return IsAliasing;
3877 }
3878
3879 bool isKnownNoAliasDueToNoAliasPreservation(
3880 Attributor &A, AAResults *&AAR, const AAMemoryBehavior &MemBehaviorAA) {
3881 // We can deduce "noalias" if the following conditions hold.
3882 // (i) Associated value is assumed to be noalias in the definition.
3883 // (ii) Associated value is assumed to be no-capture in all the uses
3884 // possibly executed before this callsite.
3885 // (iii) There is no other pointer argument which could alias with the
3886 // value.
3887
3888 auto IsDereferenceableOrNull = [&](Value *O, const DataLayout &DL) {
3889 const auto *DerefAA = A.getAAFor<AADereferenceable>(
3890 *this, IRPosition::value(*O), DepClassTy::OPTIONAL);
3891 return DerefAA ? DerefAA->getAssumedDereferenceableBytes() : 0;
3892 };
3893
3894 const IRPosition &VIRP = IRPosition::value(getAssociatedValue());
3895 const Function *ScopeFn = VIRP.getAnchorScope();
3896 // Check whether the value is captured in the scope using AANoCapture.
3897 // Look at CFG and check only uses possibly executed before this
3898 // callsite.
3899 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
3900 Instruction *UserI = cast<Instruction>(U.getUser());
3901
3902 // If UserI is the curr instruction and there is a single potential use of
3903 // the value in UserI we allow the use.
3904 // TODO: We should inspect the operands and allow those that cannot alias
3905 // with the value.
3906 if (UserI == getCtxI() && UserI->getNumOperands() == 1)
3907 return true;
3908
3909 if (ScopeFn) {
3910 if (auto *CB = dyn_cast<CallBase>(UserI)) {
3911 if (CB->isArgOperand(&U)) {
3912
3913 unsigned ArgNo = CB->getArgOperandNo(&U);
3914
3915 bool IsKnownNoCapture;
3916 if (AA::hasAssumedIRAttr<Attribute::NoCapture>(
3917 A, this, IRPosition::callsite_argument(*CB, ArgNo),
3918 DepClassTy::OPTIONAL, IsKnownNoCapture))
3919 return true;
3920 }
3921 }
3922
3924 A, *UserI, *getCtxI(), *this, /* ExclusionSet */ nullptr,
3925 [ScopeFn](const Function &Fn) { return &Fn != ScopeFn; }))
3926 return true;
3927 }
3928
3929 // TODO: We should track the capturing uses in AANoCapture but the problem
3930 // is CGSCC runs. For those we would need to "allow" AANoCapture for
3931 // a value in the module slice.
3932 switch (DetermineUseCaptureKind(U, IsDereferenceableOrNull)) {
3933 case UseCaptureKind::NO_CAPTURE:
3934 return true;
3935 case UseCaptureKind::MAY_CAPTURE:
3936 LLVM_DEBUG(dbgs() << "[AANoAliasCSArg] Unknown user: " << *UserI
3937 << "\n");
3938 return false;
3939 case UseCaptureKind::PASSTHROUGH:
3940 Follow = true;
3941 return true;
3942 }
3943 llvm_unreachable("unknown UseCaptureKind");
3944 };
3945
3946 bool IsKnownNoCapture;
3947 const AANoCapture *NoCaptureAA = nullptr;
3948 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::NoCapture>(
3949 A, this, VIRP, DepClassTy::NONE, IsKnownNoCapture, false, &NoCaptureAA);
3950 if (!IsAssumedNoCapture &&
3951 (!NoCaptureAA || !NoCaptureAA->isAssumedNoCaptureMaybeReturned())) {
3952 if (!A.checkForAllUses(UsePred, *this, getAssociatedValue())) {
3953 LLVM_DEBUG(
3954 dbgs() << "[AANoAliasCSArg] " << getAssociatedValue()
3955 << " cannot be noalias as it is potentially captured\n");
3956 return false;
3957 }
3958 }
3959 if (NoCaptureAA)
3960 A.recordDependence(*NoCaptureAA, *this, DepClassTy::OPTIONAL);
3961
3962 // Check there is no other pointer argument which could alias with the
3963 // value passed at this call site.
3964 // TODO: AbstractCallSite
3965 const auto &CB = cast<CallBase>(getAnchorValue());
3966 for (unsigned OtherArgNo = 0; OtherArgNo < CB.arg_size(); OtherArgNo++)
3967 if (mayAliasWithArgument(A, AAR, MemBehaviorAA, CB, OtherArgNo))
3968 return false;
3969
3970 return true;
3971 }
3972
3973 /// See AbstractAttribute::updateImpl(...).
3974 ChangeStatus updateImpl(Attributor &A) override {
3975 // If the argument is readnone we are done as there are no accesses via the
3976 // argument.
3977 auto *MemBehaviorAA =
3978 A.getAAFor<AAMemoryBehavior>(*this, getIRPosition(), DepClassTy::NONE);
3979 if (MemBehaviorAA && MemBehaviorAA->isAssumedReadNone()) {
3980 A.recordDependence(*MemBehaviorAA, *this, DepClassTy::OPTIONAL);
3981 return ChangeStatus::UNCHANGED;
3982 }
3983
3984 bool IsKnownNoAlias;
3985 const IRPosition &VIRP = IRPosition::value(getAssociatedValue());
3986 if (!AA::hasAssumedIRAttr<Attribute::NoAlias>(
3987 A, this, VIRP, DepClassTy::REQUIRED, IsKnownNoAlias)) {
3988 LLVM_DEBUG(dbgs() << "[AANoAlias] " << getAssociatedValue()
3989 << " is not no-alias at the definition\n");
3990 return indicatePessimisticFixpoint();
3991 }
3992
3993 AAResults *AAR = nullptr;
3994 if (MemBehaviorAA &&
3995 isKnownNoAliasDueToNoAliasPreservation(A, AAR, *MemBehaviorAA)) {
3996 LLVM_DEBUG(
3997 dbgs() << "[AANoAlias] No-Alias deduced via no-alias preservation\n");
3998 return ChangeStatus::UNCHANGED;
3999 }
4000
4001 return indicatePessimisticFixpoint();
4002 }
4003
4004 /// See AbstractAttribute::trackStatistics()
4005 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(noalias) }
4006};
4007
4008/// NoAlias attribute for function return value.
4009struct AANoAliasReturned final : AANoAliasImpl {
4010 AANoAliasReturned(const IRPosition &IRP, Attributor &A)
4011 : AANoAliasImpl(IRP, A) {}
4012
4013 /// See AbstractAttribute::updateImpl(...).
4014 ChangeStatus updateImpl(Attributor &A) override {
4015
4016 auto CheckReturnValue = [&](Value &RV) -> bool {
4017 if (Constant *C = dyn_cast<Constant>(&RV))
4018 if (C->isNullValue() || isa<UndefValue>(C))
4019 return true;
4020
4021 /// For now, we can only deduce noalias if we have call sites.
4022 /// FIXME: add more support.
4023 if (!isa<CallBase>(&RV))
4024 return false;
4025
4026 const IRPosition &RVPos = IRPosition::value(RV);
4027 bool IsKnownNoAlias;
4028 if (!AA::hasAssumedIRAttr<Attribute::NoAlias>(
4029 A, this, RVPos, DepClassTy::REQUIRED, IsKnownNoAlias))
4030 return false;
4031
4032 bool IsKnownNoCapture;
4033 const AANoCapture *NoCaptureAA = nullptr;
4034 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::NoCapture>(
4035 A, this, RVPos, DepClassTy::REQUIRED, IsKnownNoCapture, false,
4036 &NoCaptureAA);
4037 return IsAssumedNoCapture ||
4038 (NoCaptureAA && NoCaptureAA->isAssumedNoCaptureMaybeReturned());
4039 };
4040
4041 if (!A.checkForAllReturnedValues(CheckReturnValue, *this))
4042 return indicatePessimisticFixpoint();
4043
4044 return ChangeStatus::UNCHANGED;
4045 }
4046
4047 /// See AbstractAttribute::trackStatistics()
4048 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noalias) }
4049};
4050
4051/// NoAlias attribute deduction for a call site return value.
4052struct AANoAliasCallSiteReturned final
4053 : AACalleeToCallSite<AANoAlias, AANoAliasImpl> {
4054 AANoAliasCallSiteReturned(const IRPosition &IRP, Attributor &A)
4055 : AACalleeToCallSite<AANoAlias, AANoAliasImpl>(IRP, A) {}
4056
4057 /// See AbstractAttribute::trackStatistics()
4058 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(noalias); }
4059};
4060} // namespace
4061
4062/// -------------------AAIsDead Function Attribute-----------------------
4063
4064namespace {
4065struct AAIsDeadValueImpl : public AAIsDead {
4066 AAIsDeadValueImpl(const IRPosition &IRP, Attributor &A) : AAIsDead(IRP, A) {}
4067
4068 /// See AAIsDead::isAssumedDead().
4069 bool isAssumedDead() const override { return isAssumed(IS_DEAD); }
4070
4071 /// See AAIsDead::isKnownDead().
4072 bool isKnownDead() const override { return isKnown(IS_DEAD); }
4073
4074 /// See AAIsDead::isAssumedDead(BasicBlock *).
4075 bool isAssumedDead(const BasicBlock *BB) const override { return false; }
4076
4077 /// See AAIsDead::isKnownDead(BasicBlock *).
4078 bool isKnownDead(const BasicBlock *BB) const override { return false; }
4079
4080 /// See AAIsDead::isAssumedDead(Instruction *I).
4081 bool isAssumedDead(const Instruction *I) const override {
4082 return I == getCtxI() && isAssumedDead();
4083 }
4084
4085 /// See AAIsDead::isKnownDead(Instruction *I).
4086 bool isKnownDead(const Instruction *I) const override {
4087 return isAssumedDead(I) && isKnownDead();
4088 }
4089
4090 /// See AbstractAttribute::getAsStr().
4091 const std::string getAsStr(Attributor *A) const override {
4092 return isAssumedDead() ? "assumed-dead" : "assumed-live";
4093 }
4094
4095 /// Check if all uses are assumed dead.
4096 bool areAllUsesAssumedDead(Attributor &A, Value &V) {
4097 // Callers might not check the type, void has no uses.
4098 if (V.getType()->isVoidTy() || V.use_empty())
4099 return true;
4100
4101 // If we replace a value with a constant there are no uses left afterwards.
4102 if (!isa<Constant>(V)) {
4103 if (auto *I = dyn_cast<Instruction>(&V))
4104 if (!A.isRunOn(*I->getFunction()))
4105 return false;
4106 bool UsedAssumedInformation = false;
4107 std::optional<Constant *> C =
4108 A.getAssumedConstant(V, *this, UsedAssumedInformation);
4109 if (!C || *C)
4110 return true;
4111 }
4112
4113 auto UsePred = [&](const Use &U, bool &Follow) { return false; };
4114 // Explicitly set the dependence class to required because we want a long
4115 // chain of N dependent instructions to be considered live as soon as one is
4116 // without going through N update cycles. This is not required for
4117 // correctness.
4118 return A.checkForAllUses(UsePred, *this, V, /* CheckBBLivenessOnly */ false,
4119 DepClassTy::REQUIRED,
4120 /* IgnoreDroppableUses */ false);
4121 }
4122
4123 /// Determine if \p I is assumed to be side-effect free.
4124 bool isAssumedSideEffectFree(Attributor &A, Instruction *I) {
4126 return true;
4127
4128 auto *CB = dyn_cast<CallBase>(I);
4129 if (!CB || isa<IntrinsicInst>(CB))
4130 return false;
4131
4132 const IRPosition &CallIRP = IRPosition::callsite_function(*CB);
4133
4134 bool IsKnownNoUnwind;
4135 if (!AA::hasAssumedIRAttr<Attribute::NoUnwind>(
4136 A, this, CallIRP, DepClassTy::OPTIONAL, IsKnownNoUnwind))
4137 return false;
4138
4139 bool IsKnown;
4140 return AA::isAssumedReadOnly(A, CallIRP, *this, IsKnown);
4141 }
4142};
4143
4144struct AAIsDeadFloating : public AAIsDeadValueImpl {
4145 AAIsDeadFloating(const IRPosition &IRP, Attributor &A)
4146 : AAIsDeadValueImpl(IRP, A) {}
4147
4148 /// See AbstractAttribute::initialize(...).
4149 void initialize(Attributor &A) override {
4150 AAIsDeadValueImpl::initialize(A);
4151
4152 if (isa<UndefValue>(getAssociatedValue())) {
4153 indicatePessimisticFixpoint();
4154 return;
4155 }
4156
4157 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
4158 if (!isAssumedSideEffectFree(A, I)) {
4159 if (!isa_and_nonnull<StoreInst>(I) && !isa_and_nonnull<FenceInst>(I))
4160 indicatePessimisticFixpoint();
4161 else
4162 removeAssumedBits(HAS_NO_EFFECT);
4163 }
4164 }
4165
4166 bool isDeadFence(Attributor &A, FenceInst &FI) {
4167 const auto *ExecDomainAA = A.lookupAAFor<AAExecutionDomain>(
4168 IRPosition::function(*FI.getFunction()), *this, DepClassTy::NONE);
4169 if (!ExecDomainAA || !ExecDomainAA->isNoOpFence(FI))
4170 return false;
4171 A.recordDependence(*ExecDomainAA, *this, DepClassTy::OPTIONAL);
4172 return true;
4173 }
4174
4175 bool isDeadStore(Attributor &A, StoreInst &SI,
4176 SmallSetVector<Instruction *, 8> *AssumeOnlyInst = nullptr) {
4177 // Lang ref now states volatile store is not UB/dead, let's skip them.
4178 if (SI.isVolatile())
4179 return false;
4180
4181 // If we are collecting assumes to be deleted we are in the manifest stage.
4182 // It's problematic to collect the potential copies again now so we use the
4183 // cached ones.
4184 bool UsedAssumedInformation = false;
4185 if (!AssumeOnlyInst) {
4186 PotentialCopies.clear();
4187 if (!AA::getPotentialCopiesOfStoredValue(A, SI, PotentialCopies, *this,
4188 UsedAssumedInformation)) {
4189 LLVM_DEBUG(
4190 dbgs()
4191 << "[AAIsDead] Could not determine potential copies of store!\n");
4192 return false;
4193 }
4194 }
4195 LLVM_DEBUG(dbgs() << "[AAIsDead] Store has " << PotentialCopies.size()
4196 << " potential copies.\n");
4197
4198 InformationCache &InfoCache = A.getInfoCache();
4199 return llvm::all_of(PotentialCopies, [&](Value *V) {
4200 if (A.isAssumedDead(IRPosition::value(*V), this, nullptr,
4201 UsedAssumedInformation))
4202 return true;
4203 if (auto *LI = dyn_cast<LoadInst>(V)) {
4204 if (llvm::all_of(LI->uses(), [&](const Use &U) {
4205 auto &UserI = cast<Instruction>(*U.getUser());
4206 if (InfoCache.isOnlyUsedByAssume(UserI)) {
4207 if (AssumeOnlyInst)
4208 AssumeOnlyInst->insert(&UserI);
4209 return true;
4210 }
4211 return A.isAssumedDead(U, this, nullptr, UsedAssumedInformation);
4212 })) {
4213 return true;
4214 }
4215 }
4216 LLVM_DEBUG(dbgs() << "[AAIsDead] Potential copy " << *V
4217 << " is assumed live!\n");
4218 return false;
4219 });
4220 }
4221
4222 /// See AbstractAttribute::getAsStr().
4223 const std::string getAsStr(Attributor *A) const override {
4224 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
4225 if (isa_and_nonnull<StoreInst>(I))
4226 if (isValidState())
4227 return "assumed-dead-store";
4228 if (isa_and_nonnull<FenceInst>(I))
4229 if (isValidState())
4230 return "assumed-dead-fence";
4231 return AAIsDeadValueImpl::getAsStr(A);
4232 }
4233
4234 /// See AbstractAttribute::updateImpl(...).
4235 ChangeStatus updateImpl(Attributor &A) override {
4236 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
4237 if (auto *SI = dyn_cast_or_null<StoreInst>(I)) {
4238 if (!isDeadStore(A, *SI))
4239 return indicatePessimisticFixpoint();
4240 } else if (auto *FI = dyn_cast_or_null<FenceInst>(I)) {
4241 if (!isDeadFence(A, *FI))
4242 return indicatePessimisticFixpoint();
4243 } else {
4244 if (!isAssumedSideEffectFree(A, I))
4245 return indicatePessimisticFixpoint();
4246 if (!areAllUsesAssumedDead(A, getAssociatedValue()))
4247 return indicatePessimisticFixpoint();
4248 }
4250 }
4251
4252 bool isRemovableStore() const override {
4253 return isAssumed(IS_REMOVABLE) && isa<StoreInst>(&getAssociatedValue());
4254 }
4255
4256 /// See AbstractAttribute::manifest(...).
4257 ChangeStatus manifest(Attributor &A) override {
4258 Value &V = getAssociatedValue();
4259 if (auto *I = dyn_cast<Instruction>(&V)) {
4260 // If we get here we basically know the users are all dead. We check if
4261 // isAssumedSideEffectFree returns true here again because it might not be
4262 // the case and only the users are dead but the instruction (=call) is
4263 // still needed.
4264 if (auto *SI = dyn_cast<StoreInst>(I)) {
4265 SmallSetVector<Instruction *, 8> AssumeOnlyInst;
4266 bool IsDead = isDeadStore(A, *SI, &AssumeOnlyInst);
4267 (void)IsDead;
4268 assert(IsDead && "Store was assumed to be dead!");
4269 A.deleteAfterManifest(*I);
4270 for (size_t i = 0; i < AssumeOnlyInst.size(); ++i) {
4271 Instruction *AOI = AssumeOnlyInst[i];
4272 for (auto *Usr : AOI->users())
4273 AssumeOnlyInst.insert(cast<Instruction>(Usr));
4274 A.deleteAfterManifest(*AOI);
4275 }
4276 return ChangeStatus::CHANGED;
4277 }
4278 if (auto *FI = dyn_cast<FenceInst>(I)) {
4279 assert(isDeadFence(A, *FI));
4280 A.deleteAfterManifest(*FI);
4281 return ChangeStatus::CHANGED;
4282 }
4283 if (isAssumedSideEffectFree(A, I) && !isa<InvokeInst>(I)) {
4284 A.deleteAfterManifest(*I);
4285 return ChangeStatus::CHANGED;
4286 }
4287 }
4289 }
4290
4291 /// See AbstractAttribute::trackStatistics()
4292 void trackStatistics() const override {
4294 }
4295
4296private:
4297 // The potential copies of a dead store, used for deletion during manifest.
4298 SmallSetVector<Value *, 4> PotentialCopies;
4299};
4300
4301struct AAIsDeadArgument : public AAIsDeadFloating {
4302 AAIsDeadArgument(const IRPosition &IRP, Attributor &A)
4303 : AAIsDeadFloating(IRP, A) {}
4304
4305 /// See AbstractAttribute::manifest(...).
4306 ChangeStatus manifest(Attributor &A) override {
4307 Argument &Arg = *getAssociatedArgument();
4308 if (A.isValidFunctionSignatureRewrite(Arg, /* ReplacementTypes */ {}))
4309 if (A.registerFunctionSignatureRewrite(
4310 Arg, /* ReplacementTypes */ {},
4313 return ChangeStatus::CHANGED;
4314 }
4315 return ChangeStatus::UNCHANGED;
4316 }
4317
4318 /// See AbstractAttribute::trackStatistics()
4319 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(IsDead) }
4320};
4321
4322struct AAIsDeadCallSiteArgument : public AAIsDeadValueImpl {
4323 AAIsDeadCallSiteArgument(const IRPosition &IRP, Attributor &A)
4324 : AAIsDeadValueImpl(IRP, A) {}
4325
4326 /// See AbstractAttribute::initialize(...).
4327 void initialize(Attributor &A) override {
4328 AAIsDeadValueImpl::initialize(A);
4329 if (isa<UndefValue>(getAssociatedValue()))
4330 indicatePessimisticFixpoint();
4331 }
4332
4333 /// See AbstractAttribute::updateImpl(...).
4334 ChangeStatus updateImpl(Attributor &A) override {
4335 // TODO: Once we have call site specific value information we can provide
4336 // call site specific liveness information and then it makes
4337 // sense to specialize attributes for call sites arguments instead of
4338 // redirecting requests to the callee argument.
4339 Argument *Arg = getAssociatedArgument();
4340 if (!Arg)
4341 return indicatePessimisticFixpoint();
4342 const IRPosition &ArgPos = IRPosition::argument(*Arg);
4343 auto *ArgAA = A.getAAFor<AAIsDead>(*this, ArgPos, DepClassTy::REQUIRED);
4344 if (!ArgAA)
4345 return indicatePessimisticFixpoint();
4346 return clampStateAndIndicateChange(getState(), ArgAA->getState());
4347 }
4348
4349 /// See AbstractAttribute::manifest(...).
4350 ChangeStatus manifest(Attributor &A) override {
4351 CallBase &CB = cast<CallBase>(getAnchorValue());
4352 Use &U = CB.getArgOperandUse(getCallSiteArgNo());
4353 assert(!isa<UndefValue>(U.get()) &&
4354 "Expected undef values to be filtered out!");
4355 UndefValue &UV = *UndefValue::get(U->getType());
4356 if (A.changeUseAfterManifest(U, UV))
4357 return ChangeStatus::CHANGED;
4358 return ChangeStatus::UNCHANGED;
4359 }
4360
4361 /// See AbstractAttribute::trackStatistics()
4362 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(IsDead) }
4363};
4364
4365struct AAIsDeadCallSiteReturned : public AAIsDeadFloating {
4366 AAIsDeadCallSiteReturned(const IRPosition &IRP, Attributor &A)
4367 : AAIsDeadFloating(IRP, A) {}
4368
4369 /// See AAIsDead::isAssumedDead().
4370 bool isAssumedDead() const override {
4371 return AAIsDeadFloating::isAssumedDead() && IsAssumedSideEffectFree;
4372 }
4373
4374 /// See AbstractAttribute::initialize(...).
4375 void initialize(Attributor &A) override {
4376 AAIsDeadFloating::initialize(A);
4377 if (isa<UndefValue>(getAssociatedValue())) {
4378 indicatePessimisticFixpoint();
4379 return;
4380 }
4381
4382 // We track this separately as a secondary state.
4383 IsAssumedSideEffectFree = isAssumedSideEffectFree(A, getCtxI());
4384 }
4385
4386 /// See AbstractAttribute::updateImpl(...).
4387 ChangeStatus updateImpl(Attributor &A) override {
4388 ChangeStatus Changed = ChangeStatus::UNCHANGED;
4389 if (IsAssumedSideEffectFree && !isAssumedSideEffectFree(A, getCtxI())) {
4390 IsAssumedSideEffectFree = false;
4391 Changed = ChangeStatus::CHANGED;
4392 }
4393 if (!areAllUsesAssumedDead(A, getAssociatedValue()))
4394 return indicatePessimisticFixpoint();
4395 return Changed;
4396 }
4397
4398 /// See AbstractAttribute::trackStatistics()
4399 void trackStatistics() const override {
4400 if (IsAssumedSideEffectFree)
4402 else
4403 STATS_DECLTRACK_CSRET_ATTR(UnusedResult)
4404 }
4405
4406 /// See AbstractAttribute::getAsStr().
4407 const std::string getAsStr(Attributor *A) const override {
4408 return isAssumedDead()
4409 ? "assumed-dead"
4410 : (getAssumed() ? "assumed-dead-users" : "assumed-live");
4411 }
4412
4413private:
4414 bool IsAssumedSideEffectFree = true;
4415};
4416
4417struct AAIsDeadReturned : public AAIsDeadValueImpl {
4418 AAIsDeadReturned(const IRPosition &IRP, Attributor &A)
4419 : AAIsDeadValueImpl(IRP, A) {}
4420
4421 /// See AbstractAttribute::updateImpl(...).
4422 ChangeStatus updateImpl(Attributor &A) override {
4423
4424 bool UsedAssumedInformation = false;
4425 A.checkForAllInstructions([](Instruction &) { return true; }, *this,
4426 {Instruction::Ret}, UsedAssumedInformation);
4427
4428 auto PredForCallSite = [&](AbstractCallSite ACS) {
4429 if (ACS.isCallbackCall() || !ACS.getInstruction())
4430 return false;
4431 return areAllUsesAssumedDead(A, *ACS.getInstruction());
4432 };
4433
4434 if (!A.checkForAllCallSites(PredForCallSite, *this, true,
4435 UsedAssumedInformation))
4436 return indicatePessimisticFixpoint();
4437
4438 return ChangeStatus::UNCHANGED;
4439 }
4440
4441 /// See AbstractAttribute::manifest(...).
4442 ChangeStatus manifest(Attributor &A) override {
4443 // TODO: Rewrite the signature to return void?
4444 bool AnyChange = false;
4445 UndefValue &UV = *UndefValue::get(getAssociatedFunction()->getReturnType());
4446 auto RetInstPred = [&](Instruction &I) {
4447 ReturnInst &RI = cast<ReturnInst>(I);
4448 if (!isa<UndefValue>(RI.getReturnValue()))
4449 AnyChange |= A.changeUseAfterManifest(RI.getOperandUse(0), UV);
4450 return true;
4451 };
4452 bool UsedAssumedInformation = false;
4453 A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret},
4454 UsedAssumedInformation);
4455 return AnyChange ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
4456 }
4457
4458 /// See AbstractAttribute::trackStatistics()
4459 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(IsDead) }
4460};
4461
4462struct AAIsDeadFunction : public AAIsDead {
4463 AAIsDeadFunction(const IRPosition &IRP, Attributor &A) : AAIsDead(IRP, A) {}
4464
4465 /// See AbstractAttribute::initialize(...).
4466 void initialize(Attributor &A) override {
4467 Function *F = getAnchorScope();
4468 assert(F && "Did expect an anchor function");
4469 if (!isAssumedDeadInternalFunction(A)) {
4470 ToBeExploredFrom.insert(&F->getEntryBlock().front());
4471 assumeLive(A, F->getEntryBlock());
4472 }
4473 }
4474
4475 bool isAssumedDeadInternalFunction(Attributor &A) {
4476 if (!getAnchorScope()->hasLocalLinkage())
4477 return false;
4478 bool UsedAssumedInformation = false;
4479 return A.checkForAllCallSites([](AbstractCallSite) { return false; }, *this,
4480 true, UsedAssumedInformation);
4481 }
4482
4483 /// See AbstractAttribute::getAsStr().
4484 const std::string getAsStr(Attributor *A) const override {
4485 return "Live[#BB " + std::to_string(AssumedLiveBlocks.size()) + "/" +
4486 std::to_string(getAnchorScope()->size()) + "][#TBEP " +
4487 std::to_string(ToBeExploredFrom.size()) + "][#KDE " +
4488 std::to_string(KnownDeadEnds.size()) + "]";
4489 }
4490
4491 /// See AbstractAttribute::manifest(...).
4492 ChangeStatus manifest(Attributor &A) override {
4493 assert(getState().isValidState() &&
4494 "Attempted to manifest an invalid state!");
4495
4496 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
4497 Function &F = *getAnchorScope();
4498
4499 if (AssumedLiveBlocks.empty()) {
4500 A.deleteAfterManifest(F);
4501 return ChangeStatus::CHANGED;
4502 }
4503
4504 // Flag to determine if we can change an invoke to a call assuming the
4505 // callee is nounwind. This is not possible if the personality of the
4506 // function allows to catch asynchronous exceptions.
4507 bool Invoke2CallAllowed = !mayCatchAsynchronousExceptions(F);
4508
4509 KnownDeadEnds.set_union(ToBeExploredFrom);
4510 for (const Instruction *DeadEndI : KnownDeadEnds) {
4511 auto *CB = dyn_cast<CallBase>(DeadEndI);
4512 if (!CB)
4513 continue;
4514 bool IsKnownNoReturn;
4515 bool MayReturn = !AA::hasAssumedIRAttr<Attribute::NoReturn>(
4516 A, this, IRPosition::callsite_function(*CB), DepClassTy::OPTIONAL,
4517 IsKnownNoReturn);
4518 if (MayReturn && (!Invoke2CallAllowed || !isa<InvokeInst>(CB)))
4519 continue;
4520
4521 if (auto *II = dyn_cast<InvokeInst>(DeadEndI))
4522 A.registerInvokeWithDeadSuccessor(const_cast<InvokeInst &>(*II));
4523 else
4524 A.changeToUnreachableAfterManifest(
4525 const_cast<Instruction *>(DeadEndI->getNextNode()));
4526 HasChanged = ChangeStatus::CHANGED;
4527 }
4528
4529 STATS_DECL(AAIsDead, BasicBlock, "Number of dead basic blocks deleted.");
4530 for (BasicBlock &BB : F)
4531 if (!AssumedLiveBlocks.count(&BB)) {
4532 A.deleteAfterManifest(BB);
4534 HasChanged = ChangeStatus::CHANGED;
4535 }
4536
4537 return HasChanged;
4538 }
4539
4540 /// See AbstractAttribute::updateImpl(...).
4541 ChangeStatus updateImpl(Attributor &A) override;
4542
4543 bool isEdgeDead(const BasicBlock *From, const BasicBlock *To) const override {
4544 assert(From->getParent() == getAnchorScope() &&
4545 To->getParent() == getAnchorScope() &&
4546 "Used AAIsDead of the wrong function");
4547 return isValidState() && !AssumedLiveEdges.count(std::make_pair(From, To));
4548 }
4549
4550 /// See AbstractAttribute::trackStatistics()
4551 void trackStatistics() const override {}
4552
4553 /// Returns true if the function is assumed dead.
4554 bool isAssumedDead() const override { return false; }
4555
4556 /// See AAIsDead::isKnownDead().
4557 bool isKnownDead() const override { return false; }
4558
4559 /// See AAIsDead::isAssumedDead(BasicBlock *).
4560 bool isAssumedDead(const BasicBlock *BB) const override {
4561 assert(BB->getParent() == getAnchorScope() &&
4562 "BB must be in the same anchor scope function.");
4563
4564 if (!getAssumed())
4565 return false;
4566 return !AssumedLiveBlocks.count(BB);
4567 }
4568
4569 /// See AAIsDead::isKnownDead(BasicBlock *).
4570 bool isKnownDead(const BasicBlock *BB) const override {
4571 return getKnown() && isAssumedDead(BB);
4572 }
4573
4574 /// See AAIsDead::isAssumed(Instruction *I).
4575 bool isAssumedDead(const Instruction *I) const override {
4576 assert(I->getParent()->getParent() == getAnchorScope() &&
4577 "Instruction must be in the same anchor scope function.");
4578
4579 if (!getAssumed())
4580 return false;
4581
4582 // If it is not in AssumedLiveBlocks then it for sure dead.
4583 // Otherwise, it can still be after noreturn call in a live block.
4584 if (!AssumedLiveBlocks.count(I->getParent()))
4585 return true;
4586
4587 // If it is not after a liveness barrier it is live.
4588 const Instruction *PrevI = I->getPrevNode();
4589 while (PrevI) {
4590 if (KnownDeadEnds.count(PrevI) || ToBeExploredFrom.count(PrevI))
4591 return true;
4592 PrevI = PrevI->getPrevNode();
4593 }
4594 return false;
4595 }
4596
4597 /// See AAIsDead::isKnownDead(Instruction *I).
4598 bool isKnownDead(const Instruction *I) const override {
4599 return getKnown() && isAssumedDead(I);
4600 }
4601
4602 /// Assume \p BB is (partially) live now and indicate to the Attributor \p A
4603 /// that internal function called from \p BB should now be looked at.
4604 bool assumeLive(Attributor &A, const BasicBlock &BB) {
4605 if (!AssumedLiveBlocks.insert(&BB).second)
4606 return false;
4607
4608 // We assume that all of BB is (probably) live now and if there are calls to
4609 // internal functions we will assume that those are now live as well. This
4610 // is a performance optimization for blocks with calls to a lot of internal
4611 // functions. It can however cause dead functions to be treated as live.
4612 for (const Instruction &I : BB)
4613 if (const auto *CB = dyn_cast<CallBase>(&I))
4614 if (auto *F = dyn_cast_if_present<Function>(CB->getCalledOperand()))
4615 if (F->hasLocalLinkage())
4616 A.markLiveInternalFunction(*F);
4617 return true;
4618 }
4619
4620 /// Collection of instructions that need to be explored again, e.g., we
4621 /// did assume they do not transfer control to (one of their) successors.
4623
4624 /// Collection of instructions that are known to not transfer control.
4626
4627 /// Collection of all assumed live edges
4629
4630 /// Collection of all assumed live BasicBlocks.
4631 DenseSet<const BasicBlock *> AssumedLiveBlocks;
4632};
4633
4634static bool
4635identifyAliveSuccessors(Attributor &A, const CallBase &CB,
4637 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4638 const IRPosition &IPos = IRPosition::callsite_function(CB);
4639
4640 bool IsKnownNoReturn;
4641 if (AA::hasAssumedIRAttr<Attribute::NoReturn>(
4642 A, &AA, IPos, DepClassTy::OPTIONAL, IsKnownNoReturn))
4643 return !IsKnownNoReturn;
4644 if (CB.isTerminator())
4645 AliveSuccessors.push_back(&CB.getSuccessor(0)->front());
4646 else
4647 AliveSuccessors.push_back(CB.getNextNode());
4648 return false;
4649}
4650
4651static bool
4652identifyAliveSuccessors(Attributor &A, const InvokeInst &II,
4654 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4655 bool UsedAssumedInformation =
4656 identifyAliveSuccessors(A, cast<CallBase>(II), AA, AliveSuccessors);
4657
4658 // First, determine if we can change an invoke to a call assuming the
4659 // callee is nounwind. This is not possible if the personality of the
4660 // function allows to catch asynchronous exceptions.
4661 if (AAIsDeadFunction::mayCatchAsynchronousExceptions(*II.getFunction())) {
4662 AliveSuccessors.push_back(&II.getUnwindDest()->front());
4663 } else {
4665
4666 bool IsKnownNoUnwind;
4667 if (AA::hasAssumedIRAttr<Attribute::NoUnwind>(
4668 A, &AA, IPos, DepClassTy::OPTIONAL, IsKnownNoUnwind)) {
4669 UsedAssumedInformation |= !IsKnownNoUnwind;
4670 } else {
4671 AliveSuccessors.push_back(&II.getUnwindDest()->front());
4672 }
4673 }
4674 return UsedAssumedInformation;
4675}
4676
4677static bool
4678identifyAliveSuccessors(Attributor &A, const BranchInst &BI,
4680 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4681 bool UsedAssumedInformation = false;
4682 if (BI.getNumSuccessors() == 1) {
4683 AliveSuccessors.push_back(&BI.getSuccessor(0)->front());
4684 } else {
4685 std::optional<Constant *> C =
4686 A.getAssumedConstant(*BI.getCondition(), AA, UsedAssumedInformation);
4687 if (!C || isa_and_nonnull<UndefValue>(*C)) {
4688 // No value yet, assume both edges are dead.
4689 } else if (isa_and_nonnull<ConstantInt>(*C)) {
4690 const BasicBlock *SuccBB =
4691 BI.getSuccessor(1 - cast<ConstantInt>(*C)->getValue().getZExtValue());
4692 AliveSuccessors.push_back(&SuccBB->front());
4693 } else {
4694 AliveSuccessors.push_back(&BI.getSuccessor(0)->front());
4695 AliveSuccessors.push_back(&BI.getSuccessor(1)->front());
4696 UsedAssumedInformation = false;
4697 }
4698 }
4699 return UsedAssumedInformation;
4700}
4701
4702static bool
4703identifyAliveSuccessors(Attributor &A, const SwitchInst &SI,
4705 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4706 bool UsedAssumedInformation = false;
4708 if (!A.getAssumedSimplifiedValues(IRPosition::value(*SI.getCondition()), &AA,
4709 Values, AA::AnyScope,
4710 UsedAssumedInformation)) {
4711 // Something went wrong, assume all successors are live.
4712 for (const BasicBlock *SuccBB : successors(SI.getParent()))
4713 AliveSuccessors.push_back(&SuccBB->front());
4714 return false;
4715 }
4716
4717 if (Values.empty() ||
4718 (Values.size() == 1 &&
4719 isa_and_nonnull<UndefValue>(Values.front().getValue()))) {
4720 // No valid value yet, assume all edges are dead.
4721 return UsedAssumedInformation;
4722 }
4723
4724 Type &Ty = *SI.getCondition()->getType();
4726 auto CheckForConstantInt = [&](Value *V) {
4727 if (auto *CI = dyn_cast_if_present<ConstantInt>(AA::getWithType(*V, Ty))) {
4728 Constants.insert(CI);
4729 return true;
4730 }
4731 return false;
4732 };
4733
4734 if (!all_of(Values, [&](AA::ValueAndContext &VAC) {
4735 return CheckForConstantInt(VAC.getValue());
4736 })) {
4737 for (const BasicBlock *SuccBB : successors(SI.getParent()))
4738 AliveSuccessors.push_back(&SuccBB->front());
4739 return UsedAssumedInformation;
4740 }
4741
4742 unsigned MatchedCases = 0;
4743 for (const auto &CaseIt : SI.cases()) {
4744 if (Constants.count(CaseIt.getCaseValue())) {
4745 ++MatchedCases;
4746 AliveSuccessors.push_back(&CaseIt.getCaseSuccessor()->front());
4747 }
4748 }
4749
4750 // If all potential values have been matched, we will not visit the default
4751 // case.
4752 if (MatchedCases < Constants.size())
4753 AliveSuccessors.push_back(&SI.getDefaultDest()->front());
4754 return UsedAssumedInformation;
4755}
4756
4757ChangeStatus AAIsDeadFunction::updateImpl(Attributor &A) {
4759
4760 if (AssumedLiveBlocks.empty()) {
4761 if (isAssumedDeadInternalFunction(A))
4763
4764 Function *F = getAnchorScope();
4765 ToBeExploredFrom.insert(&F->getEntryBlock().front());
4766 assumeLive(A, F->getEntryBlock());
4767 Change = ChangeStatus::CHANGED;
4768 }
4769
4770 LLVM_DEBUG(dbgs() << "[AAIsDead] Live [" << AssumedLiveBlocks.size() << "/"
4771 << getAnchorScope()->size() << "] BBs and "
4772 << ToBeExploredFrom.size() << " exploration points and "
4773 << KnownDeadEnds.size() << " known dead ends\n");
4774
4775 // Copy and clear the list of instructions we need to explore from. It is
4776 // refilled with instructions the next update has to look at.
4777 SmallVector<const Instruction *, 8> Worklist(ToBeExploredFrom.begin(),
4778 ToBeExploredFrom.end());
4779 decltype(ToBeExploredFrom) NewToBeExploredFrom;
4780
4782 while (!Worklist.empty()) {
4783 const Instruction *I = Worklist.pop_back_val();
4784 LLVM_DEBUG(dbgs() << "[AAIsDead] Exploration inst: " << *I << "\n");
4785
4786 // Fast forward for uninteresting instructions. We could look for UB here
4787 // though.
4788 while (!I->isTerminator() && !isa<CallBase>(I))
4789 I = I->getNextNode();
4790
4791 AliveSuccessors.clear();
4792
4793 bool UsedAssumedInformation = false;
4794 switch (I->getOpcode()) {
4795 // TODO: look for (assumed) UB to backwards propagate "deadness".
4796 default:
4797 assert(I->isTerminator() &&
4798 "Expected non-terminators to be handled already!");
4799 for (const BasicBlock *SuccBB : successors(I->getParent()))
4800 AliveSuccessors.push_back(&SuccBB->front());
4801 break;
4802 case Instruction::Call:
4803 UsedAssumedInformation = identifyAliveSuccessors(A, cast<CallInst>(*I),
4804 *this, AliveSuccessors);
4805 break;
4806 case Instruction::Invoke:
4807 UsedAssumedInformation = identifyAliveSuccessors(A, cast<InvokeInst>(*I),
4808 *this, AliveSuccessors);
4809 break;
4810 case Instruction::Br:
4811 UsedAssumedInformation = identifyAliveSuccessors(A, cast<BranchInst>(*I),
4812 *this, AliveSuccessors);
4813 break;
4814 case Instruction::Switch:
4815 UsedAssumedInformation = identifyAliveSuccessors(A, cast<SwitchInst>(*I),
4816 *this, AliveSuccessors);
4817 break;
4818 }
4819
4820 if (UsedAssumedInformation) {
4821 NewToBeExploredFrom.insert(I);
4822 } else if (AliveSuccessors.empty() ||
4823 (I->isTerminator() &&
4824 AliveSuccessors.size() < I->getNumSuccessors())) {
4825 if (KnownDeadEnds.insert(I))
4826 Change = ChangeStatus::CHANGED;
4827 }
4828
4829 LLVM_DEBUG(dbgs() << "[AAIsDead] #AliveSuccessors: "
4830 << AliveSuccessors.size() << " UsedAssumedInformation: "
4831 << UsedAssumedInformation << "\n");
4832
4833 for (const Instruction *AliveSuccessor : AliveSuccessors) {
4834 if (!I->isTerminator()) {
4835 assert(AliveSuccessors.size() == 1 &&
4836 "Non-terminator expected to have a single successor!");
4837 Worklist.push_back(AliveSuccessor);
4838 } else {
4839 // record the assumed live edge
4840 auto Edge = std::make_pair(I->getParent(), AliveSuccessor->getParent());
4841 if (AssumedLiveEdges.insert(Edge).second)
4842 Change = ChangeStatus::CHANGED;
4843 if (assumeLive(A, *AliveSuccessor->getParent()))
4844 Worklist.push_back(AliveSuccessor);
4845 }
4846 }
4847 }
4848
4849 // Check if the content of ToBeExploredFrom changed, ignore the order.
4850 if (NewToBeExploredFrom.size() != ToBeExploredFrom.size() ||
4851 llvm::any_of(NewToBeExploredFrom, [&](const Instruction *I) {
4852 return !ToBeExploredFrom.count(I);
4853 })) {
4854 Change = ChangeStatus::CHANGED;
4855 ToBeExploredFrom = std::move(NewToBeExploredFrom);
4856 }
4857
4858 // If we know everything is live there is no need to query for liveness.
4859 // Instead, indicating a pessimistic fixpoint will cause the state to be
4860 // "invalid" and all queries to be answered conservatively without lookups.
4861 // To be in this state we have to (1) finished the exploration and (3) not
4862 // discovered any non-trivial dead end and (2) not ruled unreachable code
4863 // dead.
4864 if (ToBeExploredFrom.empty() &&
4865 getAnchorScope()->size() == AssumedLiveBlocks.size() &&
4866 llvm::all_of(KnownDeadEnds, [](const Instruction *DeadEndI) {
4867 return DeadEndI->isTerminator() && DeadEndI->getNumSuccessors() == 0;
4868 }))
4869 return indicatePessimisticFixpoint();
4870 return Change;
4871}
4872
4873/// Liveness information for a call sites.
4874struct AAIsDeadCallSite final : AAIsDeadFunction {
4875 AAIsDeadCallSite(const IRPosition &IRP, Attributor &A)
4876 : AAIsDeadFunction(IRP, A) {}
4877
4878 /// See AbstractAttribute::initialize(...).
4879 void initialize(Attributor &A) override {
4880 // TODO: Once we have call site specific value information we can provide
4881 // call site specific liveness information and then it makes
4882 // sense to specialize attributes for call sites instead of
4883 // redirecting requests to the callee.
4884 llvm_unreachable("Abstract attributes for liveness are not "
4885 "supported for call sites yet!");
4886 }
4887
4888 /// See AbstractAttribute::updateImpl(...).
4889 ChangeStatus updateImpl(Attributor &A) override {
4890 return indicatePessimisticFixpoint();
4891 }
4892
4893 /// See AbstractAttribute::trackStatistics()
4894 void trackStatistics() const override {}
4895};
4896} // namespace
4897
4898/// -------------------- Dereferenceable Argument Attribute --------------------
4899
4900namespace {
4901struct AADereferenceableImpl : AADereferenceable {
4902 AADereferenceableImpl(const IRPosition &IRP, Attributor &A)
4903 : AADereferenceable(IRP, A) {}
4904 using StateType = DerefState;
4905
4906 /// See AbstractAttribute::initialize(...).
4907 void initialize(Attributor &A) override {
4908 Value &V = *getAssociatedValue().stripPointerCasts();
4910 A.getAttrs(getIRPosition(),
4911 {Attribute::Dereferenceable, Attribute::DereferenceableOrNull},
4912 Attrs, /* IgnoreSubsumingPositions */ false);
4913 for (const Attribute &Attr : Attrs)
4914 takeKnownDerefBytesMaximum(Attr.getValueAsInt());
4915
4916 // Ensure we initialize the non-null AA (if necessary).
4917 bool IsKnownNonNull;
4918 AA::hasAssumedIRAttr<Attribute::NonNull>(
4919 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNonNull);
4920
4921 bool CanBeNull, CanBeFreed;
4922 takeKnownDerefBytesMaximum(V.getPointerDereferenceableBytes(
4923 A.getDataLayout(), CanBeNull, CanBeFreed));
4924
4925 if (Instruction *CtxI = getCtxI())
4926 followUsesInMBEC(*this, A, getState(), *CtxI);
4927 }
4928
4929 /// See AbstractAttribute::getState()
4930 /// {
4931 StateType &getState() override { return *this; }
4932 const StateType &getState() const override { return *this; }
4933 /// }
4934
4935 /// Helper function for collecting accessed bytes in must-be-executed-context
4936 void addAccessedBytesForUse(Attributor &A, const Use *U, const Instruction *I,
4937 DerefState &State) {
4938 const Value *UseV = U->get();
4939 if (!UseV->getType()->isPointerTy())
4940 return;
4941
4942 std::optional<MemoryLocation> Loc = MemoryLocation::getOrNone(I);
4943 if (!Loc || Loc->Ptr != UseV || !Loc->Size.isPrecise() || I->isVolatile())
4944 return;
4945
4946 int64_t Offset;
4948 Loc->Ptr, Offset, A.getDataLayout(), /*AllowNonInbounds*/ true);
4949 if (Base && Base == &getAssociatedValue())
4950 State.addAccessedBytes(Offset, Loc->Size.getValue());
4951 }
4952
4953 /// See followUsesInMBEC
4954 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
4956 bool IsNonNull = false;
4957 bool TrackUse = false;
4958 int64_t DerefBytes = getKnownNonNullAndDerefBytesForUse(
4959 A, *this, getAssociatedValue(), U, I, IsNonNull, TrackUse);
4960 LLVM_DEBUG(dbgs() << "[AADereferenceable] Deref bytes: " << DerefBytes
4961 << " for instruction " << *I << "\n");
4962
4963 addAccessedBytesForUse(A, U, I, State);
4964 State.takeKnownDerefBytesMaximum(DerefBytes);
4965 return TrackUse;
4966 }
4967
4968 /// See AbstractAttribute::manifest(...).
4969 ChangeStatus manifest(Attributor &A) override {
4970 ChangeStatus Change = AADereferenceable::manifest(A);
4971 bool IsKnownNonNull;
4972 bool IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>(
4973 A, this, getIRPosition(), DepClassTy::NONE, IsKnownNonNull);
4974 if (IsAssumedNonNull &&
4975 A.hasAttr(getIRPosition(), Attribute::DereferenceableOrNull)) {
4976 A.removeAttrs(getIRPosition(), {Attribute::DereferenceableOrNull});
4977 return ChangeStatus::CHANGED;
4978 }
4979 return Change;
4980 }
4981
4982 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
4983 SmallVectorImpl<Attribute> &Attrs) const override {
4984 // TODO: Add *_globally support
4985 bool IsKnownNonNull;
4986 bool IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>(
4987 A, this, getIRPosition(), DepClassTy::NONE, IsKnownNonNull);
4988 if (IsAssumedNonNull)
4990 Ctx, getAssumedDereferenceableBytes()));
4991 else
4993 Ctx, getAssumedDereferenceableBytes()));
4994 }
4995
4996 /// See AbstractAttribute::getAsStr().
4997 const std::string getAsStr(Attributor *A) const override {
4998 if (!getAssumedDereferenceableBytes())
4999 return "unknown-dereferenceable";
5000 bool IsKnownNonNull;
5001 bool IsAssumedNonNull = false;
5002 if (A)
5003 IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>(
5004 *A, this, getIRPosition(), DepClassTy::NONE, IsKnownNonNull);
5005 return std::string("dereferenceable") +
5006 (IsAssumedNonNull ? "" : "_or_null") +
5007 (isAssumedGlobal() ? "_globally" : "") + "<" +
5008 std::to_string(getKnownDereferenceableBytes()) + "-" +
5009 std::to_string(getAssumedDereferenceableBytes()) + ">" +
5010 (!A ? " [non-null is unknown]" : "");
5011 }
5012};
5013
5014/// Dereferenceable attribute for a floating value.
5015struct AADereferenceableFloating : AADereferenceableImpl {
5016 AADereferenceableFloating(const IRPosition &IRP, Attributor &A)
5017 : AADereferenceableImpl(IRP, A) {}
5018
5019 /// See AbstractAttribute::updateImpl(...).
5020 ChangeStatus updateImpl(Attributor &A) override {
5021 bool Stripped;
5022 bool UsedAssumedInformation = false;
5024 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
5025 AA::AnyScope, UsedAssumedInformation)) {
5026 Values.push_back({getAssociatedValue(), getCtxI()});
5027 Stripped = false;
5028 } else {
5029 Stripped = Values.size() != 1 ||
5030 Values.front().getValue() != &getAssociatedValue();
5031 }
5032
5033 const DataLayout &DL = A.getDataLayout();
5034 DerefState T;
5035
5036 auto VisitValueCB = [&](const Value &V) -> bool {
5037 unsigned IdxWidth =
5038 DL.getIndexSizeInBits(V.getType()->getPointerAddressSpace());
5039 APInt Offset(IdxWidth, 0);
5041 A, *this, &V, DL, Offset, /* GetMinOffset */ false,
5042 /* AllowNonInbounds */ true);
5043
5044 const auto *AA = A.getAAFor<AADereferenceable>(
5045 *this, IRPosition::value(*Base), DepClassTy::REQUIRED);
5046 int64_t DerefBytes = 0;
5047 if (!AA || (!Stripped && this == AA)) {
5048 // Use IR information if we did not strip anything.
5049 // TODO: track globally.
5050 bool CanBeNull, CanBeFreed;
5051 DerefBytes =
5052 Base->getPointerDereferenceableBytes(DL, CanBeNull, CanBeFreed);
5053 T.GlobalState.indicatePessimisticFixpoint();
5054 } else {
5055 const DerefState &DS = AA->getState();
5056 DerefBytes = DS.DerefBytesState.getAssumed();
5057 T.GlobalState &= DS.GlobalState;
5058 }
5059
5060 // For now we do not try to "increase" dereferenceability due to negative
5061 // indices as we first have to come up with code to deal with loops and
5062 // for overflows of the dereferenceable bytes.
5063 int64_t OffsetSExt = Offset.getSExtValue();
5064 if (OffsetSExt < 0)
5065 OffsetSExt = 0;
5066
5067 T.takeAssumedDerefBytesMinimum(
5068 std::max(int64_t(0), DerefBytes - OffsetSExt));
5069
5070 if (this == AA) {
5071 if (!Stripped) {
5072 // If nothing was stripped IR information is all we got.
5073 T.takeKnownDerefBytesMaximum(
5074 std::max(int64_t(0), DerefBytes - OffsetSExt));
5075 T.indicatePessimisticFixpoint();
5076 } else if (OffsetSExt > 0) {
5077 // If something was stripped but there is circular reasoning we look
5078 // for the offset. If it is positive we basically decrease the
5079 // dereferenceable bytes in a circular loop now, which will simply
5080 // drive them down to the known value in a very slow way which we
5081 // can accelerate.
5082 T.indicatePessimisticFixpoint();
5083 }
5084 }
5085
5086 return T.isValidState();
5087 };
5088
5089 for (const auto &VAC : Values)
5090 if (!VisitValueCB(*VAC.getValue()))
5091 return indicatePessimisticFixpoint();
5092
5093 return clampStateAndIndicateChange(getState(), T);
5094 }
5095
5096 /// See AbstractAttribute::trackStatistics()
5097 void trackStatistics() const override {
5098 STATS_DECLTRACK_FLOATING_ATTR(dereferenceable)
5099 }
5100};
5101
5102/// Dereferenceable attribute for a return value.
5103struct AADereferenceableReturned final
5104 : AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl> {
5105 using Base =
5106 AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl>;
5107 AADereferenceableReturned(const IRPosition &IRP, Attributor &A)
5108 : Base(IRP, A) {}
5109
5110 /// See AbstractAttribute::trackStatistics()
5111 void trackStatistics() const override {
5112 STATS_DECLTRACK_FNRET_ATTR(dereferenceable)
5113 }
5114};
5115
5116/// Dereferenceable attribute for an argument
5117struct AADereferenceableArgument final
5118 : AAArgumentFromCallSiteArguments<AADereferenceable,
5119 AADereferenceableImpl> {
5120 using Base =
5121 AAArgumentFromCallSiteArguments<AADereferenceable, AADereferenceableImpl>;
5122 AADereferenceableArgument(const IRPosition &IRP, Attributor &A)
5123 : Base(IRP, A) {}
5124
5125 /// See AbstractAttribute::trackStatistics()
5126 void trackStatistics() const override {
5127 STATS_DECLTRACK_ARG_ATTR(dereferenceable)
5128 }
5129};
5130
5131/// Dereferenceable attribute for a call site argument.
5132struct AADereferenceableCallSiteArgument final : AADereferenceableFloating {
5133 AADereferenceableCallSiteArgument(const IRPosition &IRP, Attributor &A)
5134 : AADereferenceableFloating(IRP, A) {}
5135
5136 /// See AbstractAttribute::trackStatistics()
5137 void trackStatistics() const override {
5138 STATS_DECLTRACK_CSARG_ATTR(dereferenceable)
5139 }
5140};
5141
5142/// Dereferenceable attribute deduction for a call site return value.
5143struct AADereferenceableCallSiteReturned final
5144 : AACalleeToCallSite<AADereferenceable, AADereferenceableImpl> {
5145 using Base = AACalleeToCallSite<AADereferenceable, AADereferenceableImpl>;
5146 AADereferenceableCallSiteReturned(const IRPosition &IRP, Attributor &A)
5147 : Base(IRP, A) {}
5148
5149 /// See AbstractAttribute::trackStatistics()
5150 void trackStatistics() const override {
5151 STATS_DECLTRACK_CS_ATTR(dereferenceable);
5152 }
5153};
5154} // namespace
5155
5156// ------------------------ Align Argument Attribute ------------------------
5157
5158namespace {
5159static unsigned getKnownAlignForUse(Attributor &A, AAAlign &QueryingAA,
5160 Value &AssociatedValue, const Use *U,
5161 const Instruction *I, bool &TrackUse) {
5162 // We need to follow common pointer manipulation uses to the accesses they
5163 // feed into.
5164 if (isa<CastInst>(I)) {
5165 // Follow all but ptr2int casts.
5166 TrackUse = !isa<PtrToIntInst>(I);
5167 return 0;
5168 }
5169 if (auto *GEP = dyn_cast<GetElementPtrInst>(I)) {
5170 if (GEP->hasAllConstantIndices())
5171 TrackUse = true;
5172 return 0;
5173 }
5174
5175 MaybeAlign MA;
5176 if (const auto *CB = dyn_cast<CallBase>(I)) {
5177 if (CB->isBundleOperand(U) || CB->isCallee(U))
5178 return 0;
5179
5180 unsigned ArgNo = CB->getArgOperandNo(U);
5181 IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo);
5182 // As long as we only use known information there is no need to track
5183 // dependences here.
5184 auto *AlignAA = A.getAAFor<AAAlign>(QueryingAA, IRP, DepClassTy::NONE);
5185 if (AlignAA)
5186 MA = MaybeAlign(AlignAA->getKnownAlign());
5187 }
5188
5189 const DataLayout &DL = A.getDataLayout();
5190 const Value *UseV = U->get();
5191 if (auto *SI = dyn_cast<StoreInst>(I)) {
5192 if (SI->getPointerOperand() == UseV)
5193 MA = SI->getAlign();
5194 } else if (auto *LI = dyn_cast<LoadInst>(I)) {
5195 if (LI->getPointerOperand() == UseV)
5196 MA = LI->getAlign();
5197 } else if (auto *AI = dyn_cast<AtomicRMWInst>(I)) {
5198 if (AI->getPointerOperand() == UseV)
5199 MA = AI->getAlign();
5200 } else if (auto *AI = dyn_cast<AtomicCmpXchgInst>(I)) {
5201 if (AI->getPointerOperand() == UseV)
5202 MA = AI->getAlign();
5203 }
5204
5205 if (!MA || *MA <= QueryingAA.getKnownAlign())
5206 return 0;
5207
5208 unsigned Alignment = MA->value();
5209 int64_t Offset;
5210
5211 if (const Value *Base = GetPointerBaseWithConstantOffset(UseV, Offset, DL)) {
5212 if (Base == &AssociatedValue) {
5213 // BasePointerAddr + Offset = Alignment * Q for some integer Q.
5214 // So we can say that the maximum power of two which is a divisor of
5215 // gcd(Offset, Alignment) is an alignment.
5216
5217 uint32_t gcd = std::gcd(uint32_t(abs((int32_t)Offset)), Alignment);
5218 Alignment = llvm::bit_floor(gcd);
5219 }
5220 }
5221
5222 return Alignment;
5223}
5224
5225struct AAAlignImpl : AAAlign {
5226 AAAlignImpl(const IRPosition &IRP, Attributor &A) : AAAlign(IRP, A) {}
5227
5228 /// See AbstractAttribute::initialize(...).
5229 void initialize(Attributor &A) override {
5231 A.getAttrs(getIRPosition(), {Attribute::Alignment}, Attrs);
5232 for (const Attribute &Attr : Attrs)
5233 takeKnownMaximum(Attr.getValueAsInt());
5234
5235 Value &V = *getAssociatedValue().stripPointerCasts();
5236 takeKnownMaximum(V.getPointerAlignment(A.getDataLayout()).value());
5237
5238 if (Instruction *CtxI = getCtxI())
5239 followUsesInMBEC(*this, A, getState(), *CtxI);
5240 }
5241
5242 /// See AbstractAttribute::manifest(...).
5243 ChangeStatus manifest(Attributor &A) override {
5244 ChangeStatus LoadStoreChanged = ChangeStatus::UNCHANGED;
5245
5246 // Check for users that allow alignment annotations.
5247 Value &AssociatedValue = getAssociatedValue();
5248 for (const Use &U : AssociatedValue.uses()) {
5249 if (auto *SI = dyn_cast<StoreInst>(U.getUser())) {
5250 if (SI->getPointerOperand() == &AssociatedValue)
5251 if (SI->getAlign() < getAssumedAlign()) {
5252 STATS_DECLTRACK(AAAlign, Store,
5253 "Number of times alignment added to a store");
5254 SI->setAlignment(getAssumedAlign());
5255 LoadStoreChanged = ChangeStatus::CHANGED;
5256 }
5257 } else if (auto *LI = dyn_cast<LoadInst>(U.getUser())) {
5258 if (LI->getPointerOperand() == &AssociatedValue)
5259 if (LI->getAlign() < getAssumedAlign()) {
5260 LI->setAlignment(getAssumedAlign());
5262 "Number of times alignment added to a load");
5263 LoadStoreChanged = ChangeStatus::CHANGED;
5264 }
5265 }
5266 }
5267
5268 ChangeStatus Changed = AAAlign::manifest(A);
5269
5270 Align InheritAlign =
5271 getAssociatedValue().getPointerAlignment(A.getDataLayout());
5272 if (InheritAlign >= getAssumedAlign())
5273 return LoadStoreChanged;
5274 return Changed | LoadStoreChanged;
5275 }
5276
5277 // TODO: Provide a helper to determine the implied ABI alignment and check in
5278 // the existing manifest method and a new one for AAAlignImpl that value
5279 // to avoid making the alignment explicit if it did not improve.
5280
5281 /// See AbstractAttribute::getDeducedAttributes
5282 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
5283 SmallVectorImpl<Attribute> &Attrs) const override {
5284 if (getAssumedAlign() > 1)
5285 Attrs.emplace_back(
5286 Attribute::getWithAlignment(Ctx, Align(getAssumedAlign())));
5287 }
5288
5289 /// See followUsesInMBEC
5290 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
5291 AAAlign::StateType &State) {
5292 bool TrackUse = false;
5293
5294 unsigned int KnownAlign =
5295 getKnownAlignForUse(A, *this, getAssociatedValue(), U, I, TrackUse);
5296 State.takeKnownMaximum(KnownAlign);
5297
5298 return TrackUse;
5299 }
5300
5301 /// See AbstractAttribute::getAsStr().
5302 const std::string getAsStr(Attributor *A) const override {
5303 return "align<" + std::to_string(getKnownAlign().value()) + "-" +
5304 std::to_string(getAssumedAlign().value()) + ">";
5305 }
5306};
5307
5308/// Align attribute for a floating value.
5309struct AAAlignFloating : AAAlignImpl {
5310 AAAlignFloating(const IRPosition &IRP, Attributor &A) : AAAlignImpl(IRP, A) {}
5311
5312 /// See AbstractAttribute::updateImpl(...).
5313 ChangeStatus updateImpl(Attributor &A) override {
5314 const DataLayout &DL = A.getDataLayout();
5315
5316 bool Stripped;
5317 bool UsedAssumedInformation = false;
5319 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
5320 AA::AnyScope, UsedAssumedInformation)) {
5321 Values.push_back({getAssociatedValue(), getCtxI()});
5322 Stripped = false;
5323 } else {
5324 Stripped = Values.size() != 1 ||
5325 Values.front().getValue() != &getAssociatedValue();
5326 }
5327
5328 StateType T;
5329 auto VisitValueCB = [&](Value &V) -> bool {
5330 if (isa<UndefValue>(V) || isa<ConstantPointerNull>(V))
5331 return true;
5332 const auto *AA = A.getAAFor<AAAlign>(*this, IRPosition::value(V),
5333 DepClassTy::REQUIRED);
5334 if (!AA || (!Stripped && this == AA)) {
5335 int64_t Offset;
5336 unsigned Alignment = 1;
5337 if (const Value *Base =
5339 // TODO: Use AAAlign for the base too.
5340 Align PA = Base->getPointerAlignment(DL);
5341 // BasePointerAddr + Offset = Alignment * Q for some integer Q.
5342 // So we can say that the maximum power of two which is a divisor of
5343 // gcd(Offset, Alignment) is an alignment.
5344
5345 uint32_t gcd =
5346 std::gcd(uint32_t(abs((int32_t)Offset)), uint32_t(PA.value()));
5347 Alignment = llvm::bit_floor(gcd);
5348 } else {
5349 Alignment = V.getPointerAlignment(DL).value();
5350 }
5351 // Use only IR information if we did not strip anything.
5352 T.takeKnownMaximum(Alignment);
5353 T.indicatePessimisticFixpoint();
5354 } else {
5355 // Use abstract attribute information.
5356 const AAAlign::StateType &DS = AA->getState();
5357 T ^= DS;
5358 }
5359 return T.isValidState();
5360 };
5361
5362 for (const auto &VAC : Values) {
5363 if (!VisitValueCB(*VAC.getValue()))
5364 return indicatePessimisticFixpoint();
5365 }
5366
5367 // TODO: If we know we visited all incoming values, thus no are assumed
5368 // dead, we can take the known information from the state T.
5369 return clampStateAndIndicateChange(getState(), T);
5370 }
5371
5372 /// See AbstractAttribute::trackStatistics()
5373 void trackStatistics() const override { STATS_DECLTRACK_FLOATING_ATTR(align) }
5374};
5375
5376/// Align attribute for function return value.
5377struct AAAlignReturned final
5378 : AAReturnedFromReturnedValues<AAAlign, AAAlignImpl> {
5379 using Base = AAReturnedFromReturnedValues<AAAlign, AAAlignImpl>;
5380 AAAlignReturned(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {}
5381
5382 /// See AbstractAttribute::trackStatistics()
5383 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(aligned) }
5384};
5385
5386/// Align attribute for function argument.
5387struct AAAlignArgument final
5388 : AAArgumentFromCallSiteArguments<AAAlign, AAAlignImpl> {
5389 using Base = AAArgumentFromCallSiteArguments<AAAlign, AAAlignImpl>;
5390 AAAlignArgument(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {}
5391
5392 /// See AbstractAttribute::manifest(...).
5393 ChangeStatus manifest(Attributor &A) override {
5394 // If the associated argument is involved in a must-tail call we give up
5395 // because we would need to keep the argument alignments of caller and
5396 // callee in-sync. Just does not seem worth the trouble right now.
5397 if (A.getInfoCache().isInvolvedInMustTailCall(*getAssociatedArgument()))
5398 return ChangeStatus::UNCHANGED;
5399 return Base::manifest(A);
5400 }
5401
5402 /// See AbstractAttribute::trackStatistics()
5403 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(aligned) }
5404};
5405
5406struct AAAlignCallSiteArgument final : AAAlignFloating {
5407 AAAlignCallSiteArgument(const IRPosition &IRP, Attributor &A)
5408 : AAAlignFloating(IRP, A) {}
5409
5410 /// See AbstractAttribute::manifest(...).
5411 ChangeStatus manifest(Attributor &A) override {
5412 // If the associated argument is involved in a must-tail call we give up
5413 // because we would need to keep the argument alignments of caller and
5414 // callee in-sync. Just does not seem worth the trouble right now.
5415 if (Argument *Arg = getAssociatedArgument())
5416 if (A.getInfoCache().isInvolvedInMustTailCall(*Arg))
5417 return ChangeStatus::UNCHANGED;
5418 ChangeStatus Changed = AAAlignImpl::manifest(A);
5419 Align InheritAlign =
5420 getAssociatedValue().getPointerAlignment(A.getDataLayout());
5421 if (InheritAlign >= getAssumedAlign())
5422 Changed = ChangeStatus::UNCHANGED;
5423 return Changed;
5424 }
5425
5426 /// See AbstractAttribute::updateImpl(Attributor &A).
5427 ChangeStatus updateImpl(Attributor &A) override {
5428 ChangeStatus Changed = AAAlignFloating::updateImpl(A);
5429 if (Argument *Arg = getAssociatedArgument()) {
5430 // We only take known information from the argument
5431 // so we do not need to track a dependence.
5432 const auto *ArgAlignAA = A.getAAFor<AAAlign>(
5433 *this, IRPosition::argument(*Arg), DepClassTy::NONE);
5434 if (ArgAlignAA)
5435 takeKnownMaximum(ArgAlignAA->getKnownAlign().value());
5436 }
5437 return Changed;
5438 }
5439
5440 /// See AbstractAttribute::trackStatistics()
5441 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(aligned) }
5442};
5443
5444/// Align attribute deduction for a call site return value.
5445struct AAAlignCallSiteReturned final
5446 : AACalleeToCallSite<AAAlign, AAAlignImpl> {
5447 using Base = AACalleeToCallSite<AAAlign, AAAlignImpl>;
5448 AAAlignCallSiteReturned(const IRPosition &IRP, Attributor &A)
5449 : Base(IRP, A) {}
5450
5451 /// See AbstractAttribute::trackStatistics()
5452 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(align); }
5453};
5454} // namespace
5455
5456/// ------------------ Function No-Return Attribute ----------------------------
5457namespace {
5458struct AANoReturnImpl : public AANoReturn {
5459 AANoReturnImpl(const IRPosition &IRP, Attributor &A) : AANoReturn(IRP, A) {}
5460
5461 /// See AbstractAttribute::initialize(...).
5462 void initialize(Attributor &A) override {
5463 bool IsKnown;
5464 assert(!AA::hasAssumedIRAttr<Attribute::NoReturn>(
5465 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
5466 (void)IsKnown;
5467 }
5468
5469 /// See AbstractAttribute::getAsStr().
5470 const std::string getAsStr(Attributor *A) const override {
5471 return getAssumed() ? "noreturn" : "may-return";
5472 }
5473
5474 /// See AbstractAttribute::updateImpl(Attributor &A).
5475 ChangeStatus updateImpl(Attributor &A) override {
5476 auto CheckForNoReturn = [](Instruction &) { return false; };
5477 bool UsedAssumedInformation = false;
5478 if (!A.checkForAllInstructions(CheckForNoReturn, *this,
5479 {(unsigned)Instruction::Ret},
5480 UsedAssumedInformation))
5481 return indicatePessimisticFixpoint();
5482 return ChangeStatus::UNCHANGED;
5483 }
5484};
5485
5486struct AANoReturnFunction final : AANoReturnImpl {
5487 AANoReturnFunction(const IRPosition &IRP, Attributor &A)
5488 : AANoReturnImpl(IRP, A) {}
5489
5490 /// See AbstractAttribute::trackStatistics()
5491 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(noreturn) }
5492};
5493
5494/// NoReturn attribute deduction for a call sites.
5495struct AANoReturnCallSite final
5496 : AACalleeToCallSite<AANoReturn, AANoReturnImpl> {
5497 AANoReturnCallSite(const IRPosition &IRP, Attributor &A)
5498 : AACalleeToCallSite<AANoReturn, AANoReturnImpl>(IRP, A) {}
5499
5500 /// See AbstractAttribute::trackStatistics()
5501 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(noreturn); }
5502};
5503} // namespace
5504
5505/// ----------------------- Instance Info ---------------------------------
5506
5507namespace {
5508/// A class to hold the state of for no-capture attributes.
5509struct AAInstanceInfoImpl : public AAInstanceInfo {
5510 AAInstanceInfoImpl(const IRPosition &IRP, Attributor &A)
5511 : AAInstanceInfo(IRP, A) {}
5512
5513 /// See AbstractAttribute::initialize(...).
5514 void initialize(Attributor &A) override {
5515 Value &V = getAssociatedValue();
5516 if (auto *C = dyn_cast<Constant>(&V)) {
5517 if (C->isThreadDependent())
5518 indicatePessimisticFixpoint();
5519 else
5520 indicateOptimisticFixpoint();
5521 return;
5522 }
5523 if (auto *CB = dyn_cast<CallBase>(&V))
5524 if (CB->arg_size() == 0 && !CB->mayHaveSideEffects() &&
5525 !CB->mayReadFromMemory()) {
5526 indicateOptimisticFixpoint();
5527 return;
5528 }
5529 if (auto *I = dyn_cast<Instruction>(&V)) {
5530 const auto *CI =
5531 A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>(
5532 *I->getFunction());
5533 if (mayBeInCycle(CI, I, /* HeaderOnly */ false)) {
5534 indicatePessimisticFixpoint();
5535 return;
5536 }
5537 }
5538 }
5539
5540 /// See AbstractAttribute::updateImpl(...).
5541 ChangeStatus updateImpl(Attributor &A) override {
5542 ChangeStatus Changed = ChangeStatus::UNCHANGED;
5543
5544 Value &V = getAssociatedValue();
5545 const Function *Scope = nullptr;
5546 if (auto *I = dyn_cast<Instruction>(&V))
5547 Scope = I->getFunction();
5548 if (auto *A = dyn_cast<Argument>(&V)) {
5549 Scope = A->getParent();
5550 if (!Scope->hasLocalLinkage())
5551 return Changed;
5552 }
5553 if (!Scope)
5554 return indicateOptimisticFixpoint();
5555
5556 bool IsKnownNoRecurse;
5557 if (AA::hasAssumedIRAttr<Attribute::NoRecurse>(
5558 A, this, IRPosition::function(*Scope), DepClassTy::OPTIONAL,
5559 IsKnownNoRecurse))
5560 return Changed;
5561
5562 auto UsePred = [&](const Use &U, bool &Follow) {
5563 const Instruction *UserI = dyn_cast<Instruction>(U.getUser());
5564 if (!UserI || isa<GetElementPtrInst>(UserI) || isa<CastInst>(UserI) ||
5565 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) {
5566 Follow = true;
5567 return true;
5568 }
5569 if (isa<LoadInst>(UserI) || isa<CmpInst>(UserI) ||
5570 (isa<StoreInst>(UserI) &&
5571 cast<StoreInst>(UserI)->getValueOperand() != U.get()))
5572 return true;
5573 if (auto *CB = dyn_cast<CallBase>(UserI)) {
5574 // This check is not guaranteeing uniqueness but for now that we cannot
5575 // end up with two versions of \p U thinking it was one.
5576 auto *Callee = dyn_cast_if_present<Function>(CB->getCalledOperand());
5577 if (!Callee || !Callee->hasLocalLinkage())
5578 return true;
5579 if (!CB->isArgOperand(&U))
5580 return false;
5581 const auto *ArgInstanceInfoAA = A.getAAFor<AAInstanceInfo>(
5583 DepClassTy::OPTIONAL);
5584 if (!ArgInstanceInfoAA ||
5585 !ArgInstanceInfoAA->isAssumedUniqueForAnalysis())
5586 return false;
5587 // If this call base might reach the scope again we might forward the
5588 // argument back here. This is very conservative.
5590 A, *CB, *Scope, *this, /* ExclusionSet */ nullptr,
5591 [Scope](const Function &Fn) { return &Fn != Scope; }))
5592 return false;
5593 return true;
5594 }
5595 return false;
5596 };
5597
5598 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) {
5599 if (auto *SI = dyn_cast<StoreInst>(OldU.getUser())) {
5600 auto *Ptr = SI->getPointerOperand()->stripPointerCasts();
5601 if ((isa<AllocaInst>(Ptr) || isNoAliasCall(Ptr)) &&
5602 AA::isDynamicallyUnique(A, *this, *Ptr))
5603 return true;
5604 }
5605 return false;
5606 };
5607
5608 if (!A.checkForAllUses(UsePred, *this, V, /* CheckBBLivenessOnly */ true,
5609 DepClassTy::OPTIONAL,
5610 /* IgnoreDroppableUses */ true, EquivalentUseCB))
5611 return indicatePessimisticFixpoint();
5612
5613 return Changed;
5614 }
5615
5616 /// See AbstractState::getAsStr().
5617 const std::string getAsStr(Attributor *A) const override {
5618 return isAssumedUniqueForAnalysis() ? "<unique [fAa]>" : "<unknown>";
5619 }
5620
5621 /// See AbstractAttribute::trackStatistics()
5622 void trackStatistics() const override {}
5623};
5624
5625/// InstanceInfo attribute for floating values.
5626struct AAInstanceInfoFloating : AAInstanceInfoImpl {
5627 AAInstanceInfoFloating(const IRPosition &IRP, Attributor &A)
5628 : AAInstanceInfoImpl(IRP, A) {}
5629};
5630
5631/// NoCapture attribute for function arguments.
5632struct AAInstanceInfoArgument final : AAInstanceInfoFloating {
5633 AAInstanceInfoArgument(const IRPosition &IRP, Attributor &A)
5634 : AAInstanceInfoFloating(IRP, A) {}
5635};
5636
5637/// InstanceInfo attribute for call site arguments.
5638struct AAInstanceInfoCallSiteArgument final : AAInstanceInfoImpl {
5639 AAInstanceInfoCallSiteArgument(const IRPosition &IRP, Attributor &A)
5640 : AAInstanceInfoImpl(IRP, A) {}
5641
5642 /// See AbstractAttribute::updateImpl(...).
5643 ChangeStatus updateImpl(Attributor &A) override {
5644 // TODO: Once we have call site specific value information we can provide
5645 // call site specific liveness information and then it makes
5646 // sense to specialize attributes for call sites arguments instead of
5647 // redirecting requests to the callee argument.
5648 Argument *Arg = getAssociatedArgument();
5649 if (!Arg)
5650 return indicatePessimisticFixpoint();
5651 const IRPosition &ArgPos = IRPosition::argument(*Arg);
5652 auto *ArgAA =
5653 A.getAAFor<AAInstanceInfo>(*this, ArgPos, DepClassTy::REQUIRED);
5654 if (!ArgAA)
5655 return indicatePessimisticFixpoint();
5656 return clampStateAndIndicateChange(getState(), ArgAA->getState());
5657 }
5658};
5659
5660/// InstanceInfo attribute for function return value.
5661struct AAInstanceInfoReturned final : AAInstanceInfoImpl {
5662 AAInstanceInfoReturned(const IRPosition &IRP, Attributor &A)
5663 : AAInstanceInfoImpl(IRP, A) {
5664 llvm_unreachable("InstanceInfo is not applicable to function returns!");
5665 }
5666
5667 /// See AbstractAttribute::initialize(...).
5668 void initialize(Attributor &A) override {
5669 llvm_unreachable("InstanceInfo is not applicable to function returns!");
5670 }
5671
5672 /// See AbstractAttribute::updateImpl(...).
5673 ChangeStatus updateImpl(Attributor &A) override {
5674 llvm_unreachable("InstanceInfo is not applicable to function returns!");
5675 }
5676};
5677
5678/// InstanceInfo attribute deduction for a call site return value.
5679struct AAInstanceInfoCallSiteReturned final : AAInstanceInfoFloating {
5680 AAInstanceInfoCallSiteReturned(const IRPosition &IRP, Attributor &A)
5681 : AAInstanceInfoFloating(IRP, A) {}
5682};
5683} // namespace
5684
5685/// ----------------------- Variable Capturing ---------------------------------
5687 Attribute::AttrKind ImpliedAttributeKind,
5688 bool IgnoreSubsumingPositions) {
5689 assert(ImpliedAttributeKind == Attribute::NoCapture &&
5690 "Unexpected attribute kind");
5691 Value &V = IRP.getAssociatedValue();
5692 if (!IRP.isArgumentPosition())
5693 return V.use_empty();
5694
5695 // You cannot "capture" null in the default address space.
5696 //
5697 // FIXME: This should use NullPointerIsDefined to account for the function
5698 // attribute.
5699 if (isa<UndefValue>(V) || (isa<ConstantPointerNull>(V) &&
5700 V.getType()->getPointerAddressSpace() == 0)) {
5701 return true;
5702 }
5703
5704 if (A.hasAttr(IRP, {Attribute::NoCapture},
5705 /* IgnoreSubsumingPositions */ true, Attribute::NoCapture))
5706 return true;
5707
5708 if (IRP.getPositionKind() == IRP_CALL_SITE_ARGUMENT)
5709 if (Argument *Arg = IRP.getAssociatedArgument())
5710 if (A.hasAttr(IRPosition::argument(*Arg),
5711 {Attribute::NoCapture, Attribute::ByVal},
5712 /* IgnoreSubsumingPositions */ true)) {
5713 A.manifestAttrs(IRP,
5714 Attribute::get(V.getContext(), Attribute::NoCapture));
5715 return true;
5716 }
5717
5718 if (const Function *F = IRP.getAssociatedFunction()) {
5719 // Check what state the associated function can actually capture.
5721 determineFunctionCaptureCapabilities(IRP, *F, State);
5722 if (State.isKnown(NO_CAPTURE)) {
5723 A.manifestAttrs(IRP,
5724 Attribute::get(V.getContext(), Attribute::NoCapture));
5725 return true;
5726 }
5727 }
5728
5729 return false;
5730}
5731
5732/// Set the NOT_CAPTURED_IN_MEM and NOT_CAPTURED_IN_RET bits in \p Known
5733/// depending on the ability of the function associated with \p IRP to capture
5734/// state in memory and through "returning/throwing", respectively.
5736 const Function &F,
5737 BitIntegerState &State) {
5738 // TODO: Once we have memory behavior attributes we should use them here.
5739
5740 // If we know we cannot communicate or write to memory, we do not care about
5741 // ptr2int anymore.
5742 bool ReadOnly = F.onlyReadsMemory();
5743 bool NoThrow = F.doesNotThrow();
5744 bool IsVoidReturn = F.getReturnType()->isVoidTy();
5745 if (ReadOnly && NoThrow && IsVoidReturn) {
5746 State.addKnownBits(NO_CAPTURE);
5747 return;
5748 }
5749
5750 // A function cannot capture state in memory if it only reads memory, it can
5751 // however return/throw state and the state might be influenced by the
5752 // pointer value, e.g., loading from a returned pointer might reveal a bit.
5753 if (ReadOnly)
5754 State.addKnownBits(NOT_CAPTURED_IN_MEM);
5755
5756 // A function cannot communicate state back if it does not through
5757 // exceptions and doesn not return values.
5758 if (NoThrow && IsVoidReturn)
5759 State.addKnownBits(NOT_CAPTURED_IN_RET);
5760
5761 // Check existing "returned" attributes.
5762 int ArgNo = IRP.getCalleeArgNo();
5763 if (!NoThrow || ArgNo < 0 ||
5764 !F.getAttributes().hasAttrSomewhere(Attribute::Returned))
5765 return;
5766
5767 for (unsigned U = 0, E = F.arg_size(); U < E; ++U)
5768 if (F.hasParamAttribute(U, Attribute::Returned)) {
5769 if (U == unsigned(ArgNo))
5770 State.removeAssumedBits(NOT_CAPTURED_IN_RET);
5771 else if (ReadOnly)
5772 State.addKnownBits(NO_CAPTURE);
5773 else
5774 State.addKnownBits(NOT_CAPTURED_IN_RET);
5775 break;
5776 }
5777}
5778
5779namespace {
5780/// A class to hold the state of for no-capture attributes.
5781struct AANoCaptureImpl : public AANoCapture {
5782 AANoCaptureImpl(const IRPosition &IRP, Attributor &A) : AANoCapture(IRP, A) {}
5783
5784 /// See AbstractAttribute::initialize(...).
5785 void initialize(Attributor &A) override {
5786 bool IsKnown;
5787 assert(!AA::hasAssumedIRAttr<Attribute::NoCapture>(
5788 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
5789 (void)IsKnown;
5790 }
5791
5792 /// See AbstractAttribute::updateImpl(...).
5793 ChangeStatus updateImpl(Attributor &A) override;
5794
5795 /// see AbstractAttribute::isAssumedNoCaptureMaybeReturned(...).
5796 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
5797 SmallVectorImpl<Attribute> &Attrs) const override {
5798 if (!isAssumedNoCaptureMaybeReturned())
5799 return;
5800
5801 if (isArgumentPosition()) {
5802 if (isAssumedNoCapture())
5803 Attrs.emplace_back(Attribute::get(Ctx, Attribute::NoCapture));
5804 else if (ManifestInternal)
5805 Attrs.emplace_back(Attribute::get(Ctx, "no-capture-maybe-returned"));
5806 }
5807 }
5808
5809 /// See AbstractState::getAsStr().
5810 const std::string getAsStr(Attributor *A) const override {
5811 if (isKnownNoCapture())
5812 return "known not-captured";
5813 if (isAssumedNoCapture())
5814 return "assumed not-captured";
5815 if (isKnownNoCaptureMaybeReturned())
5816 return "known not-captured-maybe-returned";
5817 if (isAssumedNoCaptureMaybeReturned())
5818 return "assumed not-captured-maybe-returned";
5819 return "assumed-captured";
5820 }
5821
5822 /// Check the use \p U and update \p State accordingly. Return true if we
5823 /// should continue to update the state.
5824 bool checkUse(Attributor &A, AANoCapture::StateType &State, const Use &U,
5825 bool &Follow) {
5826 Instruction *UInst = cast<Instruction>(U.getUser());
5827 LLVM_DEBUG(dbgs() << "[AANoCapture] Check use: " << *U.get() << " in "
5828 << *UInst << "\n");
5829
5830 // Deal with ptr2int by following uses.
5831 if (isa<PtrToIntInst>(UInst)) {
5832 LLVM_DEBUG(dbgs() << " - ptr2int assume the worst!\n");
5833 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
5834 /* Return */ true);
5835 }
5836
5837 // For stores we already checked if we can follow them, if they make it
5838 // here we give up.
5839 if (isa<StoreInst>(UInst))
5840 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
5841 /* Return */ true);
5842
5843 // Explicitly catch return instructions.
5844 if (isa<ReturnInst>(UInst)) {
5845 if (UInst->getFunction() == getAnchorScope())
5846 return isCapturedIn(State, /* Memory */ false, /* Integer */ false,
5847 /* Return */ true);
5848 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
5849 /* Return */ true);
5850 }
5851
5852 // For now we only use special logic for call sites. However, the tracker
5853 // itself knows about a lot of other non-capturing cases already.
5854 auto *CB = dyn_cast<CallBase>(UInst);
5855 if (!CB || !CB->isArgOperand(&U))
5856 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
5857 /* Return */ true);
5858
5859 unsigned ArgNo = CB->getArgOperandNo(&U);
5860 const IRPosition &CSArgPos = IRPosition::callsite_argument(*CB, ArgNo);
5861 // If we have a abstract no-capture attribute for the argument we can use
5862 // it to justify a non-capture attribute here. This allows recursion!
5863 bool IsKnownNoCapture;
5864 const AANoCapture *ArgNoCaptureAA = nullptr;
5865 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::NoCapture>(
5866 A, this, CSArgPos, DepClassTy::REQUIRED, IsKnownNoCapture, false,
5867 &ArgNoCaptureAA);
5868 if (IsAssumedNoCapture)
5869 return isCapturedIn(State, /* Memory */ false, /* Integer */ false,
5870 /* Return */ false);
5871 if (ArgNoCaptureAA && ArgNoCaptureAA->isAssumedNoCaptureMaybeReturned()) {
5872 Follow = true;
5873 return isCapturedIn(State, /* Memory */ false, /* Integer */ false,
5874 /* Return */ false);
5875 }
5876
5877 // Lastly, we could not find a reason no-capture can be assumed so we don't.
5878 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
5879 /* Return */ true);
5880 }
5881
5882 /// Update \p State according to \p CapturedInMem, \p CapturedInInt, and
5883 /// \p CapturedInRet, then return true if we should continue updating the
5884 /// state.
5885 static bool isCapturedIn(AANoCapture::StateType &State, bool CapturedInMem,
5886 bool CapturedInInt, bool CapturedInRet) {
5887 LLVM_DEBUG(dbgs() << " - captures [Mem " << CapturedInMem << "|Int "
5888 << CapturedInInt << "|Ret " << CapturedInRet << "]\n");
5889 if (CapturedInMem)
5890 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_MEM);
5891 if (CapturedInInt)
5892 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_INT);
5893 if (CapturedInRet)
5894 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_RET);
5895 return State.isAssumed(AANoCapture::NO_CAPTURE_MAYBE_RETURNED);
5896 }
5897};
5898
5899ChangeStatus AANoCaptureImpl::updateImpl(Attributor &A) {
5900 const IRPosition &IRP = getIRPosition();
5901 Value *V = isArgumentPosition() ? IRP.getAssociatedArgument()
5902 : &IRP.getAssociatedValue();
5903 if (!V)
5904 return indicatePessimisticFixpoint();
5905
5906 const Function *F =
5907 isArgumentPosition() ? IRP.getAssociatedFunction() : IRP.getAnchorScope();
5908
5909 // TODO: Is the checkForAllUses below useful for constants?
5910 if (!F)
5911 return indicatePessimisticFixpoint();
5912
5914 const IRPosition &FnPos = IRPosition::function(*F);
5915
5916 // Readonly means we cannot capture through memory.
5917 bool IsKnown;
5918 if (AA::isAssumedReadOnly(A, FnPos, *this, IsKnown)) {
5919 T.addKnownBits(NOT_CAPTURED_IN_MEM);
5920 if (IsKnown)
5921 addKnownBits(NOT_CAPTURED_IN_MEM);
5922 }
5923
5924 // Make sure all returned values are different than the underlying value.
5925 // TODO: we could do this in a more sophisticated way inside
5926 // AAReturnedValues, e.g., track all values that escape through returns
5927 // directly somehow.
5928 auto CheckReturnedArgs = [&](bool &UsedAssumedInformation) {
5930 if (!A.getAssumedSimplifiedValues(IRPosition::returned(*F), this, Values,
5932 UsedAssumedInformation))
5933 return false;
5934 bool SeenConstant = false;
5935 for (const AA::ValueAndContext &VAC : Values) {
5936 if (isa<Constant>(VAC.getValue())) {
5937 if (SeenConstant)
5938 return false;
5939 SeenConstant = true;
5940 } else if (!isa<Argument>(VAC.getValue()) ||
5941 VAC.getValue() == getAssociatedArgument())
5942 return false;
5943 }
5944 return true;
5945 };
5946
5947 bool IsKnownNoUnwind;
5948 if (AA::hasAssumedIRAttr<Attribute::NoUnwind>(
5949 A, this, FnPos, DepClassTy::OPTIONAL, IsKnownNoUnwind)) {
5950 bool IsVoidTy = F->getReturnType()->isVoidTy();
5951 bool UsedAssumedInformation = false;
5952 if (IsVoidTy || CheckReturnedArgs(UsedAssumedInformation)) {
5953 T.addKnownBits(NOT_CAPTURED_IN_RET);
5954 if (T.isKnown(NOT_CAPTURED_IN_MEM))
5956 if (IsKnownNoUnwind && (IsVoidTy || !UsedAssumedInformation)) {
5957 addKnownBits(NOT_CAPTURED_IN_RET);
5958 if (isKnown(NOT_CAPTURED_IN_MEM))
5959 return indicateOptimisticFixpoint();
5960 }
5961 }
5962 }
5963
5964 auto IsDereferenceableOrNull = [&](Value *O, const DataLayout &DL) {
5965 const auto *DerefAA = A.getAAFor<AADereferenceable>(
5967 return DerefAA && DerefAA->getAssumedDereferenceableBytes();
5968 };
5969
5970 auto UseCheck = [&](const Use &U, bool &Follow) -> bool {
5971 switch (DetermineUseCaptureKind(U, IsDereferenceableOrNull)) {
5973 return true;
5975 return checkUse(A, T, U, Follow);
5977 Follow = true;
5978 return true;
5979 }
5980 llvm_unreachable("Unexpected use capture kind!");
5981 };
5982
5983 if (!A.checkForAllUses(UseCheck, *this, *V))
5984 return indicatePessimisticFixpoint();
5985
5986 AANoCapture::StateType &S = getState();
5987 auto Assumed = S.getAssumed();
5988 S.intersectAssumedBits(T.getAssumed());
5989 if (!isAssumedNoCaptureMaybeReturned())
5990 return indicatePessimisticFixpoint();
5991 return Assumed == S.getAssumed() ? ChangeStatus::UNCHANGED
5993}
5994
5995/// NoCapture attribute for function arguments.
5996struct AANoCaptureArgument final : AANoCaptureImpl {
5997 AANoCaptureArgument(const IRPosition &IRP, Attributor &A)
5998 : AANoCaptureImpl(IRP, A) {}
5999
6000 /// See AbstractAttribute::trackStatistics()
6001 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nocapture) }
6002};
6003
6004/// NoCapture attribute for call site arguments.
6005struct AANoCaptureCallSiteArgument final : AANoCaptureImpl {
6006 AANoCaptureCallSiteArgument(const IRPosition &IRP, Attributor &A)
6007 : AANoCaptureImpl(IRP, A) {}
6008
6009 /// See AbstractAttribute::updateImpl(...).
6010 ChangeStatus updateImpl(Attributor &A) override {
6011 // TODO: Once we have call site specific value information we can provide
6012 // call site specific liveness information and then it makes
6013 // sense to specialize attributes for call sites arguments instead of
6014 // redirecting requests to the callee argument.
6015 Argument *Arg = getAssociatedArgument();
6016 if (!Arg)
6017 return indicatePessimisticFixpoint();
6018 const IRPosition &ArgPos = IRPosition::argument(*Arg);
6019 bool IsKnownNoCapture;
6020 const AANoCapture *ArgAA = nullptr;
6021 if (AA::hasAssumedIRAttr<Attribute::NoCapture>(
6022 A, this, ArgPos, DepClassTy::REQUIRED, IsKnownNoCapture, false,
6023 &ArgAA))
6024 return ChangeStatus::UNCHANGED;
6025 if (!ArgAA || !ArgAA->isAssumedNoCaptureMaybeReturned())
6026 return indicatePessimisticFixpoint();
6027 return clampStateAndIndicateChange(getState(), ArgAA->getState());
6028 }
6029
6030 /// See AbstractAttribute::trackStatistics()
6031 void trackStatistics() const override{STATS_DECLTRACK_CSARG_ATTR(nocapture)};
6032};
6033
6034/// NoCapture attribute for floating values.
6035struct AANoCaptureFloating final : AANoCaptureImpl {
6036 AANoCaptureFloating(const IRPosition &IRP, Attributor &A)
6037 : AANoCaptureImpl(IRP, A) {}
6038
6039 /// See AbstractAttribute::trackStatistics()
6040 void trackStatistics() const override {
6042 }
6043};
6044
6045/// NoCapture attribute for function return value.
6046struct AANoCaptureReturned final : AANoCaptureImpl {
6047 AANoCaptureReturned(const IRPosition &IRP, Attributor &A)
6048 : AANoCaptureImpl(IRP, A) {
6049 llvm_unreachable("NoCapture is not applicable to function returns!");
6050 }
6051
6052 /// See AbstractAttribute::initialize(...).
6053 void initialize(Attributor &A) override {
6054 llvm_unreachable("NoCapture is not applicable to function returns!");
6055 }
6056
6057 /// See AbstractAttribute::updateImpl(...).
6058 ChangeStatus updateImpl(Attributor &A) override {
6059 llvm_unreachable("NoCapture is not applicable to function returns!");
6060 }
6061
6062 /// See AbstractAttribute::trackStatistics()
6063 void trackStatistics() const override {}
6064};
6065
6066/// NoCapture attribute deduction for a call site return value.
6067struct AANoCaptureCallSiteReturned final : AANoCaptureImpl {
6068 AANoCaptureCallSiteReturned(const IRPosition &IRP, Attributor &A)
6069 : AANoCaptureImpl(IRP, A) {}
6070
6071 /// See AbstractAttribute::initialize(...).
6072 void initialize(Attributor &A) override {
6073 const Function *F = getAnchorScope();
6074 // Check what state the associated function can actually capture.
6075 determineFunctionCaptureCapabilities(getIRPosition(), *F, *this);
6076 }
6077
6078 /// See AbstractAttribute::trackStatistics()
6079 void trackStatistics() const override {
6081 }
6082};
6083} // namespace
6084
6085/// ------------------ Value Simplify Attribute ----------------------------
6086
6087bool ValueSimplifyStateType::unionAssumed(std::optional<Value *> Other) {
6088 // FIXME: Add a typecast support.
6089 SimplifiedAssociatedValue = AA::combineOptionalValuesInAAValueLatice(
6090 SimplifiedAssociatedValue, Other, Ty);
6091 if (SimplifiedAssociatedValue == std::optional<Value *>(nullptr))
6092 return false;
6093
6094 LLVM_DEBUG({
6095 if (SimplifiedAssociatedValue)
6096 dbgs() << "[ValueSimplify] is assumed to be "
6097 << **SimplifiedAssociatedValue << "\n";
6098 else
6099 dbgs() << "[ValueSimplify] is assumed to be <none>\n";
6100 });
6101 return true;
6102}
6103
6104namespace {
6105struct AAValueSimplifyImpl : AAValueSimplify {
6106 AAValueSimplifyImpl(const IRPosition &IRP, Attributor &A)
6107 : AAValueSimplify(IRP, A) {}
6108
6109 /// See AbstractAttribute::initialize(...).
6110 void initialize(Attributor &A) override {
6111 if (getAssociatedValue().getType()->isVoidTy())
6112 indicatePessimisticFixpoint();
6113 if (A.hasSimplificationCallback(getIRPosition()))
6114 indicatePessimisticFixpoint();
6115 }
6116
6117 /// See AbstractAttribute::getAsStr().
6118 const std::string getAsStr(Attributor *A) const override {
6119 LLVM_DEBUG({
6120 dbgs() << "SAV: " << (bool)SimplifiedAssociatedValue << " ";
6121 if (SimplifiedAssociatedValue && *SimplifiedAssociatedValue)
6122 dbgs() << "SAV: " << **SimplifiedAssociatedValue << " ";
6123 });
6124 return isValidState() ? (isAtFixpoint() ? "simplified" : "maybe-simple")
6125 : "not-simple";
6126 }
6127
6128 /// See AbstractAttribute::trackStatistics()
6129 void trackStatistics() const override {}
6130
6131 /// See AAValueSimplify::getAssumedSimplifiedValue()
6132 std::optional<Value *>
6133 getAssumedSimplifiedValue(Attributor &A) const override {
6134 return SimplifiedAssociatedValue;
6135 }
6136
6137 /// Ensure the return value is \p V with type \p Ty, if not possible return
6138 /// nullptr. If \p Check is true we will only verify such an operation would
6139 /// suceed and return a non-nullptr value if that is the case. No IR is
6140 /// generated or modified.
6141 static Value *ensureType(Attributor &A, Value &V, Type &Ty, Instruction *CtxI,
6142 bool Check) {
6143 if (auto *TypedV = AA::getWithType(V, Ty))
6144 return TypedV;
6145 if (CtxI && V.getType()->canLosslesslyBitCastTo(&Ty))
6146 return Check ? &V
6147 : BitCastInst::CreatePointerBitCastOrAddrSpaceCast(
6148 &V, &Ty, "", CtxI->getIterator());
6149 return nullptr;
6150 }
6151
6152 /// Reproduce \p I with type \p Ty or return nullptr if that is not posisble.
6153 /// If \p Check is true we will only verify such an operation would suceed and
6154 /// return a non-nullptr value if that is the case. No IR is generated or
6155 /// modified.
6156 static Value *reproduceInst(Attributor &A,
6157 const AbstractAttribute &QueryingAA,
6158 Instruction &I, Type &Ty, Instruction *CtxI,
6159 bool Check, ValueToValueMapTy &VMap) {
6160 assert(CtxI && "Cannot reproduce an instruction without context!");
6161 if (Check && (I.mayReadFromMemory() ||
6162 !isSafeToSpeculativelyExecute(&I, CtxI, /* DT */ nullptr,
6163 /* TLI */ nullptr)))
6164 return nullptr;
6165 for (Value *Op : I.operands()) {
6166 Value *NewOp = reproduceValue(A, QueryingAA, *Op, Ty, CtxI, Check, VMap);
6167 if (!NewOp) {
6168 assert(Check && "Manifest of new value unexpectedly failed!");
6169 return nullptr;
6170 }
6171 if (!Check)
6172 VMap[Op] = NewOp;
6173 }
6174 if (Check)
6175 return &I;
6176
6177 Instruction *CloneI = I.clone();
6178 // TODO: Try to salvage debug information here.
6179 CloneI->setDebugLoc(DebugLoc());
6180 VMap[&I] = CloneI;
6181 CloneI->insertBefore(CtxI);
6182 RemapInstruction(CloneI, VMap);
6183 return CloneI;
6184 }
6185
6186 /// Reproduce \p V with type \p Ty or return nullptr if that is not posisble.
6187 /// If \p Check is true we will only verify such an operation would suceed and
6188 /// return a non-nullptr value if that is the case. No IR is generated or
6189 /// modified.
6190 static Value *reproduceValue(Attributor &A,
6191 const AbstractAttribute &QueryingAA, Value &V,
6192 Type &Ty, Instruction *CtxI, bool Check,
6193 ValueToValueMapTy &VMap) {
6194 if (const auto &NewV = VMap.lookup(&V))
6195 return NewV;
6196 bool UsedAssumedInformation = false;
6197 std::optional<Value *> SimpleV = A.getAssumedSimplified(
6198 V, QueryingAA, UsedAssumedInformation, AA::Interprocedural);
6199 if (!SimpleV.has_value())
6200 return PoisonValue::get(&Ty);
6201 Value *EffectiveV = &V;
6202 if (*SimpleV)
6203 EffectiveV = *SimpleV;
6204 if (auto *C = dyn_cast<Constant>(EffectiveV))
6205 return C;
6206 if (CtxI && AA::isValidAtPosition(AA::ValueAndContext(*EffectiveV, *CtxI),
6207 A.getInfoCache()))
6208 return ensureType(A, *EffectiveV, Ty, CtxI, Check);
6209 if (auto *I = dyn_cast<Instruction>(EffectiveV))
6210 if (Value *NewV = reproduceInst(A, QueryingAA, *I, Ty, CtxI, Check, VMap))
6211 return ensureType(A, *NewV, Ty, CtxI, Check);
6212 return nullptr;
6213 }
6214
6215 /// Return a value we can use as replacement for the associated one, or
6216 /// nullptr if we don't have one that makes sense.
6217 Value *manifestReplacementValue(Attributor &A, Instruction *CtxI) const {
6218 Value *NewV = SimplifiedAssociatedValue
6219 ? *SimplifiedAssociatedValue
6220 : UndefValue::get(getAssociatedType());
6221 if (NewV && NewV != &getAssociatedValue()) {
6222 ValueToValueMapTy VMap;
6223 // First verify we can reprduce the value with the required type at the
6224 // context location before we actually start modifying the IR.
6225 if (reproduceValue(A, *this, *NewV, *getAssociatedType(), CtxI,
6226 /* CheckOnly */ true, VMap))
6227 return reproduceValue(A, *this, *NewV, *getAssociatedType(), CtxI,
6228 /* CheckOnly */ false, VMap);
6229 }
6230 return nullptr;
6231 }
6232
6233 /// Helper function for querying AAValueSimplify and updating candidate.
6234 /// \param IRP The value position we are trying to unify with SimplifiedValue
6235 bool checkAndUpdate(Attributor &A, const AbstractAttribute &QueryingAA,
6236 const IRPosition &IRP, bool Simplify = true) {
6237 bool UsedAssumedInformation = false;
6238 std::optional<Value *> QueryingValueSimplified = &IRP.getAssociatedValue();
6239 if (Simplify)
6240 QueryingValueSimplified = A.getAssumedSimplified(
6241 IRP, QueryingAA, UsedAssumedInformation, AA::Interprocedural);
6242 return unionAssumed(QueryingValueSimplified);
6243 }
6244
6245 /// Returns a candidate is found or not
6246 template <typename AAType> bool askSimplifiedValueFor(Attributor &A) {
6247 if (!getAssociatedValue().getType()->isIntegerTy())
6248 return false;
6249
6250 // This will also pass the call base context.
6251 const auto *AA =
6252 A.getAAFor<AAType>(*this, getIRPosition(), DepClassTy::NONE);
6253 if (!AA)
6254 return false;
6255
6256 std::optional<Constant *> COpt = AA->getAssumedConstant(A);
6257
6258 if (!COpt) {
6259 SimplifiedAssociatedValue = std::nullopt;
6260 A.recordDependence(*AA, *this, DepClassTy::OPTIONAL);
6261 return true;
6262 }
6263 if (auto *C = *COpt) {
6264 SimplifiedAssociatedValue = C;
6265 A.recordDependence(*AA, *this, DepClassTy::OPTIONAL);
6266 return true;
6267 }
6268 return false;
6269 }
6270
6271 bool askSimplifiedValueForOtherAAs(Attributor &A) {
6272 if (askSimplifiedValueFor<AAValueConstantRange>(A))
6273 return true;
6274 if (askSimplifiedValueFor<AAPotentialConstantValues>(A))
6275 return true;
6276 return false;
6277 }
6278
6279 /// See AbstractAttribute::manifest(...).
6280 ChangeStatus manifest(Attributor &A) override {
6281 ChangeStatus Changed = ChangeStatus::UNCHANGED;
6282 for (auto &U : getAssociatedValue().uses()) {
6283 // Check if we need to adjust the insertion point to make sure the IR is
6284 // valid.
6285 Instruction *IP = dyn_cast<Instruction>(U.getUser());
6286 if (auto *PHI = dyn_cast_or_null<PHINode>(IP))
6287 IP = PHI->getIncomingBlock(U)->getTerminator();
6288 if (auto *NewV = manifestReplacementValue(A, IP)) {
6289 LLVM_DEBUG(dbgs() << "[ValueSimplify] " << getAssociatedValue()
6290 << " -> " << *NewV << " :: " << *this << "\n");
6291 if (A.changeUseAfterManifest(U, *NewV))
6292 Changed = ChangeStatus::CHANGED;
6293 }
6294 }
6295
6296 return Changed | AAValueSimplify::manifest(A);
6297 }
6298
6299 /// See AbstractState::indicatePessimisticFixpoint(...).
6300 ChangeStatus indicatePessimisticFixpoint() override {
6301 SimplifiedAssociatedValue = &getAssociatedValue();
6302 return AAValueSimplify::indicatePessimisticFixpoint();
6303 }
6304};
6305
6306struct AAValueSimplifyArgument final : AAValueSimplifyImpl {
6307 AAValueSimplifyArgument(const IRPosition &IRP, Attributor &A)
6308 : AAValueSimplifyImpl(IRP, A) {}
6309
6310 void initialize(Attributor &A) override {
6311 AAValueSimplifyImpl::initialize(A);
6312 if (A.hasAttr(getIRPosition(),
6313 {Attribute::InAlloca, Attribute::Preallocated,
6314 Attribute::StructRet, Attribute::Nest, Attribute::ByVal},
6315 /* IgnoreSubsumingPositions */ true))
6316 indicatePessimisticFixpoint();
6317 }
6318
6319 /// See AbstractAttribute::updateImpl(...).
6320 ChangeStatus updateImpl(Attributor &A) override {
6321 // Byval is only replacable if it is readonly otherwise we would write into
6322 // the replaced value and not the copy that byval creates implicitly.
6323 Argument *Arg = getAssociatedArgument();
6324 if (Arg->hasByValAttr()) {
6325 // TODO: We probably need to verify synchronization is not an issue, e.g.,
6326 // there is no race by not copying a constant byval.
6327 bool IsKnown;
6328 if (!AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown))
6329 return indicatePessimisticFixpoint();
6330 }
6331
6332 auto Before = SimplifiedAssociatedValue;
6333
6334 auto PredForCallSite = [&](AbstractCallSite ACS) {
6335 const IRPosition &ACSArgPos =
6336 IRPosition::callsite_argument(ACS, getCallSiteArgNo());
6337 // Check if a coresponding argument was found or if it is on not
6338 // associated (which can happen for callback calls).
6339 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
6340 return false;
6341
6342 // Simplify the argument operand explicitly and check if the result is
6343 // valid in the current scope. This avoids refering to simplified values
6344 // in other functions, e.g., we don't want to say a an argument in a
6345 // static function is actually an argument in a different function.
6346 bool UsedAssumedInformation = false;
6347 std::optional<Constant *> SimpleArgOp =
6348 A.getAssumedConstant(ACSArgPos, *this, UsedAssumedInformation);
6349 if (!SimpleArgOp)
6350 return true;
6351 if (!*SimpleArgOp)
6352 return false;
6353 if (!AA::isDynamicallyUnique(A, *this, **SimpleArgOp))
6354 return false;
6355 return unionAssumed(*SimpleArgOp);
6356 };
6357
6358 // Generate a answer specific to a call site context.
6359 bool Success;
6360 bool UsedAssumedInformation = false;
6361 if (hasCallBaseContext() &&
6362 getCallBaseContext()->getCalledOperand() == Arg->getParent())
6363 Success = PredForCallSite(
6364 AbstractCallSite(&getCallBaseContext()->getCalledOperandUse()));
6365 else
6366 Success = A.checkForAllCallSites(PredForCallSite, *this, true,
6367 UsedAssumedInformation);
6368
6369 if (!Success)
6370 if (!askSimplifiedValueForOtherAAs(A))
6371 return indicatePessimisticFixpoint();
6372
6373 // If a candidate was found in this update, return CHANGED.
6374 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED
6375 : ChangeStatus ::CHANGED;
6376 }
6377
6378 /// See AbstractAttribute::trackStatistics()
6379 void trackStatistics() const override {
6380 STATS_DECLTRACK_ARG_ATTR(value_simplify)
6381 }
6382};
6383
6384struct AAValueSimplifyReturned : AAValueSimplifyImpl {
6385 AAValueSimplifyReturned(const IRPosition &IRP, Attributor &A)
6386 : AAValueSimplifyImpl(IRP, A) {}
6387
6388 /// See AAValueSimplify::getAssumedSimplifiedValue()
6389 std::optional<Value *>
6390 getAssumedSimplifiedValue(Attributor &A) const override {
6391 if (!isValidState())
6392 return nullptr;
6393 return SimplifiedAssociatedValue;
6394 }
6395
6396 /// See AbstractAttribute::updateImpl(...).
6397 ChangeStatus updateImpl(Attributor &A) override {
6398 auto Before = SimplifiedAssociatedValue;
6399
6400 auto ReturnInstCB = [&](Instruction &I) {
6401 auto &RI = cast<ReturnInst>(I);
6402 return checkAndUpdate(
6403 A, *this,
6404 IRPosition::value(*RI.getReturnValue(), getCallBaseContext()));
6405 };
6406
6407 bool UsedAssumedInformation = false;
6408 if (!A.checkForAllInstructions(ReturnInstCB, *this, {Instruction::Ret},
6409 UsedAssumedInformation))
6410 if (!askSimplifiedValueForOtherAAs(A))
6411 return indicatePessimisticFixpoint();
6412
6413 // If a candidate was found in this update, return CHANGED.
6414 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED
6415 : ChangeStatus ::CHANGED;
6416 }
6417
6418 ChangeStatus manifest(Attributor &A) override {
6419 // We queried AAValueSimplify for the returned values so they will be
6420 // replaced if a simplified form was found. Nothing to do here.
6421 return ChangeStatus::UNCHANGED;
6422 }
6423
6424 /// See AbstractAttribute::trackStatistics()
6425 void trackStatistics() const override {
6426 STATS_DECLTRACK_FNRET_ATTR(value_simplify)
6427 }
6428};
6429
6430struct AAValueSimplifyFloating : AAValueSimplifyImpl {
6431 AAValueSimplifyFloating(const IRPosition &IRP, Attributor &A)
6432 : AAValueSimplifyImpl(IRP, A) {}
6433
6434 /// See AbstractAttribute::initialize(...).
6435 void initialize(Attributor &A) override {
6436 AAValueSimplifyImpl::initialize(A);
6437 Value &V = getAnchorValue();
6438
6439 // TODO: add other stuffs
6440 if (isa<Constant>(V))
6441 indicatePessimisticFixpoint();
6442 }
6443
6444 /// See AbstractAttribute::updateImpl(...).
6445 ChangeStatus updateImpl(Attributor &A) override {
6446 auto Before = SimplifiedAssociatedValue;
6447 if (!askSimplifiedValueForOtherAAs(A))
6448 return indicatePessimisticFixpoint();
6449
6450 // If a candidate was found in this update, return CHANGED.
6451 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED
6452 : ChangeStatus ::CHANGED;
6453 }
6454
6455 /// See AbstractAttribute::trackStatistics()
6456 void trackStatistics() const override {
6457 STATS_DECLTRACK_FLOATING_ATTR(value_simplify)
6458 }
6459};
6460
6461struct AAValueSimplifyFunction : AAValueSimplifyImpl {
6462 AAValueSimplifyFunction(const IRPosition &IRP, Attributor &A)
6463 : AAValueSimplifyImpl(IRP, A) {}
6464
6465 /// See AbstractAttribute::initialize(...).
6466 void initialize(Attributor &A) override {
6467 SimplifiedAssociatedValue = nullptr;
6468 indicateOptimisticFixpoint();
6469 }
6470 /// See AbstractAttribute::initialize(...).
6471 ChangeStatus updateImpl(Attributor &A) override {
6473 "AAValueSimplify(Function|CallSite)::updateImpl will not be called");
6474 }
6475 /// See AbstractAttribute::trackStatistics()
6476 void trackStatistics() const override {
6477 STATS_DECLTRACK_FN_ATTR(value_simplify)
6478 }
6479};
6480
6481struct AAValueSimplifyCallSite : AAValueSimplifyFunction {
6482 AAValueSimplifyCallSite(const IRPosition &IRP, Attributor &A)
6483 : AAValueSimplifyFunction(IRP, A) {}
6484 /// See AbstractAttribute::trackStatistics()
6485 void trackStatistics() const override {
6486 STATS_DECLTRACK_CS_ATTR(value_simplify)
6487 }
6488};
6489
6490struct AAValueSimplifyCallSiteReturned : AAValueSimplifyImpl {
6491 AAValueSimplifyCallSiteReturned(const IRPosition &IRP, Attributor &A)
6492 : AAValueSimplifyImpl(IRP, A) {}
6493
6494 void initialize(Attributor &A) override {
6495 AAValueSimplifyImpl::initialize(A);
6496 Function *Fn = getAssociatedFunction();
6497 assert(Fn && "Did expect an associted function");
6498 for (Argument &Arg : Fn->args()) {
6499 if (Arg.hasReturnedAttr()) {
6500 auto IRP = IRPosition::callsite_argument(*cast<CallBase>(getCtxI()),
6501 Arg.getArgNo());
6503 checkAndUpdate(A, *this, IRP))
6504 indicateOptimisticFixpoint();
6505 else
6506 indicatePessimisticFixpoint();
6507 return;
6508 }
6509 }
6510 }
6511
6512 /// See AbstractAttribute::updateImpl(...).
6513 ChangeStatus updateImpl(Attributor &A) override {
6514 return indicatePessimisticFixpoint();
6515 }
6516
6517 void trackStatistics() const override {
6518 STATS_DECLTRACK_CSRET_ATTR(value_simplify)
6519 }
6520};
6521
6522struct AAValueSimplifyCallSiteArgument : AAValueSimplifyFloating {
6523 AAValueSimplifyCallSiteArgument(const IRPosition &IRP, Attributor &A)
6524 : AAValueSimplifyFloating(IRP, A) {}
6525
6526 /// See AbstractAttribute::manifest(...).
6527 ChangeStatus manifest(Attributor &A) override {
6528 ChangeStatus Changed = ChangeStatus::UNCHANGED;
6529 // TODO: We should avoid simplification duplication to begin with.
6530 auto *FloatAA = A.lookupAAFor<AAValueSimplify>(
6531 IRPosition::value(getAssociatedValue()), this, DepClassTy::NONE);
6532 if (FloatAA && FloatAA->getState().isValidState())
6533 return Changed;
6534
6535 if (auto *NewV = manifestReplacementValue(A, getCtxI())) {
6536 Use &U = cast<CallBase>(&getAnchorValue())
6537 ->getArgOperandUse(getCallSiteArgNo());
6538 if (A.changeUseAfterManifest(U, *NewV))
6539 Changed = ChangeStatus::CHANGED;
6540 }
6541
6542 return Changed | AAValueSimplify::manifest(A);
6543 }
6544
6545 void trackStatistics() const override {
6546 STATS_DECLTRACK_CSARG_ATTR(value_simplify)
6547 }
6548};
6549} // namespace
6550
6551/// ----------------------- Heap-To-Stack Conversion ---------------------------
6552namespace {
6553struct AAHeapToStackFunction final : public AAHeapToStack {
6554
6555 struct AllocationInfo {
6556 /// The call that allocates the memory.
6557 CallBase *const CB;
6558
6559 /// The library function id for the allocation.
6560 LibFunc LibraryFunctionId = NotLibFunc;
6561
6562 /// The status wrt. a rewrite.
6563 enum {
6564 STACK_DUE_TO_USE,
6565 STACK_DUE_TO_FREE,
6566 INVALID,
6567 } Status = STACK_DUE_TO_USE;
6568
6569 /// Flag to indicate if we encountered a use that might free this allocation
6570 /// but which is not in the deallocation infos.
6571 bool HasPotentiallyFreeingUnknownUses = false;
6572
6573 /// Flag to indicate that we should place the new alloca in the function
6574 /// entry block rather than where the call site (CB) is.
6575 bool MoveAllocaIntoEntry = true;
6576
6577 /// The set of free calls that use this allocation.
6578 SmallSetVector<CallBase *, 1> PotentialFreeCalls{};
6579 };
6580
6581 struct DeallocationInfo {
6582 /// The call that deallocates the memory.
6583 CallBase *const CB;
6584 /// The value freed by the call.
6585 Value *FreedOp;
6586
6587 /// Flag to indicate if we don't know all objects this deallocation might
6588 /// free.
6589 bool MightFreeUnknownObjects = false;
6590
6591 /// The set of allocation calls that are potentially freed.
6592 SmallSetVector<CallBase *, 1> PotentialAllocationCalls{};
6593 };
6594
6595 AAHeapToStackFunction(const IRPosition &IRP, Attributor &A)
6596 : AAHeapToStack(IRP, A) {}
6597
6598 ~AAHeapToStackFunction() {
6599 // Ensure we call the destructor so we release any memory allocated in the
6600 // sets.
6601 for (auto &It : AllocationInfos)
6602 It.second->~AllocationInfo();
6603 for (auto &It : DeallocationInfos)
6604 It.second->~DeallocationInfo();
6605 }
6606
6607 void initialize(Attributor &A) override {
6608 AAHeapToStack::initialize(A);
6609
6610 const Function *F = getAnchorScope();
6611 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
6612
6613 auto AllocationIdentifierCB = [&](Instruction &I) {
6614 CallBase *CB = dyn_cast<CallBase>(&I);
6615 if (!CB)
6616 return true;
6617 if (Value *FreedOp = getFreedOperand(CB, TLI)) {
6618 DeallocationInfos[CB] = new (A.Allocator) DeallocationInfo{CB, FreedOp};
6619 return true;
6620 }
6621 // To do heap to stack, we need to know that the allocation itself is
6622 // removable once uses are rewritten, and that we can initialize the
6623 // alloca to the same pattern as the original allocation result.
6624 if (isRemovableAlloc(CB, TLI)) {
6625 auto *I8Ty = Type::getInt8Ty(CB->getParent()->getContext());
6626 if (nullptr != getInitialValueOfAllocation(CB, TLI, I8Ty)) {
6627 AllocationInfo *AI = new (A.Allocator) AllocationInfo{CB};
6628 AllocationInfos[CB] = AI;
6629 if (TLI)
6630 TLI->getLibFunc(*CB, AI->LibraryFunctionId);
6631 }
6632 }
6633 return true;
6634 };
6635
6636 bool UsedAssumedInformation = false;
6637 bool Success = A.checkForAllCallLikeInstructions(
6638 AllocationIdentifierCB, *this, UsedAssumedInformation,
6639 /* CheckBBLivenessOnly */ false,
6640 /* CheckPotentiallyDead */ true);
6641 (void)Success;
6642 assert(Success && "Did not expect the call base visit callback to fail!");
6643
6645 [](const IRPosition &, const AbstractAttribute *,
6646 bool &) -> std::optional<Value *> { return nullptr; };
6647 for (const auto &It : AllocationInfos)
6648 A.registerSimplificationCallback(IRPosition::callsite_returned(*It.first),
6649 SCB);
6650 for (const auto &It : DeallocationInfos)
6651 A.registerSimplificationCallback(IRPosition::callsite_returned(*It.first),
6652 SCB);
6653 }
6654
6655 const std::string getAsStr(Attributor *A) const override {
6656 unsigned NumH2SMallocs = 0, NumInvalidMallocs = 0;
6657 for (const auto &It : AllocationInfos) {
6658 if (It.second->Status == AllocationInfo::INVALID)
6659 ++NumInvalidMallocs;
6660 else
6661 ++NumH2SMallocs;
6662 }
6663 return "[H2S] Mallocs Good/Bad: " + std::to_string(NumH2SMallocs) + "/" +
6664 std::to_string(NumInvalidMallocs);
6665 }
6666
6667 /// See AbstractAttribute::trackStatistics().
6668 void trackStatistics() const override {
6669 STATS_DECL(
6670 MallocCalls, Function,
6671 "Number of malloc/calloc/aligned_alloc calls converted to allocas");
6672 for (const auto &It : AllocationInfos)
6673 if (It.second->Status != AllocationInfo::INVALID)
6674 ++BUILD_STAT_NAME(MallocCalls, Function);
6675 }
6676
6677 bool isAssumedHeapToStack(const CallBase &CB) const override {
6678 if (isValidState())
6679 if (AllocationInfo *AI =
6680 AllocationInfos.lookup(const_cast<CallBase *>(&CB)))
6681 return AI->Status != AllocationInfo::INVALID;
6682 return false;
6683 }
6684
6685 bool isAssumedHeapToStackRemovedFree(CallBase &CB) const override {
6686 if (!isValidState())
6687 return false;
6688
6689 for (const auto &It : AllocationInfos) {
6690 AllocationInfo &AI = *It.second;
6691 if (AI.Status == AllocationInfo::INVALID)
6692 continue;
6693
6694 if (AI.PotentialFreeCalls.count(&CB))
6695 return true;
6696 }
6697
6698 return false;
6699 }
6700
6701 ChangeStatus manifest(Attributor &A) override {
6702 assert(getState().isValidState() &&
6703 "Attempted to manifest an invalid state!");
6704
6705 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
6706 Function *F = getAnchorScope();
6707 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
6708
6709 for (auto &It : AllocationInfos) {
6710 AllocationInfo &AI = *It.second;
6711 if (AI.Status == AllocationInfo::INVALID)
6712 continue;
6713
6714 for (CallBase *FreeCall : AI.PotentialFreeCalls) {
6715 LLVM_DEBUG(dbgs() << "H2S: Removing free call: " << *FreeCall << "\n");
6716 A.deleteAfterManifest(*FreeCall);
6717 HasChanged = ChangeStatus::CHANGED;
6718 }
6719
6720 LLVM_DEBUG(dbgs() << "H2S: Removing malloc-like call: " << *AI.CB
6721 << "\n");
6722
6723 auto Remark = [&](OptimizationRemark OR) {
6724 LibFunc IsAllocShared;
6725 if (TLI->getLibFunc(*AI.CB, IsAllocShared))
6726 if (IsAllocShared == LibFunc___kmpc_alloc_shared)
6727 return OR << "Moving globalized variable to the stack.";
6728 return OR << "Moving memory allocation from the heap to the stack.";
6729 };
6730 if (AI.LibraryFunctionId == LibFunc___kmpc_alloc_shared)
6731 A.emitRemark<OptimizationRemark>(AI.CB, "OMP110", Remark);
6732 else
6733 A.emitRemark<OptimizationRemark>(AI.CB, "HeapToStack", Remark);
6734
6735 const DataLayout &DL = A.getInfoCache().getDL();
6736 Value *Size;
6737 std::optional<APInt> SizeAPI = getSize(A, *this, AI);
6738 if (SizeAPI) {
6739 Size = ConstantInt::get(AI.CB->getContext(), *SizeAPI);
6740 } else {
6741 LLVMContext &Ctx = AI.CB->getContext();
6742 ObjectSizeOpts Opts;
6743 ObjectSizeOffsetEvaluator Eval(DL, TLI, Ctx, Opts);
6744 SizeOffsetValue SizeOffsetPair = Eval.compute(AI.CB);
6745 assert(SizeOffsetPair != ObjectSizeOffsetEvaluator::unknown() &&
6746 cast<ConstantInt>(SizeOffsetPair.Offset)->isZero());
6747 Size = SizeOffsetPair.Size;
6748 }
6749
6750 BasicBlock::iterator IP = AI.MoveAllocaIntoEntry
6751 ? F->getEntryBlock().begin()
6752 : AI.CB->getIterator();
6753
6754 Align Alignment(1);
6755 if (MaybeAlign RetAlign = AI.CB->getRetAlign())
6756 Alignment = std::max(Alignment, *RetAlign);
6757 if (Value *Align = getAllocAlignment(AI.CB, TLI)) {
6758 std::optional<APInt> AlignmentAPI = getAPInt(A, *this, *Align);
6759 assert(AlignmentAPI && AlignmentAPI->getZExtValue() > 0 &&
6760 "Expected an alignment during manifest!");
6761 Alignment =
6762 std::max(Alignment, assumeAligned(AlignmentAPI->getZExtValue()));
6763 }
6764
6765 // TODO: Hoist the alloca towards the function entry.
6766 unsigned AS = DL.getAllocaAddrSpace();
6767 Instruction *Alloca =
6768 new AllocaInst(Type::getInt8Ty(F->getContext()), AS, Size, Alignment,
6769 AI.CB->getName() + ".h2s", IP);
6770
6771 if (Alloca->getType() != AI.CB->getType())
6772 Alloca = BitCastInst::CreatePointerBitCastOrAddrSpaceCast(
6773 Alloca, AI.CB->getType(), "malloc_cast", AI.CB->getIterator());
6774
6775 auto *I8Ty = Type::getInt8Ty(F->getContext());
6776 auto *InitVal = getInitialValueOfAllocation(AI.CB, TLI, I8Ty);
6777 assert(InitVal &&
6778 "Must be able to materialize initial memory state of allocation");
6779
6780 A.changeAfterManifest(IRPosition::inst(*AI.CB), *Alloca);
6781
6782 if (auto *II = dyn_cast<InvokeInst>(AI.CB)) {
6783 auto *NBB = II->getNormalDest();
6784 BranchInst::Create(NBB, AI.CB->getParent());
6785 A.deleteAfterManifest(*AI.CB);
6786 } else {
6787 A.deleteAfterManifest(*AI.CB);
6788 }
6789
6790 // Initialize the alloca with the same value as used by the allocation
6791 // function. We can skip undef as the initial value of an alloc is
6792 // undef, and the memset would simply end up being DSEd.
6793 if (!isa<UndefValue>(InitVal)) {
6794 IRBuilder<> Builder(Alloca->getNextNode());
6795 // TODO: Use alignment above if align!=1
6796 Builder.CreateMemSet(Alloca, InitVal, Size, std::nullopt);
6797 }
6798 HasChanged = ChangeStatus::CHANGED;
6799 }
6800
6801 return HasChanged;
6802 }
6803
6804 std::optional<APInt> getAPInt(Attributor &A, const AbstractAttribute &AA,
6805 Value &V) {
6806 bool UsedAssumedInformation = false;
6807 std::optional<Constant *> SimpleV =
6808 A.getAssumedConstant(V, AA, UsedAssumedInformation);
6809 if (!SimpleV)
6810 return APInt(64, 0);
6811 if (auto *CI = dyn_cast_or_null<ConstantInt>(*SimpleV))
6812 return CI->getValue();
6813 return std::nullopt;
6814 }
6815
6816 std::optional<APInt> getSize(Attributor &A, const AbstractAttribute &AA,
6817 AllocationInfo &AI) {
6818 auto Mapper = [&](const Value *V) -> const Value * {
6819 bool UsedAssumedInformation = false;
6820 if (std::optional<Constant *> SimpleV =
6821 A.getAssumedConstant(*V, AA, UsedAssumedInformation))
6822 if (*SimpleV)
6823 return *SimpleV;
6824 return V;
6825 };
6826
6827 const Function *F = getAnchorScope();
6828 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
6829 return getAllocSize(AI.CB, TLI, Mapper);
6830 }
6831
6832 /// Collection of all malloc-like calls in a function with associated
6833 /// information.
6835
6836 /// Collection of all free-like calls in a function with associated
6837 /// information.
6839
6840 ChangeStatus updateImpl(Attributor &A) override;
6841};
6842
6843ChangeStatus AAHeapToStackFunction::updateImpl(Attributor &A) {
6845 const Function *F = getAnchorScope();
6846 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
6847
6848 const auto *LivenessAA =
6849 A.getAAFor<AAIsDead>(*this, IRPosition::function(*F), DepClassTy::NONE);
6850
6852 A.getInfoCache().getMustBeExecutedContextExplorer();
6853
6854 bool StackIsAccessibleByOtherThreads =
6855 A.getInfoCache().stackIsAccessibleByOtherThreads();
6856
6857 LoopInfo *LI =
6858 A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(*F);
6859 std::optional<bool> MayContainIrreducibleControl;
6860 auto IsInLoop = [&](BasicBlock &BB) {
6861 if (&F->getEntryBlock() == &BB)
6862 return false;
6863 if (!MayContainIrreducibleControl.has_value())
6864 MayContainIrreducibleControl = mayContainIrreducibleControl(*F, LI);
6865 if (*MayContainIrreducibleControl)
6866 return true;
6867 if (!LI)
6868 return true;
6869 return LI->getLoopFor(&BB) != nullptr;
6870 };
6871
6872 // Flag to ensure we update our deallocation information at most once per
6873 // updateImpl call and only if we use the free check reasoning.
6874 bool HasUpdatedFrees = false;
6875
6876 auto UpdateFrees = [&]() {
6877 HasUpdatedFrees = true;
6878
6879 for (auto &It : DeallocationInfos) {
6880 DeallocationInfo &DI = *It.second;
6881 // For now we cannot use deallocations that have unknown inputs, skip
6882 // them.
6883 if (DI.MightFreeUnknownObjects)
6884 continue;
6885
6886 // No need to analyze dead calls, ignore them instead.
6887 bool UsedAssumedInformation = false;
6888 if (A.isAssumedDead(*DI.CB, this, LivenessAA, UsedAssumedInformation,
6889 /* CheckBBLivenessOnly */ true))
6890 continue;
6891
6892 // Use the non-optimistic version to get the freed object.
6893 Value *Obj = getUnderlyingObject(DI.FreedOp);
6894 if (!Obj) {
6895 LLVM_DEBUG(dbgs() << "[H2S] Unknown underlying object for free!\n");
6896 DI.MightFreeUnknownObjects = true;
6897 continue;
6898 }
6899
6900 // Free of null and undef can be ignored as no-ops (or UB in the latter
6901 // case).
6902 if (isa<ConstantPointerNull>(Obj) || isa<UndefValue>(Obj))
6903 continue;
6904
6905 CallBase *ObjCB = dyn_cast<CallBase>(Obj);
6906 if (!ObjCB) {
6907 LLVM_DEBUG(dbgs() << "[H2S] Free of a non-call object: " << *Obj
6908 << "\n");
6909 DI.MightFreeUnknownObjects = true;
6910 continue;
6911 }
6912
6913 AllocationInfo *AI = AllocationInfos.lookup(ObjCB);
6914 if (!AI) {
6915 LLVM_DEBUG(dbgs() << "[H2S] Free of a non-allocation object: " << *Obj
6916 << "\n");
6917 DI.MightFreeUnknownObjects = true;
6918 continue;
6919 }
6920
6921 DI.PotentialAllocationCalls.insert(ObjCB);
6922 }
6923 };
6924
6925 auto FreeCheck = [&](AllocationInfo &AI) {
6926 // If the stack is not accessible by other threads, the "must-free" logic
6927 // doesn't apply as the pointer could be shared and needs to be places in
6928 // "shareable" memory.
6929 if (!StackIsAccessibleByOtherThreads) {
6930 bool IsKnownNoSycn;
6931 if (!AA::hasAssumedIRAttr<Attribute::NoSync>(
6932 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNoSycn)) {
6933 LLVM_DEBUG(
6934 dbgs() << "[H2S] found an escaping use, stack is not accessible by "
6935 "other threads and function is not nosync:\n");
6936 return false;
6937 }
6938 }
6939 if (!HasUpdatedFrees)
6940 UpdateFrees();
6941
6942 // TODO: Allow multi exit functions that have different free calls.
6943 if (AI.PotentialFreeCalls.size() != 1) {
6944 LLVM_DEBUG(dbgs() << "[H2S] did not find one free call but "
6945 << AI.PotentialFreeCalls.size() << "\n");
6946 return false;
6947 }
6948 CallBase *UniqueFree = *AI.PotentialFreeCalls.begin();
6949 DeallocationInfo *DI = DeallocationInfos.lookup(UniqueFree);
6950 if (!DI) {
6951 LLVM_DEBUG(
6952 dbgs() << "[H2S] unique free call was not known as deallocation call "
6953 << *UniqueFree << "\n");
6954 return false;
6955 }
6956 if (DI->MightFreeUnknownObjects) {
6957 LLVM_DEBUG(
6958 dbgs() << "[H2S] unique free call might free unknown allocations\n");
6959 return false;
6960 }
6961 if (DI->PotentialAllocationCalls.empty())
6962 return true;
6963 if (DI->PotentialAllocationCalls.size() > 1) {
6964 LLVM_DEBUG(dbgs() << "[H2S] unique free call might free "
6965 << DI->PotentialAllocationCalls.size()
6966 << " different allocations\n");
6967 return false;
6968 }
6969 if (*DI->PotentialAllocationCalls.begin() != AI.CB) {
6970 LLVM_DEBUG(
6971 dbgs()
6972 << "[H2S] unique free call not known to free this allocation but "
6973 << **DI->PotentialAllocationCalls.begin() << "\n");
6974 return false;
6975 }
6976
6977 // __kmpc_alloc_shared and __kmpc_alloc_free are by construction matched.
6978 if (AI.LibraryFunctionId != LibFunc___kmpc_alloc_shared) {
6979 Instruction *CtxI = isa<InvokeInst>(AI.CB) ? AI.CB : AI.CB->getNextNode();
6980 if (!Explorer || !Explorer->findInContextOf(UniqueFree, CtxI)) {
6981 LLVM_DEBUG(dbgs() << "[H2S] unique free call might not be executed "
6982 "with the allocation "
6983 << *UniqueFree << "\n");
6984 return false;
6985 }
6986 }
6987 return true;
6988 };
6989
6990 auto UsesCheck = [&](AllocationInfo &AI) {
6991 bool ValidUsesOnly = true;
6992
6993 auto Pred = [&](const Use &U, bool &Follow) -> bool {
6994 Instruction *UserI = cast<Instruction>(U.getUser());
6995 if (isa<LoadInst>(UserI))
6996 return true;
6997 if (auto *SI = dyn_cast<StoreInst>(UserI)) {
6998 if (SI->getValueOperand() == U.get()) {
7000 << "[H2S] escaping store to memory: " << *UserI << "\n");
7001 ValidUsesOnly = false;
7002 } else {
7003 // A store into the malloc'ed memory is fine.
7004 }
7005 return true;
7006 }
7007 if (auto *CB = dyn_cast<CallBase>(UserI)) {
7008 if (!CB->isArgOperand(&U) || CB->isLifetimeStartOrEnd())
7009 return true;
7010 if (DeallocationInfos.count(CB)) {
7011 AI.PotentialFreeCalls.insert(CB);
7012 return true;
7013 }
7014
7015 unsigned ArgNo = CB->getArgOperandNo(&U);
7016 auto CBIRP = IRPosition::callsite_argument(*CB, ArgNo);
7017
7018 bool IsKnownNoCapture;
7019 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::NoCapture>(
7020 A, this, CBIRP, DepClassTy::OPTIONAL, IsKnownNoCapture);
7021
7022 // If a call site argument use is nofree, we are fine.
7023 bool IsKnownNoFree;
7024 bool IsAssumedNoFree = AA::hasAssumedIRAttr<Attribute::NoFree>(
7025 A, this, CBIRP, DepClassTy::OPTIONAL, IsKnownNoFree);
7026
7027 if (!IsAssumedNoCapture ||
7028 (AI.LibraryFunctionId != LibFunc___kmpc_alloc_shared &&
7029 !IsAssumedNoFree)) {
7030 AI.HasPotentiallyFreeingUnknownUses |= !IsAssumedNoFree;
7031
7032 // Emit a missed remark if this is missed OpenMP globalization.
7033 auto Remark = [&](OptimizationRemarkMissed ORM) {
7034 return ORM
7035 << "Could not move globalized variable to the stack. "
7036 "Variable is potentially captured in call. Mark "
7037 "parameter as `__attribute__((noescape))` to override.";
7038 };
7039
7040 if (ValidUsesOnly &&
7041 AI.LibraryFunctionId == LibFunc___kmpc_alloc_shared)
7042 A.emitRemark<OptimizationRemarkMissed>(CB, "OMP113", Remark);
7043
7044 LLVM_DEBUG(dbgs() << "[H2S] Bad user: " << *UserI << "\n");
7045 ValidUsesOnly = false;
7046 }
7047 return true;
7048 }
7049
7050 if (isa<GetElementPtrInst>(UserI) || isa<BitCastInst>(UserI) ||
7051 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) {
7052 Follow = true;
7053 return true;
7054 }
7055 // Unknown user for which we can not track uses further (in a way that
7056 // makes sense).
7057 LLVM_DEBUG(dbgs() << "[H2S] Unknown user: " << *UserI << "\n");
7058 ValidUsesOnly = false;
7059 return true;
7060 };
7061 if (!A.checkForAllUses(Pred, *this, *AI.CB, /* CheckBBLivenessOnly */ false,
7062 DepClassTy::OPTIONAL, /* IgnoreDroppableUses */ true,
7063 [&](const Use &OldU, const Use &NewU) {
7064 auto *SI = dyn_cast<StoreInst>(OldU.getUser());
7065 return !SI || StackIsAccessibleByOtherThreads ||
7066 AA::isAssumedThreadLocalObject(
7067 A, *SI->getPointerOperand(), *this);
7068 }))
7069 return false;
7070 return ValidUsesOnly;
7071 };
7072
7073 // The actual update starts here. We look at all allocations and depending on
7074 // their status perform the appropriate check(s).
7075 for (auto &It : AllocationInfos) {
7076 AllocationInfo &AI = *It.second;
7077 if (AI.Status == AllocationInfo::INVALID)
7078 continue;
7079
7080 if (Value *Align = getAllocAlignment(AI.CB, TLI)) {
7081 std::optional<APInt> APAlign = getAPInt(A, *this, *Align);
7082 if (!APAlign) {
7083 // Can't generate an alloca which respects the required alignment
7084 // on the allocation.
7085 LLVM_DEBUG(dbgs() << "[H2S] Unknown allocation alignment: " << *AI.CB
7086 << "\n");
7087 AI.Status = AllocationInfo::INVALID;
7088 Changed = ChangeStatus::CHANGED;
7089 continue;
7090 }
7091 if (APAlign->ugt(llvm::Value::MaximumAlignment) ||
7092 !APAlign->isPowerOf2()) {
7093 LLVM_DEBUG(dbgs() << "[H2S] Invalid allocation alignment: " << APAlign
7094 << "\n");
7095 AI.Status = AllocationInfo::INVALID;
7096 Changed = ChangeStatus::CHANGED;
7097 continue;
7098 }
7099 }
7100
7101 std::optional<APInt> Size = getSize(A, *this, AI);
7102 if (AI.LibraryFunctionId != LibFunc___kmpc_alloc_shared &&
7103 MaxHeapToStackSize != -1) {
7104 if (!Size || Size->ugt(MaxHeapToStackSize)) {
7105 LLVM_DEBUG({
7106 if (!Size)
7107 dbgs() << "[H2S] Unknown allocation size: " << *AI.CB << "\n";
7108 else
7109 dbgs() << "[H2S] Allocation size too large: " << *AI.CB << " vs. "
7110 << MaxHeapToStackSize << "\n";
7111 });
7112
7113 AI.Status = AllocationInfo::INVALID;
7114 Changed = ChangeStatus::CHANGED;
7115 continue;
7116 }
7117 }
7118
7119 switch (AI.Status) {
7120 case AllocationInfo::STACK_DUE_TO_USE:
7121 if (UsesCheck(AI))
7122 break;
7123 AI.Status = AllocationInfo::STACK_DUE_TO_FREE;
7124 [[fallthrough]];
7125 case AllocationInfo::STACK_DUE_TO_FREE:
7126 if (FreeCheck(AI))
7127 break;
7128 AI.Status = AllocationInfo::INVALID;
7129 Changed = ChangeStatus::CHANGED;
7130 break;
7131 case AllocationInfo::INVALID:
7132 llvm_unreachable("Invalid allocations should never reach this point!");
7133 };
7134
7135 // Check if we still think we can move it into the entry block. If the
7136 // alloca comes from a converted __kmpc_alloc_shared then we can usually
7137 // ignore the potential compilations associated with loops.
7138 bool IsGlobalizedLocal =
7139 AI.LibraryFunctionId == LibFunc___kmpc_alloc_shared;
7140 if (AI.MoveAllocaIntoEntry &&
7141 (!Size.has_value() ||
7142 (!IsGlobalizedLocal && IsInLoop(*AI.CB->getParent()))))
7143 AI.MoveAllocaIntoEntry = false;
7144 }
7145
7146 return Changed;
7147}
7148} // namespace
7149
7150/// ----------------------- Privatizable Pointers ------------------------------
7151namespace {
7152struct AAPrivatizablePtrImpl : public AAPrivatizablePtr {
7153 AAPrivatizablePtrImpl(const IRPosition &IRP, Attributor &A)
7154 : AAPrivatizablePtr(IRP, A), PrivatizableType(std::nullopt) {}
7155
7156 ChangeStatus indicatePessimisticFixpoint() override {
7157 AAPrivatizablePtr::indicatePessimisticFixpoint();
7158 PrivatizableType = nullptr;
7159 return ChangeStatus::CHANGED;
7160 }
7161
7162 /// Identify the type we can chose for a private copy of the underlying
7163 /// argument. std::nullopt means it is not clear yet, nullptr means there is
7164 /// none.
7165 virtual std::optional<Type *> identifyPrivatizableType(Attributor &A) = 0;
7166
7167 /// Return a privatizable type that encloses both T0 and T1.
7168 /// TODO: This is merely a stub for now as we should manage a mapping as well.
7169 std::optional<Type *> combineTypes(std::optional<Type *> T0,
7170 std::optional<Type *> T1) {
7171 if (!T0)
7172 return T1;
7173 if (!T1)
7174 return T0;
7175 if (T0 == T1)
7176 return T0;
7177 return nullptr;
7178 }
7179
7180 std::optional<Type *> getPrivatizableType() const override {
7181 return PrivatizableType;
7182 }
7183
7184 const std::string getAsStr(Attributor *A) const override {
7185 return isAssumedPrivatizablePtr() ? "[priv]" : "[no-priv]";
7186 }
7187
7188protected:
7189 std::optional<Type *> PrivatizableType;
7190};
7191
7192// TODO: Do this for call site arguments (probably also other values) as well.
7193
7194struct AAPrivatizablePtrArgument final : public AAPrivatizablePtrImpl {
7195 AAPrivatizablePtrArgument(const IRPosition &IRP, Attributor &A)
7196 : AAPrivatizablePtrImpl(IRP, A) {}
7197
7198 /// See AAPrivatizablePtrImpl::identifyPrivatizableType(...)
7199 std::optional<Type *> identifyPrivatizableType(Attributor &A) override {
7200 // If this is a byval argument and we know all the call sites (so we can
7201 // rewrite them), there is no need to check them explicitly.
7202 bool UsedAssumedInformation = false;
7204 A.getAttrs(getIRPosition(), {Attribute::ByVal}, Attrs,
7205 /* IgnoreSubsumingPositions */ true);
7206 if (!Attrs.empty() &&
7207 A.checkForAllCallSites([](AbstractCallSite ACS) { return true; }, *this,
7208 true, UsedAssumedInformation))
7209 return Attrs[0].getValueAsType();
7210
7211 std::optional<Type *> Ty;
7212 unsigned ArgNo = getIRPosition().getCallSiteArgNo();
7213
7214 // Make sure the associated call site argument has the same type at all call
7215 // sites and it is an allocation we know is safe to privatize, for now that
7216 // means we only allow alloca instructions.
7217 // TODO: We can additionally analyze the accesses in the callee to create
7218 // the type from that information instead. That is a little more
7219 // involved and will be done in a follow up patch.
7220 auto CallSiteCheck = [&](AbstractCallSite ACS) {
7221 IRPosition ACSArgPos = IRPosition::callsite_argument(ACS, ArgNo);
7222 // Check if a coresponding argument was found or if it is one not
7223 // associated (which can happen for callback calls).
7224 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
7225 return false;
7226
7227 // Check that all call sites agree on a type.
7228 auto *PrivCSArgAA =
7229 A.getAAFor<AAPrivatizablePtr>(*this, ACSArgPos, DepClassTy::REQUIRED);
7230 if (!PrivCSArgAA)
7231 return false;
7232 std::optional<Type *> CSTy = PrivCSArgAA->getPrivatizableType();
7233
7234 LLVM_DEBUG({
7235 dbgs() << "[AAPrivatizablePtr] ACSPos: " << ACSArgPos << ", CSTy: ";
7236 if (CSTy && *CSTy)
7237 (*CSTy)->print(dbgs());
7238 else if (CSTy)
7239 dbgs() << "<nullptr>";
7240 else
7241 dbgs() << "<none>";
7242 });
7243
7244 Ty = combineTypes(Ty, CSTy);
7245
7246 LLVM_DEBUG({
7247 dbgs() << " : New Type: ";
7248 if (Ty && *Ty)
7249 (*Ty)->print(dbgs());
7250 else if (Ty)
7251 dbgs() << "<nullptr>";
7252 else
7253 dbgs() << "<none>";
7254 dbgs() << "\n";
7255 });
7256
7257 return !Ty || *Ty;
7258 };
7259
7260 if (!A.checkForAllCallSites(CallSiteCheck, *this, true,
7261 UsedAssumedInformation))
7262 return nullptr;
7263 return Ty;
7264 }
7265
7266 /// See AbstractAttribute::updateImpl(...).
7267 ChangeStatus updateImpl(Attributor &A) override {
7268 PrivatizableType = identifyPrivatizableType(A);
7269 if (!PrivatizableType)
7270 return ChangeStatus::UNCHANGED;
7271 if (!*PrivatizableType)
7272 return indicatePessimisticFixpoint();
7273
7274 // The dependence is optional so we don't give up once we give up on the
7275 // alignment.
7276 A.getAAFor<AAAlign>(*this, IRPosition::value(getAssociatedValue()),
7277 DepClassTy::OPTIONAL);
7278
7279 // Avoid arguments with padding for now.
7280 if (!A.hasAttr(getIRPosition(), Attribute::ByVal) &&
7281 !isDenselyPacked(*PrivatizableType, A.getInfoCache().getDL())) {
7282 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Padding detected\n");
7283 return indicatePessimisticFixpoint();
7284 }
7285
7286 // Collect the types that will replace the privatizable type in the function
7287 // signature.
7288 SmallVector<Type *, 16> ReplacementTypes;
7289 identifyReplacementTypes(*PrivatizableType, ReplacementTypes);
7290
7291 // Verify callee and caller agree on how the promoted argument would be
7292 // passed.
7293 Function &Fn = *getIRPosition().getAnchorScope();
7294 const auto *TTI =
7295 A.getInfoCache().getAnalysisResultForFunction<TargetIRAnalysis>(Fn);
7296 if (!TTI) {
7297 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Missing TTI for function "
7298 << Fn.getName() << "\n");
7299 return indicatePessimisticFixpoint();
7300 }
7301
7302 auto CallSiteCheck = [&](AbstractCallSite ACS) {
7303 CallBase *CB = ACS.getInstruction();
7304 return TTI->areTypesABICompatible(
7305 CB->getCaller(),
7306 dyn_cast_if_present<Function>(CB->getCalledOperand()),
7307 ReplacementTypes);
7308 };
7309 bool UsedAssumedInformation = false;
7310 if (!A.checkForAllCallSites(CallSiteCheck, *this, true,
7311 UsedAssumedInformation)) {
7312 LLVM_DEBUG(
7313 dbgs() << "[AAPrivatizablePtr] ABI incompatibility detected for "
7314 << Fn.getName() << "\n");
7315 return indicatePessimisticFixpoint();
7316 }
7317
7318 // Register a rewrite of the argument.
7319 Argument *Arg = getAssociatedArgument();
7320 if (!A.isValidFunctionSignatureRewrite(*Arg, ReplacementTypes)) {
7321 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Rewrite not valid\n");
7322 return indicatePessimisticFixpoint();
7323 }
7324
7325 unsigned ArgNo = Arg->getArgNo();
7326
7327 // Helper to check if for the given call site the associated argument is
7328 // passed to a callback where the privatization would be different.
7329 auto IsCompatiblePrivArgOfCallback = [&](CallBase &CB) {
7330 SmallVector<const Use *, 4> CallbackUses;
7331 AbstractCallSite::getCallbackUses(CB, CallbackUses);
7332 for (const Use *U : CallbackUses) {
7333 AbstractCallSite CBACS(U);
7334 assert(CBACS && CBACS.isCallbackCall());
7335 for (Argument &CBArg : CBACS.getCalledFunction()->args()) {
7336 int CBArgNo = CBACS.getCallArgOperandNo(CBArg);
7337
7338 LLVM_DEBUG({
7339 dbgs()
7340 << "[AAPrivatizablePtr] Argument " << *Arg
7341 << "check if can be privatized in the context of its parent ("
7342 << Arg->getParent()->getName()
7343 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7344 "callback ("
7345 << CBArgNo << "@" << CBACS.getCalledFunction()->getName()
7346 << ")\n[AAPrivatizablePtr] " << CBArg << " : "
7347 << CBACS.getCallArgOperand(CBArg) << " vs "
7348 << CB.getArgOperand(ArgNo) << "\n"
7349 << "[AAPrivatizablePtr] " << CBArg << " : "
7350 << CBACS.getCallArgOperandNo(CBArg) << " vs " << ArgNo << "\n";
7351 });
7352
7353 if (CBArgNo != int(ArgNo))
7354 continue;
7355 const auto *CBArgPrivAA = A.getAAFor<AAPrivatizablePtr>(
7356 *this, IRPosition::argument(CBArg), DepClassTy::REQUIRED);
7357 if (CBArgPrivAA && CBArgPrivAA->isValidState()) {
7358 auto CBArgPrivTy = CBArgPrivAA->getPrivatizableType();
7359 if (!CBArgPrivTy)
7360 continue;
7361 if (*CBArgPrivTy == PrivatizableType)
7362 continue;
7363 }
7364
7365 LLVM_DEBUG({
7366 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
7367 << " cannot be privatized in the context of its parent ("
7368 << Arg->getParent()->getName()
7369 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7370 "callback ("
7371 << CBArgNo << "@" << CBACS.getCalledFunction()->getName()
7372 << ").\n[AAPrivatizablePtr] for which the argument "
7373 "privatization is not compatible.\n";
7374 });
7375 return false;
7376 }
7377 }
7378 return true;
7379 };
7380
7381 // Helper to check if for the given call site the associated argument is
7382 // passed to a direct call where the privatization would be different.
7383 auto IsCompatiblePrivArgOfDirectCS = [&](AbstractCallSite ACS) {
7384 CallBase *DC = cast<CallBase>(ACS.getInstruction());
7385 int DCArgNo = ACS.getCallArgOperandNo(ArgNo);
7386 assert(DCArgNo >= 0 && unsigned(DCArgNo) < DC->arg_size() &&
7387 "Expected a direct call operand for callback call operand");
7388
7389 Function *DCCallee =
7390 dyn_cast_if_present<Function>(DC->getCalledOperand());
7391 LLVM_DEBUG({
7392 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
7393 << " check if be privatized in the context of its parent ("
7394 << Arg->getParent()->getName()
7395 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7396 "direct call of ("
7397 << DCArgNo << "@" << DCCallee->getName() << ").\n";
7398 });
7399
7400 if (unsigned(DCArgNo) < DCCallee->arg_size()) {
7401 const auto *DCArgPrivAA = A.getAAFor<AAPrivatizablePtr>(
7402 *this, IRPosition::argument(*DCCallee->getArg(DCArgNo)),
7403 DepClassTy::REQUIRED);
7404 if (DCArgPrivAA && DCArgPrivAA->isValidState()) {
7405 auto DCArgPrivTy = DCArgPrivAA->getPrivatizableType();
7406 if (!DCArgPrivTy)
7407 return true;
7408 if (*DCArgPrivTy == PrivatizableType)
7409 return true;
7410 }
7411 }
7412
7413 LLVM_DEBUG({
7414 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
7415 << " cannot be privatized in the context of its parent ("
7416 << Arg->getParent()->getName()
7417 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7418 "direct call of ("
7420 << ").\n[AAPrivatizablePtr] for which the argument "
7421 "privatization is not compatible.\n";
7422 });
7423 return false;
7424 };
7425
7426 // Helper to check if the associated argument is used at the given abstract
7427 // call site in a way that is incompatible with the privatization assumed
7428 // here.
7429 auto IsCompatiblePrivArgOfOtherCallSite = [&](AbstractCallSite ACS) {
7430 if (ACS.isDirectCall())
7431 return IsCompatiblePrivArgOfCallback(*ACS.getInstruction());
7432 if (ACS.isCallbackCall())
7433 return IsCompatiblePrivArgOfDirectCS(ACS);
7434 return false;
7435 };
7436
7437 if (!A.checkForAllCallSites(IsCompatiblePrivArgOfOtherCallSite, *this, true,
7438 UsedAssumedInformation))
7439 return indicatePessimisticFixpoint();
7440
7441 return ChangeStatus::UNCHANGED;
7442 }
7443
7444 /// Given a type to private \p PrivType, collect the constituates (which are
7445 /// used) in \p ReplacementTypes.
7446 static void
7447 identifyReplacementTypes(Type *PrivType,
7448 SmallVectorImpl<Type *> &ReplacementTypes) {
7449 // TODO: For now we expand the privatization type to the fullest which can
7450 // lead to dead arguments that need to be removed later.
7451 assert(PrivType && "Expected privatizable type!");
7452
7453 // Traverse the type, extract constituate types on the outermost level.
7454 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) {
7455 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++)
7456 ReplacementTypes.push_back(PrivStructType->getElementType(u));
7457 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) {
7458 ReplacementTypes.append(PrivArrayType->getNumElements(),
7459 PrivArrayType->getElementType());
7460 } else {
7461 ReplacementTypes.push_back(PrivType);
7462 }
7463 }
7464
7465 /// Initialize \p Base according to the type \p PrivType at position \p IP.
7466 /// The values needed are taken from the arguments of \p F starting at
7467 /// position \p ArgNo.
7468 static void createInitialization(Type *PrivType, Value &Base, Function &F,
7469 unsigned ArgNo, BasicBlock::iterator IP) {
7470 assert(PrivType && "Expected privatizable type!");
7471
7472 IRBuilder<NoFolder> IRB(IP->getParent(), IP);
7473 const DataLayout &DL = F.getDataLayout();
7474
7475 // Traverse the type, build GEPs and stores.
7476 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) {
7477 const StructLayout *PrivStructLayout = DL.getStructLayout(PrivStructType);
7478 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++) {
7479 Value *Ptr =
7480 constructPointer(&Base, PrivStructLayout->getElementOffset(u), IRB);
7481 new StoreInst(F.getArg(ArgNo + u), Ptr, IP);
7482 }
7483 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) {
7484 Type *PointeeTy = PrivArrayType->getElementType();
7485 uint64_t PointeeTySize = DL.getTypeStoreSize(PointeeTy);
7486 for (unsigned u = 0, e = PrivArrayType->getNumElements(); u < e; u++) {
7487 Value *Ptr = constructPointer(&Base, u * PointeeTySize, IRB);
7488 new StoreInst(F.getArg(ArgNo + u), Ptr, IP);
7489 }
7490 } else {
7491 new StoreInst(F.getArg(ArgNo), &Base, IP);
7492 }
7493 }
7494
7495 /// Extract values from \p Base according to the type \p PrivType at the
7496 /// call position \p ACS. The values are appended to \p ReplacementValues.
7497 void createReplacementValues(Align Alignment, Type *PrivType,
7499 SmallVectorImpl<Value *> &ReplacementValues) {
7500 assert(Base && "Expected base value!");
7501 assert(PrivType && "Expected privatizable type!");
7502 Instruction *IP = ACS.getInstruction();
7503
7504 IRBuilder<NoFolder> IRB(IP);
7505 const DataLayout &DL = IP->getDataLayout();
7506
7507 // Traverse the type, build GEPs and loads.
7508 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) {
7509 const StructLayout *PrivStructLayout = DL.getStructLayout(PrivStructType);
7510 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++) {
7511 Type *PointeeTy = PrivStructType->getElementType(u);
7512 Value *Ptr =
7513 constructPointer(Base, PrivStructLayout->getElementOffset(u), IRB);
7514 LoadInst *L = new LoadInst(PointeeTy, Ptr, "", IP->getIterator());
7515 L->setAlignment(Alignment);
7516 ReplacementValues.push_back(L);
7517 }
7518 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) {
7519 Type *PointeeTy = PrivArrayType->getElementType();
7520 uint64_t PointeeTySize = DL.getTypeStoreSize(PointeeTy);
7521 for (unsigned u = 0, e = PrivArrayType->getNumElements(); u < e; u++) {
7522 Value *Ptr = constructPointer(Base, u * PointeeTySize, IRB);
7523 LoadInst *L = new LoadInst(PointeeTy, Ptr, "", IP->getIterator());
7524 L->setAlignment(Alignment);
7525 ReplacementValues.push_back(L);
7526 }
7527 } else {
7528 LoadInst *L = new LoadInst(PrivType, Base, "", IP->getIterator());
7529 L->setAlignment(Alignment);
7530 ReplacementValues.push_back(L);
7531 }
7532 }
7533
7534 /// See AbstractAttribute::manifest(...)
7535 ChangeStatus manifest(Attributor &A) override {
7536 if (!PrivatizableType)
7537 return ChangeStatus::UNCHANGED;
7538 assert(*PrivatizableType && "Expected privatizable type!");
7539
7540 // Collect all tail calls in the function as we cannot allow new allocas to
7541 // escape into tail recursion.
7542 // TODO: Be smarter about new allocas escaping into tail calls.
7544 bool UsedAssumedInformation = false;
7545 if (!A.checkForAllInstructions(
7546 [&](Instruction &I) {
7547 CallInst &CI = cast<CallInst>(I);
7548 if (CI.isTailCall())
7549 TailCalls.push_back(&CI);
7550 return true;
7551 },
7552 *this, {Instruction::Call}, UsedAssumedInformation))
7553 return ChangeStatus::UNCHANGED;
7554
7555 Argument *Arg = getAssociatedArgument();
7556 // Query AAAlign attribute for alignment of associated argument to
7557 // determine the best alignment of loads.
7558 const auto *AlignAA =
7559 A.getAAFor<AAAlign>(*this, IRPosition::value(*Arg), DepClassTy::NONE);
7560
7561 // Callback to repair the associated function. A new alloca is placed at the
7562 // beginning and initialized with the values passed through arguments. The
7563 // new alloca replaces the use of the old pointer argument.
7566 Function &ReplacementFn, Function::arg_iterator ArgIt) {
7567 BasicBlock &EntryBB = ReplacementFn.getEntryBlock();
7569 const DataLayout &DL = IP->getDataLayout();
7570 unsigned AS = DL.getAllocaAddrSpace();
7571 Instruction *AI = new AllocaInst(*PrivatizableType, AS,
7572 Arg->getName() + ".priv", IP);
7573 createInitialization(*PrivatizableType, *AI, ReplacementFn,
7574 ArgIt->getArgNo(), IP);
7575
7576 if (AI->getType() != Arg->getType())
7577 AI = BitCastInst::CreatePointerBitCastOrAddrSpaceCast(
7578 AI, Arg->getType(), "", IP);
7579 Arg->replaceAllUsesWith(AI);
7580
7581 for (CallInst *CI : TailCalls)
7582 CI->setTailCall(false);
7583 };
7584
7585 // Callback to repair a call site of the associated function. The elements
7586 // of the privatizable type are loaded prior to the call and passed to the
7587 // new function version.
7590 AbstractCallSite ACS, SmallVectorImpl<Value *> &NewArgOperands) {
7591 // When no alignment is specified for the load instruction,
7592 // natural alignment is assumed.
7593 createReplacementValues(
7594 AlignAA ? AlignAA->getAssumedAlign() : Align(0),
7595 *PrivatizableType, ACS,
7596 ACS.getCallArgOperand(ARI.getReplacedArg().getArgNo()),
7597 NewArgOperands);
7598 };
7599
7600 // Collect the types that will replace the privatizable type in the function
7601 // signature.
7602 SmallVector<Type *, 16> ReplacementTypes;
7603 identifyReplacementTypes(*PrivatizableType, ReplacementTypes);
7604
7605 // Register a rewrite of the argument.
7606 if (A.registerFunctionSignatureRewrite(*Arg, ReplacementTypes,
7607 std::move(FnRepairCB),
7608 std::move(ACSRepairCB)))
7609 return ChangeStatus::CHANGED;
7610 return ChangeStatus::UNCHANGED;
7611 }
7612
7613 /// See AbstractAttribute::trackStatistics()
7614 void trackStatistics() const override {
7615 STATS_DECLTRACK_ARG_ATTR(privatizable_ptr);
7616 }
7617};
7618
7619struct AAPrivatizablePtrFloating : public AAPrivatizablePtrImpl {
7620 AAPrivatizablePtrFloating(const IRPosition &IRP, Attributor &A)
7621 : AAPrivatizablePtrImpl(IRP, A) {}
7622
7623 /// See AbstractAttribute::initialize(...).
7624 void initialize(Attributor &A) override {
7625 // TODO: We can privatize more than arguments.
7626 indicatePessimisticFixpoint();
7627 }
7628
7629 ChangeStatus updateImpl(Attributor &A) override {
7630 llvm_unreachable("AAPrivatizablePtr(Floating|Returned|CallSiteReturned)::"
7631 "updateImpl will not be called");
7632 }
7633
7634 /// See AAPrivatizablePtrImpl::identifyPrivatizableType(...)
7635 std::optional<Type *> identifyPrivatizableType(Attributor &A) override {
7636 Value *Obj = getUnderlyingObject(&getAssociatedValue());
7637 if (!Obj) {
7638 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] No underlying object found!\n");
7639 return nullptr;
7640 }
7641
7642 if (auto *AI = dyn_cast<AllocaInst>(Obj))
7643 if (auto *CI = dyn_cast<ConstantInt>(AI->getArraySize()))
7644 if (CI->isOne())
7645 return AI->getAllocatedType();
7646 if (auto *Arg = dyn_cast<Argument>(Obj)) {
7647 auto *PrivArgAA = A.getAAFor<AAPrivatizablePtr>(
7648 *this, IRPosition::argument(*Arg), DepClassTy::REQUIRED);
7649 if (PrivArgAA && PrivArgAA->isAssumedPrivatizablePtr())
7650 return PrivArgAA->getPrivatizableType();
7651 }
7652
7653 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Underlying object neither valid "
7654 "alloca nor privatizable argument: "
7655 << *Obj << "!\n");
7656 return nullptr;
7657 }
7658
7659 /// See AbstractAttribute::trackStatistics()
7660 void trackStatistics() const override {
7661 STATS_DECLTRACK_FLOATING_ATTR(privatizable_ptr);
7662 }
7663};
7664
7665struct AAPrivatizablePtrCallSiteArgument final
7666 : public AAPrivatizablePtrFloating {
7667 AAPrivatizablePtrCallSiteArgument(const IRPosition &IRP, Attributor &A)
7668 : AAPrivatizablePtrFloating(IRP, A) {}
7669
7670 /// See AbstractAttribute::initialize(...).
7671 void initialize(Attributor &A) override {
7672 if (A.hasAttr(getIRPosition(), Attribute::ByVal))
7673 indicateOptimisticFixpoint();
7674 }
7675
7676 /// See AbstractAttribute::updateImpl(...).
7677 ChangeStatus updateImpl(Attributor &A) override {
7678 PrivatizableType = identifyPrivatizableType(A);
7679 if (!PrivatizableType)
7680 return ChangeStatus::UNCHANGED;
7681 if (!*PrivatizableType)
7682 return indicatePessimisticFixpoint();
7683
7684 const IRPosition &IRP = getIRPosition();
7685 bool IsKnownNoCapture;
7686 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::NoCapture>(
7687 A, this, IRP, DepClassTy::REQUIRED, IsKnownNoCapture);
7688 if (!IsAssumedNoCapture) {
7689 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer might be captured!\n");
7690 return indicatePessimisticFixpoint();
7691 }
7692
7693 bool IsKnownNoAlias;
7694 if (!AA::hasAssumedIRAttr<Attribute::NoAlias>(
7695 A, this, IRP, DepClassTy::REQUIRED, IsKnownNoAlias)) {
7696 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer might alias!\n");
7697 return indicatePessimisticFixpoint();
7698 }
7699
7700 bool IsKnown;
7701 if (!AA::isAssumedReadOnly(A, IRP, *this, IsKnown)) {
7702 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer is written!\n");
7703 return indicatePessimisticFixpoint();
7704 }
7705
7706 return ChangeStatus::UNCHANGED;
7707 }
7708
7709 /// See AbstractAttribute::trackStatistics()
7710 void trackStatistics() const override {
7711 STATS_DECLTRACK_CSARG_ATTR(privatizable_ptr);
7712 }
7713};
7714
7715struct AAPrivatizablePtrCallSiteReturned final
7716 : public AAPrivatizablePtrFloating {
7717 AAPrivatizablePtrCallSiteReturned(const IRPosition &IRP, Attributor &A)
7718 : AAPrivatizablePtrFloating(IRP, A) {}
7719
7720 /// See AbstractAttribute::initialize(...).
7721 void initialize(Attributor &A) override {
7722 // TODO: We can privatize more than arguments.
7723 indicatePessimisticFixpoint();
7724 }
7725
7726 /// See AbstractAttribute::trackStatistics()
7727 void trackStatistics() const override {
7728 STATS_DECLTRACK_CSRET_ATTR(privatizable_ptr);
7729 }
7730};
7731
7732struct AAPrivatizablePtrReturned final : public AAPrivatizablePtrFloating {
7733 AAPrivatizablePtrReturned(const IRPosition &IRP, Attributor &A)
7734 : AAPrivatizablePtrFloating(IRP, A) {}
7735
7736 /// See AbstractAttribute::initialize(...).
7737 void initialize(Attributor &A) override {
7738 // TODO: We can privatize more than arguments.
7739 indicatePessimisticFixpoint();
7740 }
7741
7742 /// See AbstractAttribute::trackStatistics()
7743 void trackStatistics() const override {
7744 STATS_DECLTRACK_FNRET_ATTR(privatizable_ptr);
7745 }
7746};
7747} // namespace
7748
7749/// -------------------- Memory Behavior Attributes ----------------------------
7750/// Includes read-none, read-only, and write-only.
7751/// ----------------------------------------------------------------------------
7752namespace {
7753struct AAMemoryBehaviorImpl : public AAMemoryBehavior {
7754 AAMemoryBehaviorImpl(const IRPosition &IRP, Attributor &A)
7755 : AAMemoryBehavior(IRP, A) {}
7756
7757 /// See AbstractAttribute::initialize(...).
7758 void initialize(Attributor &A) override {
7759 intersectAssumedBits(BEST_STATE);
7760 getKnownStateFromValue(A, getIRPosition(), getState());
7761 AAMemoryBehavior::initialize(A);
7762 }
7763
7764 /// Return the memory behavior information encoded in the IR for \p IRP.
7765 static void getKnownStateFromValue(Attributor &A, const IRPosition &IRP,
7766 BitIntegerState &State,
7767 bool IgnoreSubsumingPositions = false) {
7769 A.getAttrs(IRP, AttrKinds, Attrs, IgnoreSubsumingPositions);
7770 for (const Attribute &Attr : Attrs) {
7771 switch (Attr.getKindAsEnum()) {
7772 case Attribute::ReadNone:
7773 State.addKnownBits(NO_ACCESSES);
7774 break;
7775 case Attribute::ReadOnly:
7776 State.addKnownBits(NO_WRITES);
7777 break;
7778 case Attribute::WriteOnly:
7779 State.addKnownBits(NO_READS);
7780 break;
7781 default:
7782 llvm_unreachable("Unexpected attribute!");
7783 }
7784 }
7785
7786 if (auto *I = dyn_cast<Instruction>(&IRP.getAnchorValue())) {
7787 if (!I->mayReadFromMemory())
7788 State.addKnownBits(NO_READS);
7789 if (!I->mayWriteToMemory())
7790 State.addKnownBits(NO_WRITES);
7791 }
7792 }
7793
7794 /// See AbstractAttribute::getDeducedAttributes(...).
7795 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
7796 SmallVectorImpl<Attribute> &Attrs) const override {
7797 assert(Attrs.size() == 0);
7798 if (isAssumedReadNone())
7799 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadNone));
7800 else if (isAssumedReadOnly())
7801 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadOnly));
7802 else if (isAssumedWriteOnly())
7803 Attrs.push_back(Attribute::get(Ctx, Attribute::WriteOnly));
7804 assert(Attrs.size() <= 1);
7805 }
7806
7807 /// See AbstractAttribute::manifest(...).
7808 ChangeStatus manifest(Attributor &A) override {
7809 const IRPosition &IRP = getIRPosition();
7810
7811 if (A.hasAttr(IRP, Attribute::ReadNone,
7812 /* IgnoreSubsumingPositions */ true))
7813 return ChangeStatus::UNCHANGED;
7814
7815 // Check if we would improve the existing attributes first.
7816 SmallVector<Attribute, 4> DeducedAttrs;
7817 getDeducedAttributes(A, IRP.getAnchorValue().getContext(), DeducedAttrs);
7818 if (llvm::all_of(DeducedAttrs, [&](const Attribute &Attr) {
7819 return A.hasAttr(IRP, Attr.getKindAsEnum(),
7820 /* IgnoreSubsumingPositions */ true);
7821 }))
7822 return ChangeStatus::UNCHANGED;
7823
7824 // Clear existing attributes.
7825 A.removeAttrs(IRP, AttrKinds);
7826 // Clear conflicting writable attribute.
7827 if (isAssumedReadOnly())
7828 A.removeAttrs(IRP, Attribute::Writable);
7829
7830 // Use the generic manifest method.
7831 return IRAttribute::manifest(A);
7832 }
7833
7834 /// See AbstractState::getAsStr().
7835 const std::string getAsStr(Attributor *A) const override {
7836 if (isAssumedReadNone())
7837 return "readnone";
7838 if (isAssumedReadOnly())
7839 return "readonly";
7840 if (isAssumedWriteOnly())
7841 return "writeonly";
7842 return "may-read/write";
7843 }
7844
7845 /// The set of IR attributes AAMemoryBehavior deals with.
7846 static const Attribute::AttrKind AttrKinds[3];
7847};
7848
7849const Attribute::AttrKind AAMemoryBehaviorImpl::AttrKinds[] = {
7850 Attribute::ReadNone, Attribute::ReadOnly, Attribute::WriteOnly};
7851
7852/// Memory behavior attribute for a floating value.
7853struct AAMemoryBehaviorFloating : AAMemoryBehaviorImpl {
7854 AAMemoryBehaviorFloating(const IRPosition &IRP, Attributor &A)
7855 : AAMemoryBehaviorImpl(IRP, A) {}
7856
7857 /// See AbstractAttribute::updateImpl(...).
7858 ChangeStatus updateImpl(Attributor &A) override;
7859
7860 /// See AbstractAttribute::trackStatistics()
7861 void trackStatistics() const override {
7862 if (isAssumedReadNone())
7864 else if (isAssumedReadOnly())
7866 else if (isAssumedWriteOnly())
7868 }
7869
7870private:
7871 /// Return true if users of \p UserI might access the underlying
7872 /// variable/location described by \p U and should therefore be analyzed.
7873 bool followUsersOfUseIn(Attributor &A, const Use &U,
7874 const Instruction *UserI);
7875
7876 /// Update the state according to the effect of use \p U in \p UserI.
7877 void analyzeUseIn(Attributor &A, const Use &U, const Instruction *UserI);
7878};
7879
7880/// Memory behavior attribute for function argument.
7881struct AAMemoryBehaviorArgument : AAMemoryBehaviorFloating {
7882 AAMemoryBehaviorArgument(const IRPosition &IRP, Attributor &A)
7883 : AAMemoryBehaviorFloating(IRP, A) {}
7884
7885 /// See AbstractAttribute::initialize(...).
7886 void initialize(Attributor &A) override {
7887 intersectAssumedBits(BEST_STATE);
7888 const IRPosition &IRP = getIRPosition();
7889 // TODO: Make IgnoreSubsumingPositions a property of an IRAttribute so we
7890 // can query it when we use has/getAttr. That would allow us to reuse the
7891 // initialize of the base class here.
7892 bool HasByVal = A.hasAttr(IRP, {Attribute::ByVal},
7893 /* IgnoreSubsumingPositions */ true);
7894 getKnownStateFromValue(A, IRP, getState(),
7895 /* IgnoreSubsumingPositions */ HasByVal);
7896 }
7897
7898 ChangeStatus manifest(Attributor &A) override {
7899 // TODO: Pointer arguments are not supported on vectors of pointers yet.
7900 if (!getAssociatedValue().getType()->isPointerTy())
7901 return ChangeStatus::UNCHANGED;
7902
7903 // TODO: From readattrs.ll: "inalloca parameters are always
7904 // considered written"
7905 if (A.hasAttr(getIRPosition(),
7906 {Attribute::InAlloca, Attribute::Preallocated})) {
7907 removeKnownBits(NO_WRITES);
7908 removeAssumedBits(NO_WRITES);
7909 }
7910 A.removeAttrs(getIRPosition(), AttrKinds);
7911 return AAMemoryBehaviorFloating::manifest(A);
7912 }
7913
7914 /// See AbstractAttribute::trackStatistics()
7915 void trackStatistics() const override {
7916 if (isAssumedReadNone())
7917 STATS_DECLTRACK_ARG_ATTR(readnone)
7918 else if (isAssumedReadOnly())
7919 STATS_DECLTRACK_ARG_ATTR(readonly)
7920 else if (isAssumedWriteOnly())
7921 STATS_DECLTRACK_ARG_ATTR(writeonly)
7922 }
7923};
7924
7925struct AAMemoryBehaviorCallSiteArgument final : AAMemoryBehaviorArgument {
7926 AAMemoryBehaviorCallSiteArgument(const IRPosition &IRP, Attributor &A)
7927 : AAMemoryBehaviorArgument(IRP, A) {}
7928
7929 /// See AbstractAttribute::initialize(...).
7930 void initialize(Attributor &A) override {
7931 // If we don't have an associated attribute this is either a variadic call
7932 // or an indirect call, either way, nothing to do here.
7933 Argument *Arg = getAssociatedArgument();
7934 if (!Arg) {
7935 indicatePessimisticFixpoint();
7936 return;
7937 }
7938 if (Arg->hasByValAttr()) {
7939 addKnownBits(NO_WRITES);
7940 removeKnownBits(NO_READS);
7941 removeAssumedBits(NO_READS);
7942 }
7943 AAMemoryBehaviorArgument::initialize(A);
7944 if (getAssociatedFunction()->isDeclaration())
7945 indicatePessimisticFixpoint();
7946 }
7947
7948 /// See AbstractAttribute::updateImpl(...).
7949 ChangeStatus updateImpl(Attributor &A) override {
7950 // TODO: Once we have call site specific value information we can provide
7951 // call site specific liveness liveness information and then it makes
7952 // sense to specialize attributes for call sites arguments instead of
7953 // redirecting requests to the callee argument.
7954 Argument *Arg = getAssociatedArgument();
7955 const IRPosition &ArgPos = IRPosition::argument(*Arg);
7956 auto *ArgAA =
7957 A.getAAFor<AAMemoryBehavior>(*this, ArgPos, DepClassTy::REQUIRED);
7958 if (!ArgAA)
7959 return indicatePessimisticFixpoint();
7960 return clampStateAndIndicateChange(getState(), ArgAA->getState());
7961 }
7962
7963 /// See AbstractAttribute::trackStatistics()
7964 void trackStatistics() const override {
7965 if (isAssumedReadNone())
7967 else if (isAssumedReadOnly())
7969 else if (isAssumedWriteOnly())
7971 }
7972};
7973
7974/// Memory behavior attribute for a call site return position.
7975struct AAMemoryBehaviorCallSiteReturned final : AAMemoryBehaviorFloating {
7976 AAMemoryBehaviorCallSiteReturned(const IRPosition &IRP, Attributor &A)
7977 : AAMemoryBehaviorFloating(IRP, A) {}
7978
7979 /// See AbstractAttribute::initialize(...).
7980 void initialize(Attributor &A) override {
7981 AAMemoryBehaviorImpl::initialize(A);
7982 }
7983 /// See AbstractAttribute::manifest(...).
7984 ChangeStatus manifest(Attributor &A) override {
7985 // We do not annotate returned values.
7986 return ChangeStatus::UNCHANGED;
7987 }
7988
7989 /// See AbstractAttribute::trackStatistics()
7990 void trackStatistics() const override {}
7991};
7992
7993/// An AA to represent the memory behavior function attributes.
7994struct AAMemoryBehaviorFunction final : public AAMemoryBehaviorImpl {
7995 AAMemoryBehaviorFunction(const IRPosition &IRP, Attributor &A)
7996 : AAMemoryBehaviorImpl(IRP, A) {}
7997
7998 /// See AbstractAttribute::updateImpl(Attributor &A).
7999 ChangeStatus updateImpl(Attributor &A) override;
8000
8001 /// See AbstractAttribute::manifest(...).
8002 ChangeStatus manifest(Attributor &A) override {
8003 // TODO: It would be better to merge this with AAMemoryLocation, so that
8004 // we could determine read/write per location. This would also have the
8005 // benefit of only one place trying to manifest the memory attribute.
8006 Function &F = cast<Function>(getAnchorValue());
8008 if (isAssumedReadNone())
8009 ME = MemoryEffects::none();
8010 else if (isAssumedReadOnly())
8012 else if (isAssumedWriteOnly())
8014
8015 A.removeAttrs(getIRPosition(), AttrKinds);
8016 // Clear conflicting writable attribute.
8017 if (ME.onlyReadsMemory())
8018 for (Argument &Arg : F.args())
8019 A.removeAttrs(IRPosition::argument(Arg), Attribute::Writable);
8020 return A.manifestAttrs(getIRPosition(),
8021 Attribute::getWithMemoryEffects(F.getContext(), ME));
8022 }
8023
8024 /// See AbstractAttribute::trackStatistics()
8025 void trackStatistics() const override {
8026 if (isAssumedReadNone())
8027 STATS_DECLTRACK_FN_ATTR(readnone)
8028 else if (isAssumedReadOnly())
8029 STATS_DECLTRACK_FN_ATTR(readonly)
8030 else if (isAssumedWriteOnly())
8031 STATS_DECLTRACK_FN_ATTR(writeonly)
8032 }
8033};
8034
8035/// AAMemoryBehavior attribute for call sites.
8036struct AAMemoryBehaviorCallSite final
8037 : AACalleeToCallSite<AAMemoryBehavior, AAMemoryBehaviorImpl> {
8038 AAMemoryBehaviorCallSite(const IRPosition &IRP, Attributor &A)
8039 : AACalleeToCallSite<AAMemoryBehavior, AAMemoryBehaviorImpl>(IRP, A) {}
8040
8041 /// See AbstractAttribute::manifest(...).
8042 ChangeStatus manifest(Attributor &A) override {
8043 // TODO: Deduplicate this with AAMemoryBehaviorFunction.
8044 CallBase &CB = cast<CallBase>(getAnchorValue());
8046 if (isAssumedReadNone())
8047 ME = MemoryEffects::none();
8048 else if (isAssumedReadOnly())
8050 else if (isAssumedWriteOnly())
8052
8053 A.removeAttrs(getIRPosition(), AttrKinds);
8054 // Clear conflicting writable attribute.
8055 if (ME.onlyReadsMemory())
8056 for (Use &U : CB.args())
8057 A.removeAttrs(IRPosition::callsite_argument(CB, U.getOperandNo()),
8058 Attribute::Writable);
8059 return A.manifestAttrs(
8060 getIRPosition(), Attribute::getWithMemoryEffects(CB.getContext(), ME));
8061 }
8062
8063 /// See AbstractAttribute::trackStatistics()
8064 void trackStatistics() const override {
8065 if (isAssumedReadNone())
8066 STATS_DECLTRACK_CS_ATTR(readnone)
8067 else if (isAssumedReadOnly())
8068 STATS_DECLTRACK_CS_ATTR(readonly)
8069 else if (isAssumedWriteOnly())
8070 STATS_DECLTRACK_CS_ATTR(writeonly)
8071 }
8072};
8073
8074ChangeStatus AAMemoryBehaviorFunction::updateImpl(Attributor &A) {
8075
8076 // The current assumed state used to determine a change.
8077 auto AssumedState = getAssumed();
8078
8079 auto CheckRWInst = [&](Instruction &I) {
8080 // If the instruction has an own memory behavior state, use it to restrict
8081 // the local state. No further analysis is required as the other memory
8082 // state is as optimistic as it gets.
8083 if (const auto *CB = dyn_cast<CallBase>(&I)) {
8084 const auto *MemBehaviorAA = A.getAAFor<AAMemoryBehavior>(
8086 if (MemBehaviorAA) {
8087 intersectAssumedBits(MemBehaviorAA->getAssumed());
8088 return !isAtFixpoint();
8089 }
8090 }
8091
8092 // Remove access kind modifiers if necessary.
8093 if (I.mayReadFromMemory())
8094 removeAssumedBits(NO_READS);
8095 if (I.mayWriteToMemory())
8096 removeAssumedBits(NO_WRITES);
8097 return !isAtFixpoint();
8098 };
8099
8100 bool UsedAssumedInformation = false;
8101 if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this,
8102 UsedAssumedInformation))
8103 return indicatePessimisticFixpoint();
8104
8105 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
8107}
8108
8109ChangeStatus AAMemoryBehaviorFloating::updateImpl(Attributor &A) {
8110
8111 const IRPosition &IRP = getIRPosition();
8112 const IRPosition &FnPos = IRPosition::function_scope(IRP);
8113 AAMemoryBehavior::StateType &S = getState();
8114
8115 // First, check the function scope. We take the known information and we avoid
8116 // work if the assumed information implies the current assumed information for
8117 // this attribute. This is a valid for all but byval arguments.
8118 Argument *Arg = IRP.getAssociatedArgument();
8119 AAMemoryBehavior::base_t FnMemAssumedState =
8121 if (!Arg || !Arg->hasByValAttr()) {
8122 const auto *FnMemAA =
8123 A.getAAFor<AAMemoryBehavior>(*this, FnPos, DepClassTy::OPTIONAL);
8124 if (FnMemAA) {
8125 FnMemAssumedState = FnMemAA->getAssumed();
8126 S.addKnownBits(FnMemAA->getKnown());
8127 if ((S.getAssumed() & FnMemAA->getAssumed()) == S.getAssumed())
8129 }
8130 }
8131
8132 // The current assumed state used to determine a change.
8133 auto AssumedState = S.getAssumed();
8134
8135 // Make sure the value is not captured (except through "return"), if
8136 // it is, any information derived would be irrelevant anyway as we cannot
8137 // check the potential aliases introduced by the capture. However, no need
8138 // to fall back to anythign less optimistic than the function state.
8139 bool IsKnownNoCapture;
8140 const AANoCapture *ArgNoCaptureAA = nullptr;
8141 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::NoCapture>(
8142 A, this, IRP, DepClassTy::OPTIONAL, IsKnownNoCapture, false,
8143 &ArgNoCaptureAA);
8144
8145 if (!IsAssumedNoCapture &&
8146 (!ArgNoCaptureAA || !ArgNoCaptureAA->isAssumedNoCaptureMaybeReturned())) {
8147 S.intersectAssumedBits(FnMemAssumedState);
8148 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
8150 }
8151
8152 // Visit and expand uses until all are analyzed or a fixpoint is reached.
8153 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
8154 Instruction *UserI = cast<Instruction>(U.getUser());
8155 LLVM_DEBUG(dbgs() << "[AAMemoryBehavior] Use: " << *U << " in " << *UserI
8156 << " \n");
8157
8158 // Droppable users, e.g., llvm::assume does not actually perform any action.
8159 if (UserI->isDroppable())
8160 return true;
8161
8162 // Check if the users of UserI should also be visited.
8163 Follow = followUsersOfUseIn(A, U, UserI);
8164
8165 // If UserI might touch memory we analyze the use in detail.
8166 if (UserI->mayReadOrWriteMemory())
8167 analyzeUseIn(A, U, UserI);
8168
8169 return !isAtFixpoint();
8170 };
8171
8172 if (!A.checkForAllUses(UsePred, *this, getAssociatedValue()))
8173 return indicatePessimisticFixpoint();
8174
8175 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
8177}
8178
8179bool AAMemoryBehaviorFloating::followUsersOfUseIn(Attributor &A, const Use &U,
8180 const Instruction *UserI) {
8181 // The loaded value is unrelated to the pointer argument, no need to
8182 // follow the users of the load.
8183 if (isa<LoadInst>(UserI) || isa<ReturnInst>(UserI))
8184 return false;
8185
8186 // By default we follow all uses assuming UserI might leak information on U,
8187 // we have special handling for call sites operands though.
8188 const auto *CB = dyn_cast<CallBase>(UserI);
8189 if (!CB || !CB->isArgOperand(&U))
8190 return true;
8191
8192 // If the use is a call argument known not to be captured, the users of
8193 // the call do not need to be visited because they have to be unrelated to
8194 // the input. Note that this check is not trivial even though we disallow
8195 // general capturing of the underlying argument. The reason is that the
8196 // call might the argument "through return", which we allow and for which we
8197 // need to check call users.
8198 if (U.get()->getType()->isPointerTy()) {
8199 unsigned ArgNo = CB->getArgOperandNo(&U);
8200 bool IsKnownNoCapture;
8201 return !AA::hasAssumedIRAttr<Attribute::NoCapture>(
8202 A, this, IRPosition::callsite_argument(*CB, ArgNo),
8203 DepClassTy::OPTIONAL, IsKnownNoCapture);
8204 }
8205
8206 return true;
8207}
8208
8209void AAMemoryBehaviorFloating::analyzeUseIn(Attributor &A, const Use &U,
8210 const Instruction *UserI) {
8211 assert(UserI->mayReadOrWriteMemory());
8212
8213 switch (UserI->getOpcode()) {
8214 default:
8215 // TODO: Handle all atomics and other side-effect operations we know of.
8216 break;
8217 case Instruction::Load:
8218 // Loads cause the NO_READS property to disappear.
8219 removeAssumedBits(NO_READS);
8220 return;
8221
8222 case Instruction::Store:
8223 // Stores cause the NO_WRITES property to disappear if the use is the
8224 // pointer operand. Note that while capturing was taken care of somewhere
8225 // else we need to deal with stores of the value that is not looked through.
8226 if (cast<StoreInst>(UserI)->getPointerOperand() == U.get())
8227 removeAssumedBits(NO_WRITES);
8228 else
8229 indicatePessimisticFixpoint();
8230 return;
8231
8232 case Instruction::Call:
8233 case Instruction::CallBr:
8234 case Instruction::Invoke: {
8235 // For call sites we look at the argument memory behavior attribute (this
8236 // could be recursive!) in order to restrict our own state.
8237 const auto *CB = cast<CallBase>(UserI);
8238
8239 // Give up on operand bundles.
8240 if (CB->isBundleOperand(&U)) {
8241 indicatePessimisticFixpoint();
8242 return;
8243 }
8244
8245 // Calling a function does read the function pointer, maybe write it if the
8246 // function is self-modifying.
8247 if (CB->isCallee(&U)) {
8248 removeAssumedBits(NO_READS);
8249 break;
8250 }
8251
8252 // Adjust the possible access behavior based on the information on the
8253 // argument.
8254 IRPosition Pos;
8255 if (U.get()->getType()->isPointerTy())
8257 else
8259 const auto *MemBehaviorAA =
8260 A.getAAFor<AAMemoryBehavior>(*this, Pos, DepClassTy::OPTIONAL);
8261 if (!MemBehaviorAA)
8262 break;
8263 // "assumed" has at most the same bits as the MemBehaviorAA assumed
8264 // and at least "known".
8265 intersectAssumedBits(MemBehaviorAA->getAssumed());
8266 return;
8267 }
8268 };
8269
8270 // Generally, look at the "may-properties" and adjust the assumed state if we
8271 // did not trigger special handling before.
8272 if (UserI->mayReadFromMemory())
8273 removeAssumedBits(NO_READS);
8274 if (UserI->mayWriteToMemory())
8275 removeAssumedBits(NO_WRITES);
8276}
8277} // namespace
8278
8279/// -------------------- Memory Locations Attributes ---------------------------
8280/// Includes read-none, argmemonly, inaccessiblememonly,
8281/// inaccessiblememorargmemonly
8282/// ----------------------------------------------------------------------------
8283
8286 if (0 == (MLK & AAMemoryLocation::NO_LOCATIONS))
8287 return "all memory";
8289 return "no memory";
8290 std::string S = "memory:";
8291 if (0 == (MLK & AAMemoryLocation::NO_LOCAL_MEM))
8292 S += "stack,";
8293 if (0 == (MLK & AAMemoryLocation::NO_CONST_MEM))
8294 S += "constant,";
8296 S += "internal global,";
8298 S += "external global,";
8299 if (0 == (MLK & AAMemoryLocation::NO_ARGUMENT_MEM))
8300 S += "argument,";
8302 S += "inaccessible,";
8303 if (0 == (MLK & AAMemoryLocation::NO_MALLOCED_MEM))
8304 S += "malloced,";
8305 if (0 == (MLK & AAMemoryLocation::NO_UNKOWN_MEM))
8306 S += "unknown,";
8307 S.pop_back();
8308 return S;
8309}
8310
8311namespace {
8312struct AAMemoryLocationImpl : public AAMemoryLocation {
8313
8314 AAMemoryLocationImpl(const IRPosition &IRP, Attributor &A)
8316 AccessKind2Accesses.fill(nullptr);
8317 }
8318
8319 ~AAMemoryLocationImpl() {
8320 // The AccessSets are allocated via a BumpPtrAllocator, we call
8321 // the destructor manually.
8322 for (AccessSet *AS : AccessKind2Accesses)
8323 if (AS)
8324 AS->~AccessSet();
8325 }
8326
8327 /// See AbstractAttribute::initialize(...).
8328 void initialize(Attributor &A) override {
8329 intersectAssumedBits(BEST_STATE);
8330 getKnownStateFromValue(A, getIRPosition(), getState());
8331 AAMemoryLocation::initialize(A);
8332 }
8333
8334 /// Return the memory behavior information encoded in the IR for \p IRP.
8335 static void getKnownStateFromValue(Attributor &A, const IRPosition &IRP,
8336 BitIntegerState &State,
8337 bool IgnoreSubsumingPositions = false) {
8338 // For internal functions we ignore `argmemonly` and
8339 // `inaccessiblememorargmemonly` as we might break it via interprocedural
8340 // constant propagation. It is unclear if this is the best way but it is
8341 // unlikely this will cause real performance problems. If we are deriving
8342 // attributes for the anchor function we even remove the attribute in
8343 // addition to ignoring it.
8344 // TODO: A better way to handle this would be to add ~NO_GLOBAL_MEM /
8345 // MemoryEffects::Other as a possible location.
8346 bool UseArgMemOnly = true;
8347 Function *AnchorFn = IRP.getAnchorScope();
8348 if (AnchorFn && A.isRunOn(*AnchorFn))
8349 UseArgMemOnly = !AnchorFn->hasLocalLinkage();
8350
8352 A.getAttrs(IRP, {Attribute::Memory}, Attrs, IgnoreSubsumingPositions);
8353 for (const Attribute &Attr : Attrs) {
8354 // TODO: We can map MemoryEffects to Attributor locations more precisely.
8355 MemoryEffects ME = Attr.getMemoryEffects();
8356 if (ME.doesNotAccessMemory()) {
8357 State.addKnownBits(NO_LOCAL_MEM | NO_CONST_MEM);
8358 continue;
8359 }
8360 if (ME.onlyAccessesInaccessibleMem()) {
8361 State.addKnownBits(inverseLocation(NO_INACCESSIBLE_MEM, true, true));
8362 continue;
8363 }
8364 if (ME.onlyAccessesArgPointees()) {
8365 if (UseArgMemOnly)
8366 State.addKnownBits(inverseLocation(NO_ARGUMENT_MEM, true, true));
8367 else {
8368 // Remove location information, only keep read/write info.
8369 ME = MemoryEffects(ME.getModRef());
8370 A.manifestAttrs(IRP,
8372 IRP.getAnchorValue().getContext(), ME),
8373 /*ForceReplace*/ true);
8374 }
8375 continue;
8376 }
8378 if (UseArgMemOnly)
8379 State.addKnownBits(inverseLocation(
8380 NO_INACCESSIBLE_MEM | NO_ARGUMENT_MEM, true, true));
8381 else {
8382 // Remove location information, only keep read/write info.
8383 ME = MemoryEffects(ME.getModRef());
8384 A.manifestAttrs(IRP,
8386 IRP.getAnchorValue().getContext(), ME),
8387 /*ForceReplace*/ true);
8388 }
8389 continue;
8390 }
8391 }
8392 }
8393
8394 /// See AbstractAttribute::getDeducedAttributes(...).
8395 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
8396 SmallVectorImpl<Attribute> &Attrs) const override {
8397 // TODO: We can map Attributor locations to MemoryEffects more precisely.
8398 assert(Attrs.size() == 0);
8399 if (getIRPosition().getPositionKind() == IRPosition::IRP_FUNCTION) {
8400 if (isAssumedReadNone())
8401 Attrs.push_back(
8403 else if (isAssumedInaccessibleMemOnly())
8406 else if (isAssumedArgMemOnly())
8407 Attrs.push_back(
8409 else if (isAssumedInaccessibleOrArgMemOnly())
8412 }
8413 assert(Attrs.size() <= 1);
8414 }
8415
8416 /// See AbstractAttribute::manifest(...).
8417 ChangeStatus manifest(Attributor &A) override {
8418 // TODO: If AAMemoryLocation and AAMemoryBehavior are merged, we could
8419 // provide per-location modref information here.
8420 const IRPosition &IRP = getIRPosition();
8421
8422 SmallVector<Attribute, 1> DeducedAttrs;
8423 getDeducedAttributes(A, IRP.getAnchorValue().getContext(), DeducedAttrs);
8424 if (DeducedAttrs.size() != 1)
8425 return ChangeStatus::UNCHANGED;
8426 MemoryEffects ME = DeducedAttrs[0].getMemoryEffects();
8427
8428 return A.manifestAttrs(IRP, Attribute::getWithMemoryEffects(
8429 IRP.getAnchorValue().getContext(), ME));
8430 }
8431
8432 /// See AAMemoryLocation::checkForAllAccessesToMemoryKind(...).
8433 bool checkForAllAccessesToMemoryKind(
8434 function_ref<bool(const Instruction *, const Value *, AccessKind,
8435 MemoryLocationsKind)>
8436 Pred,
8437 MemoryLocationsKind RequestedMLK) const override {
8438 if (!isValidState())
8439 return false;
8440
8441 MemoryLocationsKind AssumedMLK = getAssumedNotAccessedLocation();
8442 if (AssumedMLK == NO_LOCATIONS)
8443 return true;
8444
8445 unsigned Idx = 0;
8446 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS;
8447 CurMLK *= 2, ++Idx) {
8448 if (CurMLK & RequestedMLK)
8449 continue;
8450
8451 if (const AccessSet *Accesses = AccessKind2Accesses[Idx])
8452 for (const AccessInfo &AI : *Accesses)
8453 if (!Pred(AI.I, AI.Ptr, AI.Kind, CurMLK))
8454 return false;
8455 }
8456
8457 return true;
8458 }
8459
8460 ChangeStatus indicatePessimisticFixpoint() override {
8461 // If we give up and indicate a pessimistic fixpoint this instruction will
8462 // become an access for all potential access kinds:
8463 // TODO: Add pointers for argmemonly and globals to improve the results of
8464 // checkForAllAccessesToMemoryKind.
8465 bool Changed = false;
8466 MemoryLocationsKind KnownMLK = getKnown();
8467 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
8468 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS; CurMLK *= 2)
8469 if (!(CurMLK & KnownMLK))
8470 updateStateAndAccessesMap(getState(), CurMLK, I, nullptr, Changed,
8471 getAccessKindFromInst(I));
8472 return AAMemoryLocation::indicatePessimisticFixpoint();
8473 }
8474
8475protected:
8476 /// Helper struct to tie together an instruction that has a read or write
8477 /// effect with the pointer it accesses (if any).
8478 struct AccessInfo {
8479
8480 /// The instruction that caused the access.
8481 const Instruction *I;
8482
8483 /// The base pointer that is accessed, or null if unknown.
8484 const Value *Ptr;
8485
8486 /// The kind of access (read/write/read+write).
8488
8489 bool operator==(const AccessInfo &RHS) const {
8490 return I == RHS.I && Ptr == RHS.Ptr && Kind == RHS.Kind;
8491 }
8492 bool operator()(const AccessInfo &LHS, const AccessInfo &RHS) const {
8493 if (LHS.I != RHS.I)
8494 return LHS.I < RHS.I;
8495 if (LHS.Ptr != RHS.Ptr)
8496 return LHS.Ptr < RHS.Ptr;
8497 if (LHS.Kind != RHS.Kind)
8498 return LHS.Kind < RHS.Kind;
8499 return false;
8500 }
8501 };
8502
8503 /// Mapping from *single* memory location kinds, e.g., LOCAL_MEM with the
8504 /// value of NO_LOCAL_MEM, to the accesses encountered for this memory kind.
8505 using AccessSet = SmallSet<AccessInfo, 2, AccessInfo>;
8506 std::array<AccessSet *, llvm::CTLog2<VALID_STATE>()> AccessKind2Accesses;
8507
8508 /// Categorize the pointer arguments of CB that might access memory in
8509 /// AccessedLoc and update the state and access map accordingly.
8510 void
8511 categorizeArgumentPointerLocations(Attributor &A, CallBase &CB,
8512 AAMemoryLocation::StateType &AccessedLocs,
8513 bool &Changed);
8514
8515 /// Return the kind(s) of location that may be accessed by \p V.
8517 categorizeAccessedLocations(Attributor &A, Instruction &I, bool &Changed);
8518
8519 /// Return the access kind as determined by \p I.
8520 AccessKind getAccessKindFromInst(const Instruction *I) {
8521 AccessKind AK = READ_WRITE;
8522 if (I) {
8523 AK = I->mayReadFromMemory() ? READ : NONE;
8524 AK = AccessKind(AK | (I->mayWriteToMemory() ? WRITE : NONE));
8525 }
8526 return AK;
8527 }
8528
8529 /// Update the state \p State and the AccessKind2Accesses given that \p I is
8530 /// an access of kind \p AK to a \p MLK memory location with the access
8531 /// pointer \p Ptr.
8532 void updateStateAndAccessesMap(AAMemoryLocation::StateType &State,
8533 MemoryLocationsKind MLK, const Instruction *I,
8534 const Value *Ptr, bool &Changed,
8535 AccessKind AK = READ_WRITE) {
8536
8537 assert(isPowerOf2_32(MLK) && "Expected a single location set!");
8538 auto *&Accesses = AccessKind2Accesses[llvm::Log2_32(MLK)];
8539 if (!Accesses)
8540 Accesses = new (Allocator) AccessSet();
8541 Changed |= Accesses->insert(AccessInfo{I, Ptr, AK}).second;
8542 if (MLK == NO_UNKOWN_MEM)
8543 MLK = NO_LOCATIONS;
8544 State.removeAssumedBits(MLK);
8545 }
8546
8547 /// Determine the underlying locations kinds for \p Ptr, e.g., globals or
8548 /// arguments, and update the state and access map accordingly.
8549 void categorizePtrValue(Attributor &A, const Instruction &I, const Value &Ptr,
8550 AAMemoryLocation::StateType &State, bool &Changed,
8551 unsigned AccessAS = 0);
8552
8553 /// Used to allocate access sets.
8555};
8556
8557void AAMemoryLocationImpl::categorizePtrValue(
8558 Attributor &A, const Instruction &I, const Value &Ptr,
8559 AAMemoryLocation::StateType &State, bool &Changed, unsigned AccessAS) {
8560 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize pointer locations for "
8561 << Ptr << " ["
8562 << getMemoryLocationsAsStr(State.getAssumed()) << "]\n");
8563
8564 auto Pred = [&](Value &Obj) {
8565 unsigned ObjectAS = Obj.getType()->getPointerAddressSpace();
8566 // TODO: recognize the TBAA used for constant accesses.
8567 MemoryLocationsKind MLK = NO_LOCATIONS;
8568
8569 // Filter accesses to constant (GPU) memory if we have an AS at the access
8570 // site or the object is known to actually have the associated AS.
8571 if ((AccessAS == (unsigned)AA::GPUAddressSpace::Constant ||
8572 (ObjectAS == (unsigned)AA::GPUAddressSpace::Constant &&
8573 isIdentifiedObject(&Obj))) &&
8574 AA::isGPU(*I.getModule()))
8575 return true;
8576
8577 if (isa<UndefValue>(&Obj))
8578 return true;
8579 if (isa<Argument>(&Obj)) {
8580 // TODO: For now we do not treat byval arguments as local copies performed
8581 // on the call edge, though, we should. To make that happen we need to
8582 // teach various passes, e.g., DSE, about the copy effect of a byval. That
8583 // would also allow us to mark functions only accessing byval arguments as
8584 // readnone again, arguably their accesses have no effect outside of the
8585 // function, like accesses to allocas.
8586 MLK = NO_ARGUMENT_MEM;
8587 } else if (auto *GV = dyn_cast<GlobalValue>(&Obj)) {
8588 // Reading constant memory is not treated as a read "effect" by the
8589 // function attr pass so we won't neither. Constants defined by TBAA are
8590 // similar. (We know we do not write it because it is constant.)
8591 if (auto *GVar = dyn_cast<GlobalVariable>(GV))
8592 if (GVar->isConstant())
8593 return true;
8594
8595 if (GV->hasLocalLinkage())
8596 MLK = NO_GLOBAL_INTERNAL_MEM;
8597 else
8598 MLK = NO_GLOBAL_EXTERNAL_MEM;
8599 } else if (isa<ConstantPointerNull>(&Obj) &&
8600 (!NullPointerIsDefined(getAssociatedFunction(), AccessAS) ||
8601 !NullPointerIsDefined(getAssociatedFunction(), ObjectAS))) {
8602 return true;
8603 } else if (isa<AllocaInst>(&Obj)) {
8604 MLK = NO_LOCAL_MEM;
8605 } else if (const auto *CB = dyn_cast<CallBase>(&Obj)) {
8606 bool IsKnownNoAlias;
8607 if (AA::hasAssumedIRAttr<Attribute::NoAlias>(
8609 IsKnownNoAlias))
8610 MLK = NO_MALLOCED_MEM;
8611 else
8612 MLK = NO_UNKOWN_MEM;
8613 } else {
8614 MLK = NO_UNKOWN_MEM;
8615 }
8616
8617 assert(MLK != NO_LOCATIONS && "No location specified!");
8618 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Ptr value can be categorized: "
8619 << Obj << " -> " << getMemoryLocationsAsStr(MLK) << "\n");
8620 updateStateAndAccessesMap(State, MLK, &I, &Obj, Changed,
8621 getAccessKindFromInst(&I));
8622
8623 return true;
8624 };
8625
8626 const auto *AA = A.getAAFor<AAUnderlyingObjects>(
8628 if (!AA || !AA->forallUnderlyingObjects(Pred, AA::Intraprocedural)) {
8629 LLVM_DEBUG(
8630 dbgs() << "[AAMemoryLocation] Pointer locations not categorized\n");
8631 updateStateAndAccessesMap(State, NO_UNKOWN_MEM, &I, nullptr, Changed,
8632 getAccessKindFromInst(&I));
8633 return;
8634 }
8635
8636 LLVM_DEBUG(
8637 dbgs() << "[AAMemoryLocation] Accessed locations with pointer locations: "
8638 << getMemoryLocationsAsStr(State.getAssumed()) << "\n");
8639}
8640
8641void AAMemoryLocationImpl::categorizeArgumentPointerLocations(
8642 Attributor &A, CallBase &CB, AAMemoryLocation::StateType &AccessedLocs,
8643 bool &Changed) {
8644 for (unsigned ArgNo = 0, E = CB.arg_size(); ArgNo < E; ++ArgNo) {
8645
8646 // Skip non-pointer arguments.
8647 const Value *ArgOp = CB.getArgOperand(ArgNo);
8648 if (!ArgOp->getType()->isPtrOrPtrVectorTy())
8649 continue;
8650
8651 // Skip readnone arguments.
8652 const IRPosition &ArgOpIRP = IRPosition::callsite_argument(CB, ArgNo);
8653 const auto *ArgOpMemLocationAA =
8654 A.getAAFor<AAMemoryBehavior>(*this, ArgOpIRP, DepClassTy::OPTIONAL);
8655
8656 if (ArgOpMemLocationAA && ArgOpMemLocationAA->isAssumedReadNone())
8657 continue;
8658
8659 // Categorize potentially accessed pointer arguments as if there was an
8660 // access instruction with them as pointer.
8661 categorizePtrValue(A, CB, *ArgOp, AccessedLocs, Changed);
8662 }
8663}
8664
8666AAMemoryLocationImpl::categorizeAccessedLocations(Attributor &A, Instruction &I,
8667 bool &Changed) {
8668 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize accessed locations for "
8669 << I << "\n");
8670
8671 AAMemoryLocation::StateType AccessedLocs;
8672 AccessedLocs.intersectAssumedBits(NO_LOCATIONS);
8673
8674 if (auto *CB = dyn_cast<CallBase>(&I)) {
8675
8676 // First check if we assume any memory is access is visible.
8677 const auto *CBMemLocationAA = A.getAAFor<AAMemoryLocation>(
8679 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize call site: " << I
8680 << " [" << CBMemLocationAA << "]\n");
8681 if (!CBMemLocationAA) {
8682 updateStateAndAccessesMap(AccessedLocs, NO_UNKOWN_MEM, &I, nullptr,
8683 Changed, getAccessKindFromInst(&I));
8684 return NO_UNKOWN_MEM;
8685 }
8686
8687 if (CBMemLocationAA->isAssumedReadNone())
8688 return NO_LOCATIONS;
8689
8690 if (CBMemLocationAA->isAssumedInaccessibleMemOnly()) {
8691 updateStateAndAccessesMap(AccessedLocs, NO_INACCESSIBLE_MEM, &I, nullptr,
8692 Changed, getAccessKindFromInst(&I));
8693 return AccessedLocs.getAssumed();
8694 }
8695
8696 uint32_t CBAssumedNotAccessedLocs =
8697 CBMemLocationAA->getAssumedNotAccessedLocation();
8698
8699 // Set the argmemonly and global bit as we handle them separately below.
8700 uint32_t CBAssumedNotAccessedLocsNoArgMem =
8701 CBAssumedNotAccessedLocs | NO_ARGUMENT_MEM | NO_GLOBAL_MEM;
8702
8703 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS; CurMLK *= 2) {
8704 if (CBAssumedNotAccessedLocsNoArgMem & CurMLK)
8705 continue;
8706 updateStateAndAccessesMap(AccessedLocs, CurMLK, &I, nullptr, Changed,
8707 getAccessKindFromInst(&I));
8708 }
8709
8710 // Now handle global memory if it might be accessed. This is slightly tricky
8711 // as NO_GLOBAL_MEM has multiple bits set.
8712 bool HasGlobalAccesses = ((~CBAssumedNotAccessedLocs) & NO_GLOBAL_MEM);
8713 if (HasGlobalAccesses) {
8714 auto AccessPred = [&](const Instruction *, const Value *Ptr,
8715 AccessKind Kind, MemoryLocationsKind MLK) {
8716 updateStateAndAccessesMap(AccessedLocs, MLK, &I, Ptr, Changed,
8717 getAccessKindFromInst(&I));
8718 return true;
8719 };
8720 if (!CBMemLocationAA->checkForAllAccessesToMemoryKind(
8721 AccessPred, inverseLocation(NO_GLOBAL_MEM, false, false)))
8722 return AccessedLocs.getWorstState();
8723 }
8724
8725 LLVM_DEBUG(
8726 dbgs() << "[AAMemoryLocation] Accessed state before argument handling: "
8727 << getMemoryLocationsAsStr(AccessedLocs.getAssumed()) << "\n");
8728
8729 // Now handle argument memory if it might be accessed.
8730 bool HasArgAccesses = ((~CBAssumedNotAccessedLocs) & NO_ARGUMENT_MEM);
8731 if (HasArgAccesses)
8732 categorizeArgumentPointerLocations(A, *CB, AccessedLocs, Changed);
8733
8734 LLVM_DEBUG(
8735 dbgs() << "[AAMemoryLocation] Accessed state after argument handling: "
8736 << getMemoryLocationsAsStr(AccessedLocs.getAssumed()) << "\n");
8737
8738 return AccessedLocs.getAssumed();
8739 }
8740
8741 if (const Value *Ptr = getPointerOperand(&I, /* AllowVolatile */ true)) {
8742 LLVM_DEBUG(
8743 dbgs() << "[AAMemoryLocation] Categorize memory access with pointer: "
8744 << I << " [" << *Ptr << "]\n");
8745 categorizePtrValue(A, I, *Ptr, AccessedLocs, Changed,
8746 Ptr->getType()->getPointerAddressSpace());
8747 return AccessedLocs.getAssumed();
8748 }
8749
8750 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Failed to categorize instruction: "
8751 << I << "\n");
8752 updateStateAndAccessesMap(AccessedLocs, NO_UNKOWN_MEM, &I, nullptr, Changed,
8753 getAccessKindFromInst(&I));
8754 return AccessedLocs.getAssumed();
8755}
8756
8757/// An AA to represent the memory behavior function attributes.
8758struct AAMemoryLocationFunction final : public AAMemoryLocationImpl {
8759 AAMemoryLocationFunction(const IRPosition &IRP, Attributor &A)
8760 : AAMemoryLocationImpl(IRP, A) {}
8761
8762 /// See AbstractAttribute::updateImpl(Attributor &A).
8763 ChangeStatus updateImpl(Attributor &A) override {
8764
8765 const auto *MemBehaviorAA =
8766 A.getAAFor<AAMemoryBehavior>(*this, getIRPosition(), DepClassTy::NONE);
8767 if (MemBehaviorAA && MemBehaviorAA->isAssumedReadNone()) {
8768 if (MemBehaviorAA->isKnownReadNone())
8769 return indicateOptimisticFixpoint();
8771 "AAMemoryLocation was not read-none but AAMemoryBehavior was!");
8772 A.recordDependence(*MemBehaviorAA, *this, DepClassTy::OPTIONAL);
8773 return ChangeStatus::UNCHANGED;
8774 }
8775
8776 // The current assumed state used to determine a change.
8777 auto AssumedState = getAssumed();
8778 bool Changed = false;
8779
8780 auto CheckRWInst = [&](Instruction &I) {
8781 MemoryLocationsKind MLK = categorizeAccessedLocations(A, I, Changed);
8782 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Accessed locations for " << I
8783 << ": " << getMemoryLocationsAsStr(MLK) << "\n");
8784 removeAssumedBits(inverseLocation(MLK, false, false));
8785 // Stop once only the valid bit set in the *not assumed location*, thus
8786 // once we don't actually exclude any memory locations in the state.
8787 return getAssumedNotAccessedLocation() != VALID_STATE;
8788 };
8789
8790 bool UsedAssumedInformation = false;
8791 if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this,
8792 UsedAssumedInformation))
8793 return indicatePessimisticFixpoint();
8794
8795 Changed |= AssumedState != getAssumed();
8796 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
8797 }
8798
8799 /// See AbstractAttribute::trackStatistics()
8800 void trackStatistics() const override {
8801 if (isAssumedReadNone())
8802 STATS_DECLTRACK_FN_ATTR(readnone)
8803 else if (isAssumedArgMemOnly())
8804 STATS_DECLTRACK_FN_ATTR(argmemonly)
8805 else if (isAssumedInaccessibleMemOnly())
8806 STATS_DECLTRACK_FN_ATTR(inaccessiblememonly)
8807 else if (isAssumedInaccessibleOrArgMemOnly())
8808 STATS_DECLTRACK_FN_ATTR(inaccessiblememorargmemonly)
8809 }
8810};
8811
8812/// AAMemoryLocation attribute for call sites.
8813struct AAMemoryLocationCallSite final : AAMemoryLocationImpl {
8814 AAMemoryLocationCallSite(const IRPosition &IRP, Attributor &A)
8815 : AAMemoryLocationImpl(IRP, A) {}
8816
8817 /// See AbstractAttribute::updateImpl(...).
8818 ChangeStatus updateImpl(Attributor &A) override {
8819 // TODO: Once we have call site specific value information we can provide
8820 // call site specific liveness liveness information and then it makes
8821 // sense to specialize attributes for call sites arguments instead of
8822 // redirecting requests to the callee argument.
8823 Function *F = getAssociatedFunction();
8824 const IRPosition &FnPos = IRPosition::function(*F);
8825 auto *FnAA =
8826 A.getAAFor<AAMemoryLocation>(*this, FnPos, DepClassTy::REQUIRED);
8827 if (!FnAA)
8828 return indicatePessimisticFixpoint();
8829 bool Changed = false;
8830 auto AccessPred = [&](const Instruction *I, const Value *Ptr,
8831 AccessKind Kind, MemoryLocationsKind MLK) {
8832 updateStateAndAccessesMap(getState(), MLK, I, Ptr, Changed,
8833 getAccessKindFromInst(I));
8834 return true;
8835 };
8836 if (!FnAA->checkForAllAccessesToMemoryKind(AccessPred, ALL_LOCATIONS))
8837 return indicatePessimisticFixpoint();
8838 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
8839 }
8840
8841 /// See AbstractAttribute::trackStatistics()
8842 void trackStatistics() const override {
8843 if (isAssumedReadNone())
8844 STATS_DECLTRACK_CS_ATTR(readnone)
8845 }
8846};
8847} // namespace
8848
8849/// ------------------ denormal-fp-math Attribute -------------------------
8850
8851namespace {
8852struct AADenormalFPMathImpl : public AADenormalFPMath {
8853 AADenormalFPMathImpl(const IRPosition &IRP, Attributor &A)
8854 : AADenormalFPMath(IRP, A) {}
8855
8856 const std::string getAsStr(Attributor *A) const override {
8857 std::string Str("AADenormalFPMath[");
8859
8860 DenormalState Known = getKnown();
8861 if (Known.Mode.isValid())
8862 OS << "denormal-fp-math=" << Known.Mode;
8863 else
8864 OS << "invalid";
8865
8866 if (Known.ModeF32.isValid())
8867 OS << " denormal-fp-math-f32=" << Known.ModeF32;
8868 OS << ']';
8869 return OS.str();
8870 }
8871};
8872
8873struct AADenormalFPMathFunction final : AADenormalFPMathImpl {
8874 AADenormalFPMathFunction(const IRPosition &IRP, Attributor &A)
8875 : AADenormalFPMathImpl(IRP, A) {}
8876
8877 void initialize(Attributor &A) override {
8878 const Function *F = getAnchorScope();
8879 DenormalMode Mode = F->getDenormalModeRaw();
8880 DenormalMode ModeF32 = F->getDenormalModeF32Raw();
8881
8882 // TODO: Handling this here prevents handling the case where a callee has a
8883 // fixed denormal-fp-math with dynamic denormal-fp-math-f32, but called from
8884 // a function with a fully fixed mode.
8885 if (ModeF32 == DenormalMode::getInvalid())
8886 ModeF32 = Mode;
8887 Known = DenormalState{Mode, ModeF32};
8888 if (isModeFixed())
8889 indicateFixpoint();
8890 }
8891
8892 ChangeStatus updateImpl(Attributor &A) override {
8893 ChangeStatus Change = ChangeStatus::UNCHANGED;
8894
8895 auto CheckCallSite = [=, &Change, &A](AbstractCallSite CS) {
8896 Function *Caller = CS.getInstruction()->getFunction();
8897 LLVM_DEBUG(dbgs() << "[AADenormalFPMath] Call " << Caller->getName()
8898 << "->" << getAssociatedFunction()->getName() << '\n');
8899
8900 const auto *CallerInfo = A.getAAFor<AADenormalFPMath>(
8901 *this, IRPosition::function(*Caller), DepClassTy::REQUIRED);
8902 if (!CallerInfo)
8903 return false;
8904
8905 Change = Change | clampStateAndIndicateChange(this->getState(),
8906 CallerInfo->getState());
8907 return true;
8908 };
8909
8910 bool AllCallSitesKnown = true;
8911 if (!A.checkForAllCallSites(CheckCallSite, *this, true, AllCallSitesKnown))
8912 return indicatePessimisticFixpoint();
8913
8914 if (Change == ChangeStatus::CHANGED && isModeFixed())
8915 indicateFixpoint();
8916 return Change;
8917 }
8918
8919 ChangeStatus manifest(Attributor &A) override {
8920 LLVMContext &Ctx = getAssociatedFunction()->getContext();
8921
8922 SmallVector<Attribute, 2> AttrToAdd;
8923 SmallVector<StringRef, 2> AttrToRemove;
8924 if (Known.Mode == DenormalMode::getDefault()) {
8925 AttrToRemove.push_back("denormal-fp-math");
8926 } else {
8927 AttrToAdd.push_back(
8928 Attribute::get(Ctx, "denormal-fp-math", Known.Mode.str()));
8929 }
8930
8931 if (Known.ModeF32 != Known.Mode) {
8932 AttrToAdd.push_back(
8933 Attribute::get(Ctx, "denormal-fp-math-f32", Known.ModeF32.str()));
8934 } else {
8935 AttrToRemove.push_back("denormal-fp-math-f32");
8936 }
8937
8938 auto &IRP = getIRPosition();
8939
8940 // TODO: There should be a combined add and remove API.
8941 return A.removeAttrs(IRP, AttrToRemove) |
8942 A.manifestAttrs(IRP, AttrToAdd, /*ForceReplace=*/true);
8943 }
8944
8945 void trackStatistics() const override {
8946 STATS_DECLTRACK_FN_ATTR(denormal_fp_math)
8947 }
8948};
8949} // namespace
8950
8951/// ------------------ Value Constant Range Attribute -------------------------
8952
8953namespace {
8954struct AAValueConstantRangeImpl : AAValueConstantRange {
8955 using StateType = IntegerRangeState;
8956 AAValueConstantRangeImpl(const IRPosition &IRP, Attributor &A)
8957 : AAValueConstantRange(IRP, A) {}
8958
8959 /// See AbstractAttribute::initialize(..).
8960 void initialize(Attributor &A) override {
8961 if (A.hasSimplificationCallback(getIRPosition())) {
8962 indicatePessimisticFixpoint();
8963 return;
8964 }
8965
8966 // Intersect a range given by SCEV.
8967 intersectKnown(getConstantRangeFromSCEV(A, getCtxI()));
8968
8969 // Intersect a range given by LVI.
8970 intersectKnown(getConstantRangeFromLVI(A, getCtxI()));
8971 }
8972
8973 /// See AbstractAttribute::getAsStr().
8974 const std::string getAsStr(Attributor *A) const override {
8975 std::string Str;
8977 OS << "range(" << getBitWidth() << ")<";
8978 getKnown().print(OS);
8979 OS << " / ";
8980 getAssumed().print(OS);
8981 OS << ">";
8982 return OS.str();
8983 }
8984
8985 /// Helper function to get a SCEV expr for the associated value at program
8986 /// point \p I.
8987 const SCEV *getSCEV(Attributor &A, const Instruction *I = nullptr) const {
8988 if (!getAnchorScope())
8989 return nullptr;
8990
8991 ScalarEvolution *SE =
8992 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(
8993 *getAnchorScope());
8994
8995 LoopInfo *LI = A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(
8996 *getAnchorScope());
8997
8998 if (!SE || !LI)
8999 return nullptr;
9000
9001 const SCEV *S = SE->getSCEV(&getAssociatedValue());
9002 if (!I)
9003 return S;
9004
9005 return SE->getSCEVAtScope(S, LI->getLoopFor(I->getParent()));
9006 }
9007
9008 /// Helper function to get a range from SCEV for the associated value at
9009 /// program point \p I.
9010 ConstantRange getConstantRangeFromSCEV(Attributor &A,
9011 const Instruction *I = nullptr) const {
9012 if (!getAnchorScope())
9013 return getWorstState(getBitWidth());
9014
9015 ScalarEvolution *SE =
9016 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(
9017 *getAnchorScope());
9018
9019 const SCEV *S = getSCEV(A, I);
9020 if (!SE || !S)
9021 return getWorstState(getBitWidth());
9022
9023 return SE->getUnsignedRange(S);
9024 }
9025
9026 /// Helper function to get a range from LVI for the associated value at
9027 /// program point \p I.
9029 getConstantRangeFromLVI(Attributor &A,
9030 const Instruction *CtxI = nullptr) const {
9031 if (!getAnchorScope())
9032 return getWorstState(getBitWidth());
9033
9034 LazyValueInfo *LVI =
9035 A.getInfoCache().getAnalysisResultForFunction<LazyValueAnalysis>(
9036 *getAnchorScope());
9037
9038 if (!LVI || !CtxI)
9039 return getWorstState(getBitWidth());
9040 return LVI->getConstantRange(&getAssociatedValue(),
9041 const_cast<Instruction *>(CtxI),
9042 /*UndefAllowed*/ false);
9043 }
9044
9045 /// Return true if \p CtxI is valid for querying outside analyses.
9046 /// This basically makes sure we do not ask intra-procedural analysis
9047 /// about a context in the wrong function or a context that violates
9048 /// dominance assumptions they might have. The \p AllowAACtxI flag indicates
9049 /// if the original context of this AA is OK or should be considered invalid.
9050 bool isValidCtxInstructionForOutsideAnalysis(Attributor &A,
9051 const Instruction *CtxI,
9052 bool AllowAACtxI) const {
9053 if (!CtxI || (!AllowAACtxI && CtxI == getCtxI()))
9054 return false;
9055
9056 // Our context might be in a different function, neither intra-procedural
9057 // analysis (ScalarEvolution nor LazyValueInfo) can handle that.
9058 if (!AA::isValidInScope(getAssociatedValue(), CtxI->getFunction()))
9059 return false;
9060
9061 // If the context is not dominated by the value there are paths to the
9062 // context that do not define the value. This cannot be handled by
9063 // LazyValueInfo so we need to bail.
9064 if (auto *I = dyn_cast<Instruction>(&getAssociatedValue())) {
9065 InformationCache &InfoCache = A.getInfoCache();
9066 const DominatorTree *DT =
9068 *I->getFunction());
9069 return DT && DT->dominates(I, CtxI);
9070 }
9071
9072 return true;
9073 }
9074
9075 /// See AAValueConstantRange::getKnownConstantRange(..).
9077 getKnownConstantRange(Attributor &A,
9078 const Instruction *CtxI = nullptr) const override {
9079 if (!isValidCtxInstructionForOutsideAnalysis(A, CtxI,
9080 /* AllowAACtxI */ false))
9081 return getKnown();
9082
9083 ConstantRange LVIR = getConstantRangeFromLVI(A, CtxI);
9084 ConstantRange SCEVR = getConstantRangeFromSCEV(A, CtxI);
9085 return getKnown().intersectWith(SCEVR).intersectWith(LVIR);
9086 }
9087
9088 /// See AAValueConstantRange::getAssumedConstantRange(..).
9090 getAssumedConstantRange(Attributor &A,
9091 const Instruction *CtxI = nullptr) const override {
9092 // TODO: Make SCEV use Attributor assumption.
9093 // We may be able to bound a variable range via assumptions in
9094 // Attributor. ex.) If x is assumed to be in [1, 3] and y is known to
9095 // evolve to x^2 + x, then we can say that y is in [2, 12].
9096 if (!isValidCtxInstructionForOutsideAnalysis(A, CtxI,
9097 /* AllowAACtxI */ false))
9098 return getAssumed();
9099
9100 ConstantRange LVIR = getConstantRangeFromLVI(A, CtxI);
9101 ConstantRange SCEVR = getConstantRangeFromSCEV(A, CtxI);
9102 return getAssumed().intersectWith(SCEVR).intersectWith(LVIR);
9103 }
9104
9105 /// Helper function to create MDNode for range metadata.
9106 static MDNode *
9107 getMDNodeForConstantRange(Type *Ty, LLVMContext &Ctx,
9108 const ConstantRange &AssumedConstantRange) {
9109 Metadata *LowAndHigh[] = {ConstantAsMetadata::get(ConstantInt::get(
9110 Ty, AssumedConstantRange.getLower())),
9111 ConstantAsMetadata::get(ConstantInt::get(
9112 Ty, AssumedConstantRange.getUpper()))};
9113 return MDNode::get(Ctx, LowAndHigh);
9114 }
9115
9116 /// Return true if \p Assumed is included in \p KnownRanges.
9117 static bool isBetterRange(const ConstantRange &Assumed, MDNode *KnownRanges) {
9118
9119 if (Assumed.isFullSet())
9120 return false;
9121
9122 if (!KnownRanges)
9123 return true;
9124
9125 // If multiple ranges are annotated in IR, we give up to annotate assumed
9126 // range for now.
9127
9128 // TODO: If there exists a known range which containts assumed range, we
9129 // can say assumed range is better.
9130 if (KnownRanges->getNumOperands() > 2)
9131 return false;
9132
9134 mdconst::extract<ConstantInt>(KnownRanges->getOperand(0));
9136 mdconst::extract<ConstantInt>(KnownRanges->getOperand(1));
9137
9138 ConstantRange Known(Lower->getValue(), Upper->getValue());
9139 return Known.contains(Assumed) && Known != Assumed;
9140 }
9141
9142 /// Helper function to set range metadata.
9143 static bool
9144 setRangeMetadataIfisBetterRange(Instruction *I,
9145 const ConstantRange &AssumedConstantRange) {
9146 auto *OldRangeMD = I->getMetadata(LLVMContext::MD_range);
9147 if (isBetterRange(AssumedConstantRange, OldRangeMD)) {
9148 if (!AssumedConstantRange.isEmptySet()) {
9149 I->setMetadata(LLVMContext::MD_range,
9150 getMDNodeForConstantRange(I->getType(), I->getContext(),
9151 AssumedConstantRange));
9152 return true;
9153 }
9154 }
9155 return false;
9156 }
9157
9158 /// See AbstractAttribute::manifest()
9159 ChangeStatus manifest(Attributor &A) override {
9160 ChangeStatus Changed = ChangeStatus::UNCHANGED;
9161 ConstantRange AssumedConstantRange = getAssumedConstantRange(A);
9162 assert(!AssumedConstantRange.isFullSet() && "Invalid state");
9163
9164 auto &V = getAssociatedValue();
9165 if (!AssumedConstantRange.isEmptySet() &&
9166 !AssumedConstantRange.isSingleElement()) {
9167 if (Instruction *I = dyn_cast<Instruction>(&V)) {
9168 assert(I == getCtxI() && "Should not annotate an instruction which is "
9169 "not the context instruction");
9170 if (isa<CallInst>(I) || isa<LoadInst>(I))
9171 if (setRangeMetadataIfisBetterRange(I, AssumedConstantRange))
9172 Changed = ChangeStatus::CHANGED;
9173 }
9174 }
9175
9176 return Changed;
9177 }
9178};
9179
9180struct AAValueConstantRangeArgument final
9181 : AAArgumentFromCallSiteArguments<
9182 AAValueConstantRange, AAValueConstantRangeImpl, IntegerRangeState,
9183 true /* BridgeCallBaseContext */> {
9184 using Base = AAArgumentFromCallSiteArguments<
9185 AAValueConstantRange, AAValueConstantRangeImpl, IntegerRangeState,
9186 true /* BridgeCallBaseContext */>;
9187 AAValueConstantRangeArgument(const IRPosition &IRP, Attributor &A)
9188 : Base(IRP, A) {}
9189
9190 /// See AbstractAttribute::trackStatistics()
9191 void trackStatistics() const override {
9192 STATS_DECLTRACK_ARG_ATTR(value_range)
9193 }
9194};
9195
9196struct AAValueConstantRangeReturned
9197 : AAReturnedFromReturnedValues<AAValueConstantRange,
9198 AAValueConstantRangeImpl,
9199 AAValueConstantRangeImpl::StateType,
9200 /* PropogateCallBaseContext */ true> {
9201 using Base =
9202 AAReturnedFromReturnedValues<AAValueConstantRange,
9203 AAValueConstantRangeImpl,
9205 /* PropogateCallBaseContext */ true>;
9206 AAValueConstantRangeReturned(const IRPosition &IRP, Attributor &A)
9207 : Base(IRP, A) {}
9208
9209 /// See AbstractAttribute::initialize(...).
9210 void initialize(Attributor &A) override {
9211 if (!A.isFunctionIPOAmendable(*getAssociatedFunction()))
9212 indicatePessimisticFixpoint();
9213 }
9214
9215 /// See AbstractAttribute::trackStatistics()
9216 void trackStatistics() const override {
9217 STATS_DECLTRACK_FNRET_ATTR(value_range)
9218 }
9219};
9220
9221struct AAValueConstantRangeFloating : AAValueConstantRangeImpl {
9222 AAValueConstantRangeFloating(const IRPosition &IRP, Attributor &A)
9223 : AAValueConstantRangeImpl(IRP, A) {}
9224
9225 /// See AbstractAttribute::initialize(...).
9226 void initialize(Attributor &A) override {
9227 AAValueConstantRangeImpl::initialize(A);
9228 if (isAtFixpoint())
9229 return;
9230
9231 Value &V = getAssociatedValue();
9232
9233 if (auto *C = dyn_cast<ConstantInt>(&V)) {
9234 unionAssumed(ConstantRange(C->getValue()));
9235 indicateOptimisticFixpoint();
9236 return;
9237 }
9238
9239 if (isa<UndefValue>(&V)) {
9240 // Collapse the undef state to 0.
9241 unionAssumed(ConstantRange(APInt(getBitWidth(), 0)));
9242 indicateOptimisticFixpoint();
9243 return;
9244 }
9245
9246 if (isa<CallBase>(&V))
9247 return;
9248
9249 if (isa<BinaryOperator>(&V) || isa<CmpInst>(&V) || isa<CastInst>(&V))
9250 return;
9251
9252 // If it is a load instruction with range metadata, use it.
9253 if (LoadInst *LI = dyn_cast<LoadInst>(&V))
9254 if (auto *RangeMD = LI->getMetadata(LLVMContext::MD_range)) {
9255 intersectKnown(getConstantRangeFromMetadata(*RangeMD));
9256 return;
9257 }
9258
9259 // We can work with PHI and select instruction as we traverse their operands
9260 // during update.
9261 if (isa<SelectInst>(V) || isa<PHINode>(V))
9262 return;
9263
9264 // Otherwise we give up.
9265 indicatePessimisticFixpoint();
9266
9267 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] We give up: "
9268 << getAssociatedValue() << "\n");
9269 }
9270
9271 bool calculateBinaryOperator(
9273 const Instruction *CtxI,
9275 Value *LHS = BinOp->getOperand(0);
9276 Value *RHS = BinOp->getOperand(1);
9277
9278 // Simplify the operands first.
9279 bool UsedAssumedInformation = false;
9280 const auto &SimplifiedLHS = A.getAssumedSimplified(
9281 IRPosition::value(*LHS, getCallBaseContext()), *this,
9282 UsedAssumedInformation, AA::Interprocedural);
9283 if (!SimplifiedLHS.has_value())
9284 return true;
9285 if (!*SimplifiedLHS)
9286 return false;
9287 LHS = *SimplifiedLHS;
9288
9289 const auto &SimplifiedRHS = A.getAssumedSimplified(
9290 IRPosition::value(*RHS, getCallBaseContext()), *this,
9291 UsedAssumedInformation, AA::Interprocedural);
9292 if (!SimplifiedRHS.has_value())
9293 return true;
9294 if (!*SimplifiedRHS)
9295 return false;
9296 RHS = *SimplifiedRHS;
9297
9298 // TODO: Allow non integers as well.
9299 if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy())
9300 return false;
9301
9302 auto *LHSAA = A.getAAFor<AAValueConstantRange>(
9303 *this, IRPosition::value(*LHS, getCallBaseContext()),
9304 DepClassTy::REQUIRED);
9305 if (!LHSAA)
9306 return false;
9307 QuerriedAAs.push_back(LHSAA);
9308 auto LHSAARange = LHSAA->getAssumedConstantRange(A, CtxI);
9309
9310 auto *RHSAA = A.getAAFor<AAValueConstantRange>(
9311 *this, IRPosition::value(*RHS, getCallBaseContext()),
9312 DepClassTy::REQUIRED);
9313 if (!RHSAA)
9314 return false;
9315 QuerriedAAs.push_back(RHSAA);
9316 auto RHSAARange = RHSAA->getAssumedConstantRange(A, CtxI);
9317
9318 auto AssumedRange = LHSAARange.binaryOp(BinOp->getOpcode(), RHSAARange);
9319
9320 T.unionAssumed(AssumedRange);
9321
9322 // TODO: Track a known state too.
9323
9324 return T.isValidState();
9325 }
9326
9327 bool calculateCastInst(
9329 const Instruction *CtxI,
9331 assert(CastI->getNumOperands() == 1 && "Expected cast to be unary!");
9332 // TODO: Allow non integers as well.
9333 Value *OpV = CastI->getOperand(0);
9334
9335 // Simplify the operand first.
9336 bool UsedAssumedInformation = false;
9337 const auto &SimplifiedOpV = A.getAssumedSimplified(
9338 IRPosition::value(*OpV, getCallBaseContext()), *this,
9339 UsedAssumedInformation, AA::Interprocedural);
9340 if (!SimplifiedOpV.has_value())
9341 return true;
9342 if (!*SimplifiedOpV)
9343 return false;
9344 OpV = *SimplifiedOpV;
9345
9346 if (!OpV->getType()->isIntegerTy())
9347 return false;
9348
9349 auto *OpAA = A.getAAFor<AAValueConstantRange>(
9350 *this, IRPosition::value(*OpV, getCallBaseContext()),
9351 DepClassTy::REQUIRED);
9352 if (!OpAA)
9353 return false;
9354 QuerriedAAs.push_back(OpAA);
9355 T.unionAssumed(OpAA->getAssumed().castOp(CastI->getOpcode(),
9356 getState().getBitWidth()));
9357 return T.isValidState();
9358 }
9359
9360 bool
9361 calculateCmpInst(Attributor &A, CmpInst *CmpI, IntegerRangeState &T,
9362 const Instruction *CtxI,
9364 Value *LHS = CmpI->getOperand(0);
9365 Value *RHS = CmpI->getOperand(1);
9366
9367 // Simplify the operands first.
9368 bool UsedAssumedInformation = false;
9369 const auto &SimplifiedLHS = A.getAssumedSimplified(
9370 IRPosition::value(*LHS, getCallBaseContext()), *this,
9371 UsedAssumedInformation, AA::Interprocedural);
9372 if (!SimplifiedLHS.has_value())
9373 return true;
9374 if (!*SimplifiedLHS)
9375 return false;
9376 LHS = *SimplifiedLHS;
9377
9378 const auto &SimplifiedRHS = A.getAssumedSimplified(
9379 IRPosition::value(*RHS, getCallBaseContext()), *this,
9380 UsedAssumedInformation, AA::Interprocedural);
9381 if (!SimplifiedRHS.has_value())
9382 return true;
9383 if (!*SimplifiedRHS)
9384 return false;
9385 RHS = *SimplifiedRHS;
9386
9387 // TODO: Allow non integers as well.
9388 if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy())
9389 return false;
9390
9391 auto *LHSAA = A.getAAFor<AAValueConstantRange>(
9392 *this, IRPosition::value(*LHS, getCallBaseContext()),
9393 DepClassTy::REQUIRED);
9394 if (!LHSAA)
9395 return false;
9396 QuerriedAAs.push_back(LHSAA);
9397 auto *RHSAA = A.getAAFor<AAValueConstantRange>(
9398 *this, IRPosition::value(*RHS, getCallBaseContext()),
9399 DepClassTy::REQUIRED);
9400 if (!RHSAA)
9401 return false;
9402 QuerriedAAs.push_back(RHSAA);
9403 auto LHSAARange = LHSAA->getAssumedConstantRange(A, CtxI);
9404 auto RHSAARange = RHSAA->getAssumedConstantRange(A, CtxI);
9405
9406 // If one of them is empty set, we can't decide.
9407 if (LHSAARange.isEmptySet() || RHSAARange.isEmptySet())
9408 return true;
9409
9410 bool MustTrue = false, MustFalse = false;
9411
9412 auto AllowedRegion =
9414
9415 if (AllowedRegion.intersectWith(LHSAARange).isEmptySet())
9416 MustFalse = true;
9417
9418 if (LHSAARange.icmp(CmpI->getPredicate(), RHSAARange))
9419 MustTrue = true;
9420
9421 assert((!MustTrue || !MustFalse) &&
9422 "Either MustTrue or MustFalse should be false!");
9423
9424 if (MustTrue)
9425 T.unionAssumed(ConstantRange(APInt(/* numBits */ 1, /* val */ 1)));
9426 else if (MustFalse)
9427 T.unionAssumed(ConstantRange(APInt(/* numBits */ 1, /* val */ 0)));
9428 else
9429 T.unionAssumed(ConstantRange(/* BitWidth */ 1, /* isFullSet */ true));
9430
9431 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] " << *CmpI << " after "
9432 << (MustTrue ? "true" : (MustFalse ? "false" : "unknown"))
9433 << ": " << T << "\n\t" << *LHSAA << "\t<op>\n\t"
9434 << *RHSAA);
9435
9436 // TODO: Track a known state too.
9437 return T.isValidState();
9438 }
9439
9440 /// See AbstractAttribute::updateImpl(...).
9441 ChangeStatus updateImpl(Attributor &A) override {
9442
9444 auto VisitValueCB = [&](Value &V, const Instruction *CtxI) -> bool {
9445 Instruction *I = dyn_cast<Instruction>(&V);
9446 if (!I || isa<CallBase>(I)) {
9447
9448 // Simplify the operand first.
9449 bool UsedAssumedInformation = false;
9450 const auto &SimplifiedOpV = A.getAssumedSimplified(
9451 IRPosition::value(V, getCallBaseContext()), *this,
9452 UsedAssumedInformation, AA::Interprocedural);
9453 if (!SimplifiedOpV.has_value())
9454 return true;
9455 if (!*SimplifiedOpV)
9456 return false;
9457 Value *VPtr = *SimplifiedOpV;
9458
9459 // If the value is not instruction, we query AA to Attributor.
9460 const auto *AA = A.getAAFor<AAValueConstantRange>(
9461 *this, IRPosition::value(*VPtr, getCallBaseContext()),
9462 DepClassTy::REQUIRED);
9463
9464 // Clamp operator is not used to utilize a program point CtxI.
9465 if (AA)
9466 T.unionAssumed(AA->getAssumedConstantRange(A, CtxI));
9467 else
9468 return false;
9469
9470 return T.isValidState();
9471 }
9472
9474 if (auto *BinOp = dyn_cast<BinaryOperator>(I)) {
9475 if (!calculateBinaryOperator(A, BinOp, T, CtxI, QuerriedAAs))
9476 return false;
9477 } else if (auto *CmpI = dyn_cast<CmpInst>(I)) {
9478 if (!calculateCmpInst(A, CmpI, T, CtxI, QuerriedAAs))
9479 return false;
9480 } else if (auto *CastI = dyn_cast<CastInst>(I)) {
9481 if (!calculateCastInst(A, CastI, T, CtxI, QuerriedAAs))
9482 return false;
9483 } else {
9484 // Give up with other instructions.
9485 // TODO: Add other instructions
9486
9487 T.indicatePessimisticFixpoint();
9488 return false;
9489 }
9490
9491 // Catch circular reasoning in a pessimistic way for now.
9492 // TODO: Check how the range evolves and if we stripped anything, see also
9493 // AADereferenceable or AAAlign for similar situations.
9494 for (const AAValueConstantRange *QueriedAA : QuerriedAAs) {
9495 if (QueriedAA != this)
9496 continue;
9497 // If we are in a stady state we do not need to worry.
9498 if (T.getAssumed() == getState().getAssumed())
9499 continue;
9500 T.indicatePessimisticFixpoint();
9501 }
9502
9503 return T.isValidState();
9504 };
9505
9506 if (!VisitValueCB(getAssociatedValue(), getCtxI()))
9507 return indicatePessimisticFixpoint();
9508
9509 // Ensure that long def-use chains can't cause circular reasoning either by
9510 // introducing a cutoff below.
9511 if (clampStateAndIndicateChange(getState(), T) == ChangeStatus::UNCHANGED)
9512 return ChangeStatus::UNCHANGED;
9513 if (++NumChanges > MaxNumChanges) {
9514 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] performed " << NumChanges
9515 << " but only " << MaxNumChanges
9516 << " are allowed to avoid cyclic reasoning.");
9517 return indicatePessimisticFixpoint();
9518 }
9519 return ChangeStatus::CHANGED;
9520 }
9521
9522 /// See AbstractAttribute::trackStatistics()
9523 void trackStatistics() const override {
9525 }
9526
9527 /// Tracker to bail after too many widening steps of the constant range.
9528 int NumChanges = 0;
9529
9530 /// Upper bound for the number of allowed changes (=widening steps) for the
9531 /// constant range before we give up.
9532 static constexpr int MaxNumChanges = 5;
9533};
9534
9535struct AAValueConstantRangeFunction : AAValueConstantRangeImpl {
9536 AAValueConstantRangeFunction(const IRPosition &IRP, Attributor &A)
9537 : AAValueConstantRangeImpl(IRP, A) {}
9538
9539 /// See AbstractAttribute::initialize(...).
9540 ChangeStatus updateImpl(Attributor &A) override {
9541 llvm_unreachable("AAValueConstantRange(Function|CallSite)::updateImpl will "
9542 "not be called");
9543 }
9544
9545 /// See AbstractAttribute::trackStatistics()
9546 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(value_range) }
9547};
9548
9549struct AAValueConstantRangeCallSite : AAValueConstantRangeFunction {
9550 AAValueConstantRangeCallSite(const IRPosition &IRP, Attributor &A)
9551 : AAValueConstantRangeFunction(IRP, A) {}
9552
9553 /// See AbstractAttribute::trackStatistics()
9554 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(value_range) }
9555};
9556
9557struct AAValueConstantRangeCallSiteReturned
9558 : AACalleeToCallSite<AAValueConstantRange, AAValueConstantRangeImpl,
9559 AAValueConstantRangeImpl::StateType,
9560 /* IntroduceCallBaseContext */ true> {
9561 AAValueConstantRangeCallSiteReturned(const IRPosition &IRP, Attributor &A)
9562 : AACalleeToCallSite<AAValueConstantRange, AAValueConstantRangeImpl,
9563 AAValueConstantRangeImpl::StateType,
9564 /* IntroduceCallBaseContext */ true>(IRP, A) {}
9565
9566 /// See AbstractAttribute::initialize(...).
9567 void initialize(Attributor &A) override {
9568 // If it is a load instruction with range metadata, use the metadata.
9569 if (CallInst *CI = dyn_cast<CallInst>(&getAssociatedValue()))
9570 if (auto *RangeMD = CI->getMetadata(LLVMContext::MD_range))
9571 intersectKnown(getConstantRangeFromMetadata(*RangeMD));
9572
9573 AAValueConstantRangeImpl::initialize(A);
9574 }
9575
9576 /// See AbstractAttribute::trackStatistics()
9577 void trackStatistics() const override {
9578 STATS_DECLTRACK_CSRET_ATTR(value_range)
9579 }
9580};
9581struct AAValueConstantRangeCallSiteArgument : AAValueConstantRangeFloating {
9582 AAValueConstantRangeCallSiteArgument(const IRPosition &IRP, Attributor &A)
9583 : AAValueConstantRangeFloating(IRP, A) {}
9584
9585 /// See AbstractAttribute::manifest()
9586 ChangeStatus manifest(Attributor &A) override {
9587 return ChangeStatus::UNCHANGED;
9588 }
9589
9590 /// See AbstractAttribute::trackStatistics()
9591 void trackStatistics() const override {
9592 STATS_DECLTRACK_CSARG_ATTR(value_range)
9593 }
9594};
9595} // namespace
9596
9597/// ------------------ Potential Values Attribute -------------------------
9598
9599namespace {
9600struct AAPotentialConstantValuesImpl : AAPotentialConstantValues {
9601 using StateType = PotentialConstantIntValuesState;
9602
9603 AAPotentialConstantValuesImpl(const IRPosition &IRP, Attributor &A)
9604 : AAPotentialConstantValues(IRP, A) {}
9605
9606 /// See AbstractAttribute::initialize(..).
9607 void initialize(Attributor &A) override {
9608 if (A.hasSimplificationCallback(getIRPosition()))
9609 indicatePessimisticFixpoint();
9610 else
9611 AAPotentialConstantValues::initialize(A);
9612 }
9613
9614 bool fillSetWithConstantValues(Attributor &A, const IRPosition &IRP, SetTy &S,
9615 bool &ContainsUndef, bool ForSelf) {
9617 bool UsedAssumedInformation = false;
9618 if (!A.getAssumedSimplifiedValues(IRP, *this, Values, AA::Interprocedural,
9619 UsedAssumedInformation)) {
9620 // Avoid recursion when the caller is computing constant values for this
9621 // IRP itself.
9622 if (ForSelf)
9623 return false;
9624 if (!IRP.getAssociatedType()->isIntegerTy())
9625 return false;
9626 auto *PotentialValuesAA = A.getAAFor<AAPotentialConstantValues>(
9627 *this, IRP, DepClassTy::REQUIRED);
9628 if (!PotentialValuesAA || !PotentialValuesAA->getState().isValidState())
9629 return false;
9630 ContainsUndef = PotentialValuesAA->getState().undefIsContained();
9631 S = PotentialValuesAA->getState().getAssumedSet();
9632 return true;
9633 }
9634
9635 // Copy all the constant values, except UndefValue. ContainsUndef is true
9636 // iff Values contains only UndefValue instances. If there are other known
9637 // constants, then UndefValue is dropped.
9638 ContainsUndef = false;
9639 for (auto &It : Values) {
9640 if (isa<UndefValue>(It.getValue())) {
9641 ContainsUndef = true;
9642 continue;
9643 }
9644 auto *CI = dyn_cast<ConstantInt>(It.getValue());
9645 if (!CI)
9646 return false;
9647 S.insert(CI->getValue());
9648 }
9649 ContainsUndef &= S.empty();
9650
9651 return true;
9652 }
9653
9654 /// See AbstractAttribute::getAsStr().
9655 const std::string getAsStr(Attributor *A) const override {
9656 std::string Str;
9658 OS << getState();
9659 return OS.str();
9660 }
9661
9662 /// See AbstractAttribute::updateImpl(...).
9663 ChangeStatus updateImpl(Attributor &A) override {
9664 return indicatePessimisticFixpoint();
9665 }
9666};
9667
9668struct AAPotentialConstantValuesArgument final
9669 : AAArgumentFromCallSiteArguments<AAPotentialConstantValues,
9670 AAPotentialConstantValuesImpl,
9671 PotentialConstantIntValuesState> {
9672 using Base = AAArgumentFromCallSiteArguments<AAPotentialConstantValues,
9673 AAPotentialConstantValuesImpl,
9675 AAPotentialConstantValuesArgument(const IRPosition &IRP, Attributor &A)
9676 : Base(IRP, A) {}
9677
9678 /// See AbstractAttribute::trackStatistics()
9679 void trackStatistics() const override {
9680 STATS_DECLTRACK_ARG_ATTR(potential_values)
9681 }
9682};
9683
9684struct AAPotentialConstantValuesReturned
9685 : AAReturnedFromReturnedValues<AAPotentialConstantValues,
9686 AAPotentialConstantValuesImpl> {
9687 using Base = AAReturnedFromReturnedValues<AAPotentialConstantValues,
9688 AAPotentialConstantValuesImpl>;
9689 AAPotentialConstantValuesReturned(const IRPosition &IRP, Attributor &A)
9690 : Base(IRP, A) {}
9691
9692 void initialize(Attributor &A) override {
9693 if (!A.isFunctionIPOAmendable(*getAssociatedFunction()))
9694 indicatePessimisticFixpoint();
9695 Base::initialize(A);
9696 }
9697
9698 /// See AbstractAttribute::trackStatistics()
9699 void trackStatistics() const override {
9700 STATS_DECLTRACK_FNRET_ATTR(potential_values)
9701 }
9702};
9703
9704struct AAPotentialConstantValuesFloating : AAPotentialConstantValuesImpl {
9705 AAPotentialConstantValuesFloating(const IRPosition &IRP, Attributor &A)
9706 : AAPotentialConstantValuesImpl(IRP, A) {}
9707
9708 /// See AbstractAttribute::initialize(..).
9709 void initialize(Attributor &A) override {
9710 AAPotentialConstantValuesImpl::initialize(A);
9711 if (isAtFixpoint())
9712 return;
9713
9714 Value &V = getAssociatedValue();
9715
9716 if (auto *C = dyn_cast<ConstantInt>(&V)) {
9717 unionAssumed(C->getValue());
9718 indicateOptimisticFixpoint();
9719 return;
9720 }
9721
9722 if (isa<UndefValue>(&V)) {
9723 unionAssumedWithUndef();
9724 indicateOptimisticFixpoint();
9725 return;
9726 }
9727
9728 if (isa<BinaryOperator>(&V) || isa<ICmpInst>(&V) || isa<CastInst>(&V))
9729 return;
9730
9731 if (isa<SelectInst>(V) || isa<PHINode>(V) || isa<LoadInst>(V))
9732 return;
9733
9734 indicatePessimisticFixpoint();
9735
9736 LLVM_DEBUG(dbgs() << "[AAPotentialConstantValues] We give up: "
9737 << getAssociatedValue() << "\n");
9738 }
9739
9740 static bool calculateICmpInst(const ICmpInst *ICI, const APInt &LHS,
9741 const APInt &RHS) {
9742 return ICmpInst::compare(LHS, RHS, ICI->getPredicate());
9743 }
9744
9745 static APInt calculateCastInst(const CastInst *CI, const APInt &Src,
9746 uint32_t ResultBitWidth) {
9747 Instruction::CastOps CastOp = CI->getOpcode();
9748 switch (CastOp) {
9749 default:
9750 llvm_unreachable("unsupported or not integer cast");
9751 case Instruction::Trunc:
9752 return Src.trunc(ResultBitWidth);
9753 case Instruction::SExt:
9754 return Src.sext(ResultBitWidth);
9755 case Instruction::ZExt:
9756 return Src.zext(ResultBitWidth);
9757 case Instruction::BitCast:
9758 return Src;
9759 }
9760 }
9761
9762 static APInt calculateBinaryOperator(const BinaryOperator *BinOp,
9763 const APInt &LHS, const APInt &RHS,
9764 bool &SkipOperation, bool &Unsupported) {
9765 Instruction::BinaryOps BinOpcode = BinOp->getOpcode();
9766 // Unsupported is set to true when the binary operator is not supported.
9767 // SkipOperation is set to true when UB occur with the given operand pair
9768 // (LHS, RHS).
9769 // TODO: we should look at nsw and nuw keywords to handle operations
9770 // that create poison or undef value.
9771 switch (BinOpcode) {
9772 default:
9773 Unsupported = true;
9774 return LHS;
9775 case Instruction::Add:
9776 return LHS + RHS;
9777 case Instruction::Sub:
9778 return LHS - RHS;
9779 case Instruction::Mul:
9780 return LHS * RHS;
9781 case Instruction::UDiv:
9782 if (RHS.isZero()) {
9783 SkipOperation = true;
9784 return LHS;
9785 }
9786 return LHS.udiv(RHS);
9787 case Instruction::SDiv:
9788 if (RHS.isZero()) {
9789 SkipOperation = true;
9790 return LHS;
9791 }
9792 return LHS.sdiv(RHS);
9793 case Instruction::URem:
9794 if (RHS.isZero()) {
9795 SkipOperation = true;
9796 return LHS;
9797 }
9798 return LHS.urem(RHS);
9799 case Instruction::SRem:
9800 if (RHS.isZero()) {
9801 SkipOperation = true;
9802 return LHS;
9803 }
9804 return LHS.srem(RHS);
9805 case Instruction::Shl:
9806 return LHS.shl(RHS);
9807 case Instruction::LShr:
9808 return LHS.lshr(RHS);
9809 case Instruction::AShr:
9810 return LHS.ashr(RHS);
9811 case Instruction::And:
9812 return LHS & RHS;
9813 case Instruction::Or:
9814 return LHS | RHS;
9815 case Instruction::Xor:
9816 return LHS ^ RHS;
9817 }
9818 }
9819
9820 bool calculateBinaryOperatorAndTakeUnion(const BinaryOperator *BinOp,
9821 const APInt &LHS, const APInt &RHS) {
9822 bool SkipOperation = false;
9823 bool Unsupported = false;
9824 APInt Result =
9825 calculateBinaryOperator(BinOp, LHS, RHS, SkipOperation, Unsupported);
9826 if (Unsupported)
9827 return false;
9828 // If SkipOperation is true, we can ignore this operand pair (L, R).
9829 if (!SkipOperation)
9830 unionAssumed(Result);
9831 return isValidState();
9832 }
9833
9834 ChangeStatus updateWithICmpInst(Attributor &A, ICmpInst *ICI) {
9835 auto AssumedBefore = getAssumed();
9836 Value *LHS = ICI->getOperand(0);
9837 Value *RHS = ICI->getOperand(1);
9838
9839 bool LHSContainsUndef = false, RHSContainsUndef = false;
9840 SetTy LHSAAPVS, RHSAAPVS;
9841 if (!fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS,
9842 LHSContainsUndef, /* ForSelf */ false) ||
9843 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS,
9844 RHSContainsUndef, /* ForSelf */ false))
9845 return indicatePessimisticFixpoint();
9846
9847 // TODO: make use of undef flag to limit potential values aggressively.
9848 bool MaybeTrue = false, MaybeFalse = false;
9849 const APInt Zero(RHS->getType()->getIntegerBitWidth(), 0);
9850 if (LHSContainsUndef && RHSContainsUndef) {
9851 // The result of any comparison between undefs can be soundly replaced
9852 // with undef.
9853 unionAssumedWithUndef();
9854 } else if (LHSContainsUndef) {
9855 for (const APInt &R : RHSAAPVS) {
9856 bool CmpResult = calculateICmpInst(ICI, Zero, R);
9857 MaybeTrue |= CmpResult;
9858 MaybeFalse |= !CmpResult;
9859 if (MaybeTrue & MaybeFalse)
9860 return indicatePessimisticFixpoint();
9861 }
9862 } else if (RHSContainsUndef) {
9863 for (const APInt &L : LHSAAPVS) {
9864 bool CmpResult = calculateICmpInst(ICI, L, Zero);
9865 MaybeTrue |= CmpResult;
9866 MaybeFalse |= !CmpResult;
9867 if (MaybeTrue & MaybeFalse)
9868 return indicatePessimisticFixpoint();
9869 }
9870 } else {
9871 for (const APInt &L : LHSAAPVS) {
9872 for (const APInt &R : RHSAAPVS) {
9873 bool CmpResult = calculateICmpInst(ICI, L, R);
9874 MaybeTrue |= CmpResult;
9875 MaybeFalse |= !CmpResult;
9876 if (MaybeTrue & MaybeFalse)
9877 return indicatePessimisticFixpoint();
9878 }
9879 }
9880 }
9881 if (MaybeTrue)
9882 unionAssumed(APInt(/* numBits */ 1, /* val */ 1));
9883 if (MaybeFalse)
9884 unionAssumed(APInt(/* numBits */ 1, /* val */ 0));
9885 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
9886 : ChangeStatus::CHANGED;
9887 }
9888
9889 ChangeStatus updateWithSelectInst(Attributor &A, SelectInst *SI) {
9890 auto AssumedBefore = getAssumed();
9891 Value *LHS = SI->getTrueValue();
9892 Value *RHS = SI->getFalseValue();
9893
9894 bool UsedAssumedInformation = false;
9895 std::optional<Constant *> C = A.getAssumedConstant(
9896 *SI->getCondition(), *this, UsedAssumedInformation);
9897
9898 // Check if we only need one operand.
9899 bool OnlyLeft = false, OnlyRight = false;
9900 if (C && *C && (*C)->isOneValue())
9901 OnlyLeft = true;
9902 else if (C && *C && (*C)->isZeroValue())
9903 OnlyRight = true;
9904
9905 bool LHSContainsUndef = false, RHSContainsUndef = false;
9906 SetTy LHSAAPVS, RHSAAPVS;
9907 if (!OnlyRight &&
9908 !fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS,
9909 LHSContainsUndef, /* ForSelf */ false))
9910 return indicatePessimisticFixpoint();
9911
9912 if (!OnlyLeft &&
9913 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS,
9914 RHSContainsUndef, /* ForSelf */ false))
9915 return indicatePessimisticFixpoint();
9916
9917 if (OnlyLeft || OnlyRight) {
9918 // select (true/false), lhs, rhs
9919 auto *OpAA = OnlyLeft ? &LHSAAPVS : &RHSAAPVS;
9920 auto Undef = OnlyLeft ? LHSContainsUndef : RHSContainsUndef;
9921
9922 if (Undef)
9923 unionAssumedWithUndef();
9924 else {
9925 for (const auto &It : *OpAA)
9926 unionAssumed(It);
9927 }
9928
9929 } else if (LHSContainsUndef && RHSContainsUndef) {
9930 // select i1 *, undef , undef => undef
9931 unionAssumedWithUndef();
9932 } else {
9933 for (const auto &It : LHSAAPVS)
9934 unionAssumed(It);
9935 for (const auto &It : RHSAAPVS)
9936 unionAssumed(It);
9937 }
9938 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
9939 : ChangeStatus::CHANGED;
9940 }
9941
9942 ChangeStatus updateWithCastInst(Attributor &A, CastInst *CI) {
9943 auto AssumedBefore = getAssumed();
9944 if (!CI->isIntegerCast())
9945 return indicatePessimisticFixpoint();
9946 assert(CI->getNumOperands() == 1 && "Expected cast to be unary!");
9947 uint32_t ResultBitWidth = CI->getDestTy()->getIntegerBitWidth();
9948 Value *Src = CI->getOperand(0);
9949
9950 bool SrcContainsUndef = false;
9951 SetTy SrcPVS;
9952 if (!fillSetWithConstantValues(A, IRPosition::value(*Src), SrcPVS,
9953 SrcContainsUndef, /* ForSelf */ false))
9954 return indicatePessimisticFixpoint();
9955
9956 if (SrcContainsUndef)
9957 unionAssumedWithUndef();
9958 else {
9959 for (const APInt &S : SrcPVS) {
9960 APInt T = calculateCastInst(CI, S, ResultBitWidth);
9961 unionAssumed(T);
9962 }
9963 }
9964 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
9965 : ChangeStatus::CHANGED;
9966 }
9967
9968 ChangeStatus updateWithBinaryOperator(Attributor &A, BinaryOperator *BinOp) {
9969 auto AssumedBefore = getAssumed();
9970 Value *LHS = BinOp->getOperand(0);
9971 Value *RHS = BinOp->getOperand(1);
9972
9973 bool LHSContainsUndef = false, RHSContainsUndef = false;
9974 SetTy LHSAAPVS, RHSAAPVS;
9975 if (!fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS,
9976 LHSContainsUndef, /* ForSelf */ false) ||
9977 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS,
9978 RHSContainsUndef, /* ForSelf */ false))
9979 return indicatePessimisticFixpoint();
9980
9981 const APInt Zero = APInt(LHS->getType()->getIntegerBitWidth(), 0);
9982
9983 // TODO: make use of undef flag to limit potential values aggressively.
9984 if (LHSContainsUndef && RHSContainsUndef) {
9985 if (!calculateBinaryOperatorAndTakeUnion(BinOp, Zero, Zero))
9986 return indicatePessimisticFixpoint();
9987 } else if (LHSContainsUndef) {
9988 for (const APInt &R : RHSAAPVS) {
9989 if (!calculateBinaryOperatorAndTakeUnion(BinOp, Zero, R))
9990 return indicatePessimisticFixpoint();
9991 }
9992 } else if (RHSContainsUndef) {
9993 for (const APInt &L : LHSAAPVS) {
9994 if (!calculateBinaryOperatorAndTakeUnion(BinOp, L, Zero))
9995 return indicatePessimisticFixpoint();
9996 }
9997 } else {
9998 for (const APInt &L : LHSAAPVS) {
9999 for (const APInt &R : RHSAAPVS) {
10000 if (!calculateBinaryOperatorAndTakeUnion(BinOp, L, R))
10001 return indicatePessimisticFixpoint();
10002 }
10003 }
10004 }
10005 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10006 : ChangeStatus::CHANGED;
10007 }
10008
10009 ChangeStatus updateWithInstruction(Attributor &A, Instruction *Inst) {
10010 auto AssumedBefore = getAssumed();
10011 SetTy Incoming;
10012 bool ContainsUndef;
10013 if (!fillSetWithConstantValues(A, IRPosition::value(*Inst), Incoming,
10014 ContainsUndef, /* ForSelf */ true))
10015 return indicatePessimisticFixpoint();
10016 if (ContainsUndef) {
10017 unionAssumedWithUndef();
10018 } else {
10019 for (const auto &It : Incoming)
10020 unionAssumed(It);
10021 }
10022 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10023 : ChangeStatus::CHANGED;
10024 }
10025
10026 /// See AbstractAttribute::updateImpl(...).
10027 ChangeStatus updateImpl(Attributor &A) override {
10028 Value &V = getAssociatedValue();
10029 Instruction *I = dyn_cast<Instruction>(&V);
10030
10031 if (auto *ICI = dyn_cast<ICmpInst>(I))
10032 return updateWithICmpInst(A, ICI);
10033
10034 if (auto *SI = dyn_cast<SelectInst>(I))
10035 return updateWithSelectInst(A, SI);
10036
10037 if (auto *CI = dyn_cast<CastInst>(I))
10038 return updateWithCastInst(A, CI);
10039
10040 if (auto *BinOp = dyn_cast<BinaryOperator>(I))
10041 return updateWithBinaryOperator(A, BinOp);
10042
10043 if (isa<PHINode>(I) || isa<LoadInst>(I))
10044 return updateWithInstruction(A, I);
10045
10046 return indicatePessimisticFixpoint();
10047 }
10048
10049 /// See AbstractAttribute::trackStatistics()
10050 void trackStatistics() const override {
10051 STATS_DECLTRACK_FLOATING_ATTR(potential_values)
10052 }
10053};
10054
10055struct AAPotentialConstantValuesFunction : AAPotentialConstantValuesImpl {
10056 AAPotentialConstantValuesFunction(const IRPosition &IRP, Attributor &A)
10057 : AAPotentialConstantValuesImpl(IRP, A) {}
10058
10059 /// See AbstractAttribute::initialize(...).
10060 ChangeStatus updateImpl(Attributor &A) override {
10062 "AAPotentialConstantValues(Function|CallSite)::updateImpl will "
10063 "not be called");
10064 }
10065
10066 /// See AbstractAttribute::trackStatistics()
10067 void trackStatistics() const override {
10068 STATS_DECLTRACK_FN_ATTR(potential_values)
10069 }
10070};
10071
10072struct AAPotentialConstantValuesCallSite : AAPotentialConstantValuesFunction {
10073 AAPotentialConstantValuesCallSite(const IRPosition &IRP, Attributor &A)
10074 : AAPotentialConstantValuesFunction(IRP, A) {}
10075
10076 /// See AbstractAttribute::trackStatistics()
10077 void trackStatistics() const override {
10078 STATS_DECLTRACK_CS_ATTR(potential_values)
10079 }
10080};
10081
10082struct AAPotentialConstantValuesCallSiteReturned
10083 : AACalleeToCallSite<AAPotentialConstantValues,
10084 AAPotentialConstantValuesImpl> {
10085 AAPotentialConstantValuesCallSiteReturned(const IRPosition &IRP,
10086 Attributor &A)
10087 : AACalleeToCallSite<AAPotentialConstantValues,
10088 AAPotentialConstantValuesImpl>(IRP, A) {}
10089
10090 /// See AbstractAttribute::trackStatistics()
10091 void trackStatistics() const override {
10092 STATS_DECLTRACK_CSRET_ATTR(potential_values)
10093 }
10094};
10095
10096struct AAPotentialConstantValuesCallSiteArgument
10097 : AAPotentialConstantValuesFloating {
10098 AAPotentialConstantValuesCallSiteArgument(const IRPosition &IRP,
10099 Attributor &A)
10100 : AAPotentialConstantValuesFloating(IRP, A) {}
10101
10102 /// See AbstractAttribute::initialize(..).
10103 void initialize(Attributor &A) override {
10104 AAPotentialConstantValuesImpl::initialize(A);
10105 if (isAtFixpoint())
10106 return;
10107
10108 Value &V = getAssociatedValue();
10109
10110 if (auto *C = dyn_cast<ConstantInt>(&V)) {
10111 unionAssumed(C->getValue());
10112 indicateOptimisticFixpoint();
10113 return;
10114 }
10115
10116 if (isa<UndefValue>(&V)) {
10117 unionAssumedWithUndef();
10118 indicateOptimisticFixpoint();
10119 return;
10120 }
10121 }
10122
10123 /// See AbstractAttribute::updateImpl(...).
10124 ChangeStatus updateImpl(Attributor &A) override {
10125 Value &V = getAssociatedValue();
10126 auto AssumedBefore = getAssumed();
10127 auto *AA = A.getAAFor<AAPotentialConstantValues>(
10128 *this, IRPosition::value(V), DepClassTy::REQUIRED);
10129 if (!AA)
10130 return indicatePessimisticFixpoint();
10131 const auto &S = AA->getAssumed();
10132 unionAssumed(S);
10133 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10134 : ChangeStatus::CHANGED;
10135 }
10136
10137 /// See AbstractAttribute::trackStatistics()
10138 void trackStatistics() const override {
10139 STATS_DECLTRACK_CSARG_ATTR(potential_values)
10140 }
10141};
10142} // namespace
10143
10144/// ------------------------ NoUndef Attribute ---------------------------------
10146 Attribute::AttrKind ImpliedAttributeKind,
10147 bool IgnoreSubsumingPositions) {
10148 assert(ImpliedAttributeKind == Attribute::NoUndef &&
10149 "Unexpected attribute kind");
10150 if (A.hasAttr(IRP, {Attribute::NoUndef}, IgnoreSubsumingPositions,
10151 Attribute::NoUndef))
10152 return true;
10153
10154 Value &Val = IRP.getAssociatedValue();
10157 LLVMContext &Ctx = Val.getContext();
10158 A.manifestAttrs(IRP, Attribute::get(Ctx, Attribute::NoUndef));
10159 return true;
10160 }
10161
10162 return false;
10163}
10164
10165namespace {
10166struct AANoUndefImpl : AANoUndef {
10167 AANoUndefImpl(const IRPosition &IRP, Attributor &A) : AANoUndef(IRP, A) {}
10168
10169 /// See AbstractAttribute::initialize(...).
10170 void initialize(Attributor &A) override {
10171 Value &V = getAssociatedValue();
10172 if (isa<UndefValue>(V))
10173 indicatePessimisticFixpoint();
10174 assert(!isImpliedByIR(A, getIRPosition(), Attribute::NoUndef));
10175 }
10176
10177 /// See followUsesInMBEC
10178 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
10179 AANoUndef::StateType &State) {
10180 const Value *UseV = U->get();
10181 const DominatorTree *DT = nullptr;
10182 AssumptionCache *AC = nullptr;
10183 InformationCache &InfoCache = A.getInfoCache();
10184 if (Function *F = getAnchorScope()) {
10187 }
10188 State.setKnown(isGuaranteedNotToBeUndefOrPoison(UseV, AC, I, DT));
10189 bool TrackUse = false;
10190 // Track use for instructions which must produce undef or poison bits when
10191 // at least one operand contains such bits.
10192 if (isa<CastInst>(*I) || isa<GetElementPtrInst>(*I))
10193 TrackUse = true;
10194 return TrackUse;
10195 }
10196
10197 /// See AbstractAttribute::getAsStr().
10198 const std::string getAsStr(Attributor *A) const override {
10199 return getAssumed() ? "noundef" : "may-undef-or-poison";
10200 }
10201
10202 ChangeStatus manifest(Attributor &A) override {
10203 // We don't manifest noundef attribute for dead positions because the
10204 // associated values with dead positions would be replaced with undef
10205 // values.
10206 bool UsedAssumedInformation = false;
10207 if (A.isAssumedDead(getIRPosition(), nullptr, nullptr,
10208 UsedAssumedInformation))
10209 return ChangeStatus::UNCHANGED;
10210 // A position whose simplified value does not have any value is
10211 // considered to be dead. We don't manifest noundef in such positions for
10212 // the same reason above.
10213 if (!A.getAssumedSimplified(getIRPosition(), *this, UsedAssumedInformation,
10215 .has_value())
10216 return ChangeStatus::UNCHANGED;
10217 return AANoUndef::manifest(A);
10218 }
10219};
10220
10221struct AANoUndefFloating : public AANoUndefImpl {
10222 AANoUndefFloating(const IRPosition &IRP, Attributor &A)
10223 : AANoUndefImpl(IRP, A) {}
10224
10225 /// See AbstractAttribute::initialize(...).
10226 void initialize(Attributor &A) override {
10227 AANoUndefImpl::initialize(A);
10228 if (!getState().isAtFixpoint() && getAnchorScope() &&
10229 !getAnchorScope()->isDeclaration())
10230 if (Instruction *CtxI = getCtxI())
10231 followUsesInMBEC(*this, A, getState(), *CtxI);
10232 }
10233
10234 /// See AbstractAttribute::updateImpl(...).
10235 ChangeStatus updateImpl(Attributor &A) override {
10236 auto VisitValueCB = [&](const IRPosition &IRP) -> bool {
10237 bool IsKnownNoUndef;
10238 return AA::hasAssumedIRAttr<Attribute::NoUndef>(
10239 A, this, IRP, DepClassTy::REQUIRED, IsKnownNoUndef);
10240 };
10241
10242 bool Stripped;
10243 bool UsedAssumedInformation = false;
10244 Value *AssociatedValue = &getAssociatedValue();
10246 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
10247 AA::AnyScope, UsedAssumedInformation))
10248 Stripped = false;
10249 else
10250 Stripped =
10251 Values.size() != 1 || Values.front().getValue() != AssociatedValue;
10252
10253 if (!Stripped) {
10254 // If we haven't stripped anything we might still be able to use a
10255 // different AA, but only if the IRP changes. Effectively when we
10256 // interpret this not as a call site value but as a floating/argument
10257 // value.
10258 const IRPosition AVIRP = IRPosition::value(*AssociatedValue);
10259 if (AVIRP == getIRPosition() || !VisitValueCB(AVIRP))
10260 return indicatePessimisticFixpoint();
10261 return ChangeStatus::UNCHANGED;
10262 }
10263
10264 for (const auto &VAC : Values)
10265 if (!VisitValueCB(IRPosition::value(*VAC.getValue())))
10266 return indicatePessimisticFixpoint();
10267
10268 return ChangeStatus::UNCHANGED;
10269 }
10270
10271 /// See AbstractAttribute::trackStatistics()
10272 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noundef) }
10273};
10274
10275struct AANoUndefReturned final
10276 : AAReturnedFromReturnedValues<AANoUndef, AANoUndefImpl> {
10277 AANoUndefReturned(const IRPosition &IRP, Attributor &A)
10278 : AAReturnedFromReturnedValues<AANoUndef, AANoUndefImpl>(IRP, A) {}
10279
10280 /// See AbstractAttribute::trackStatistics()
10281 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noundef) }
10282};
10283
10284struct AANoUndefArgument final
10285 : AAArgumentFromCallSiteArguments<AANoUndef, AANoUndefImpl> {
10286 AANoUndefArgument(const IRPosition &IRP, Attributor &A)
10287 : AAArgumentFromCallSiteArguments<AANoUndef, AANoUndefImpl>(IRP, A) {}
10288
10289 /// See AbstractAttribute::trackStatistics()
10290 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noundef) }
10291};
10292
10293struct AANoUndefCallSiteArgument final : AANoUndefFloating {
10294 AANoUndefCallSiteArgument(const IRPosition &IRP, Attributor &A)
10295 : AANoUndefFloating(IRP, A) {}
10296
10297 /// See AbstractAttribute::trackStatistics()
10298 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(noundef) }
10299};
10300
10301struct AANoUndefCallSiteReturned final
10302 : AACalleeToCallSite<AANoUndef, AANoUndefImpl> {
10303 AANoUndefCallSiteReturned(const IRPosition &IRP, Attributor &A)
10304 : AACalleeToCallSite<AANoUndef, AANoUndefImpl>(IRP, A) {}
10305
10306 /// See AbstractAttribute::trackStatistics()
10307 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(noundef) }
10308};
10309
10310/// ------------------------ NoFPClass Attribute -------------------------------
10311
10312struct AANoFPClassImpl : AANoFPClass {
10313 AANoFPClassImpl(const IRPosition &IRP, Attributor &A) : AANoFPClass(IRP, A) {}
10314
10315 void initialize(Attributor &A) override {
10316 const IRPosition &IRP = getIRPosition();
10317
10318 Value &V = IRP.getAssociatedValue();
10319 if (isa<UndefValue>(V)) {
10320 indicateOptimisticFixpoint();
10321 return;
10322 }
10323
10325 A.getAttrs(getIRPosition(), {Attribute::NoFPClass}, Attrs, false);
10326 for (const auto &Attr : Attrs) {
10327 addKnownBits(Attr.getNoFPClass());
10328 }
10329
10330 const DataLayout &DL = A.getDataLayout();
10331 if (getPositionKind() != IRPosition::IRP_RETURNED) {
10333 addKnownBits(~KnownFPClass.KnownFPClasses);
10334 }
10335
10336 if (Instruction *CtxI = getCtxI())
10337 followUsesInMBEC(*this, A, getState(), *CtxI);
10338 }
10339
10340 /// See followUsesInMBEC
10341 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
10342 AANoFPClass::StateType &State) {
10343 // TODO: Determine what instructions can be looked through.
10344 auto *CB = dyn_cast<CallBase>(I);
10345 if (!CB)
10346 return false;
10347
10348 if (!CB->isArgOperand(U))
10349 return false;
10350
10351 unsigned ArgNo = CB->getArgOperandNo(U);
10352 IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo);
10353 if (auto *NoFPAA = A.getAAFor<AANoFPClass>(*this, IRP, DepClassTy::NONE))
10354 State.addKnownBits(NoFPAA->getState().getKnown());
10355 return false;
10356 }
10357
10358 const std::string getAsStr(Attributor *A) const override {
10359 std::string Result = "nofpclass";
10360 raw_string_ostream OS(Result);
10361 OS << getKnownNoFPClass() << '/' << getAssumedNoFPClass();
10362 return Result;
10363 }
10364
10365 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
10366 SmallVectorImpl<Attribute> &Attrs) const override {
10367 Attrs.emplace_back(Attribute::getWithNoFPClass(Ctx, getAssumedNoFPClass()));
10368 }
10369};
10370
10371struct AANoFPClassFloating : public AANoFPClassImpl {
10372 AANoFPClassFloating(const IRPosition &IRP, Attributor &A)
10373 : AANoFPClassImpl(IRP, A) {}
10374
10375 /// See AbstractAttribute::updateImpl(...).
10376 ChangeStatus updateImpl(Attributor &A) override {
10378 bool UsedAssumedInformation = false;
10379 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
10380 AA::AnyScope, UsedAssumedInformation)) {
10381 Values.push_back({getAssociatedValue(), getCtxI()});
10382 }
10383
10384 StateType T;
10385 auto VisitValueCB = [&](Value &V, const Instruction *CtxI) -> bool {
10386 const auto *AA = A.getAAFor<AANoFPClass>(*this, IRPosition::value(V),
10387 DepClassTy::REQUIRED);
10388 if (!AA || this == AA) {
10389 T.indicatePessimisticFixpoint();
10390 } else {
10391 const AANoFPClass::StateType &S =
10392 static_cast<const AANoFPClass::StateType &>(AA->getState());
10393 T ^= S;
10394 }
10395 return T.isValidState();
10396 };
10397
10398 for (const auto &VAC : Values)
10399 if (!VisitValueCB(*VAC.getValue(), VAC.getCtxI()))
10400 return indicatePessimisticFixpoint();
10401
10402 return clampStateAndIndicateChange(getState(), T);
10403 }
10404
10405 /// See AbstractAttribute::trackStatistics()
10406 void trackStatistics() const override {
10408 }
10409};
10410
10411struct AANoFPClassReturned final
10412 : AAReturnedFromReturnedValues<AANoFPClass, AANoFPClassImpl,
10413 AANoFPClassImpl::StateType, false,
10414 Attribute::None, false> {
10415 AANoFPClassReturned(const IRPosition &IRP, Attributor &A)
10416 : AAReturnedFromReturnedValues<AANoFPClass, AANoFPClassImpl,
10417 AANoFPClassImpl::StateType, false,
10418 Attribute::None, false>(IRP, A) {}
10419
10420 /// See AbstractAttribute::trackStatistics()
10421 void trackStatistics() const override {
10423 }
10424};
10425
10426struct AANoFPClassArgument final
10427 : AAArgumentFromCallSiteArguments<AANoFPClass, AANoFPClassImpl> {
10428 AANoFPClassArgument(const IRPosition &IRP, Attributor &A)
10429 : AAArgumentFromCallSiteArguments<AANoFPClass, AANoFPClassImpl>(IRP, A) {}
10430
10431 /// See AbstractAttribute::trackStatistics()
10432 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nofpclass) }
10433};
10434
10435struct AANoFPClassCallSiteArgument final : AANoFPClassFloating {
10436 AANoFPClassCallSiteArgument(const IRPosition &IRP, Attributor &A)
10437 : AANoFPClassFloating(IRP, A) {}
10438
10439 /// See AbstractAttribute::trackStatistics()
10440 void trackStatistics() const override {
10442 }
10443};
10444
10445struct AANoFPClassCallSiteReturned final
10446 : AACalleeToCallSite<AANoFPClass, AANoFPClassImpl> {
10447 AANoFPClassCallSiteReturned(const IRPosition &IRP, Attributor &A)
10448 : AACalleeToCallSite<AANoFPClass, AANoFPClassImpl>(IRP, A) {}
10449
10450 /// See AbstractAttribute::trackStatistics()
10451 void trackStatistics() const override {
10453 }
10454};
10455
10456struct AACallEdgesImpl : public AACallEdges {
10457 AACallEdgesImpl(const IRPosition &IRP, Attributor &A) : AACallEdges(IRP, A) {}
10458
10459 const SetVector<Function *> &getOptimisticEdges() const override {
10460 return CalledFunctions;
10461 }
10462
10463 bool hasUnknownCallee() const override { return HasUnknownCallee; }
10464
10465 bool hasNonAsmUnknownCallee() const override {
10466 return HasUnknownCalleeNonAsm;
10467 }
10468
10469 const std::string getAsStr(Attributor *A) const override {
10470 return "CallEdges[" + std::to_string(HasUnknownCallee) + "," +
10471 std::to_string(CalledFunctions.size()) + "]";
10472 }
10473
10474 void trackStatistics() const override {}
10475
10476protected:
10477 void addCalledFunction(Function *Fn, ChangeStatus &Change) {
10478 if (CalledFunctions.insert(Fn)) {
10479 Change = ChangeStatus::CHANGED;
10480 LLVM_DEBUG(dbgs() << "[AACallEdges] New call edge: " << Fn->getName()
10481 << "\n");
10482 }
10483 }
10484
10485 void setHasUnknownCallee(bool NonAsm, ChangeStatus &Change) {
10486 if (!HasUnknownCallee)
10487 Change = ChangeStatus::CHANGED;
10488 if (NonAsm && !HasUnknownCalleeNonAsm)
10489 Change = ChangeStatus::CHANGED;
10490 HasUnknownCalleeNonAsm |= NonAsm;
10491 HasUnknownCallee = true;
10492 }
10493
10494private:
10495 /// Optimistic set of functions that might be called by this position.
10496 SetVector<Function *> CalledFunctions;
10497
10498 /// Is there any call with a unknown callee.
10499 bool HasUnknownCallee = false;
10500
10501 /// Is there any call with a unknown callee, excluding any inline asm.
10502 bool HasUnknownCalleeNonAsm = false;
10503};
10504
10505struct AACallEdgesCallSite : public AACallEdgesImpl {
10506 AACallEdgesCallSite(const IRPosition &IRP, Attributor &A)
10507 : AACallEdgesImpl(IRP, A) {}
10508 /// See AbstractAttribute::updateImpl(...).
10509 ChangeStatus updateImpl(Attributor &A) override {
10510 ChangeStatus Change = ChangeStatus::UNCHANGED;
10511
10512 auto VisitValue = [&](Value &V, const Instruction *CtxI) -> bool {
10513 if (Function *Fn = dyn_cast<Function>(&V)) {
10514 addCalledFunction(Fn, Change);
10515 } else {
10516 LLVM_DEBUG(dbgs() << "[AACallEdges] Unrecognized value: " << V << "\n");
10517 setHasUnknownCallee(true, Change);
10518 }
10519
10520 // Explore all values.
10521 return true;
10522 };
10523
10525 // Process any value that we might call.
10526 auto ProcessCalledOperand = [&](Value *V, Instruction *CtxI) {
10527 if (isa<Constant>(V)) {
10528 VisitValue(*V, CtxI);
10529 return;
10530 }
10531
10532 bool UsedAssumedInformation = false;
10533 Values.clear();
10534 if (!A.getAssumedSimplifiedValues(IRPosition::value(*V), *this, Values,
10535 AA::AnyScope, UsedAssumedInformation)) {
10536 Values.push_back({*V, CtxI});
10537 }
10538 for (auto &VAC : Values)
10539 VisitValue(*VAC.getValue(), VAC.getCtxI());
10540 };
10541
10542 CallBase *CB = cast<CallBase>(getCtxI());
10543
10544 if (auto *IA = dyn_cast<InlineAsm>(CB->getCalledOperand())) {
10545 if (IA->hasSideEffects() &&
10546 !hasAssumption(*CB->getCaller(), "ompx_no_call_asm") &&
10547 !hasAssumption(*CB, "ompx_no_call_asm")) {
10548 setHasUnknownCallee(false, Change);
10549 }
10550 return Change;
10551 }
10552
10553 if (CB->isIndirectCall())
10554 if (auto *IndirectCallAA = A.getAAFor<AAIndirectCallInfo>(
10555 *this, getIRPosition(), DepClassTy::OPTIONAL))
10556 if (IndirectCallAA->foreachCallee(
10557 [&](Function *Fn) { return VisitValue(*Fn, CB); }))
10558 return Change;
10559
10560 // The most simple case.
10561 ProcessCalledOperand(CB->getCalledOperand(), CB);
10562
10563 // Process callback functions.
10564 SmallVector<const Use *, 4u> CallbackUses;
10565 AbstractCallSite::getCallbackUses(*CB, CallbackUses);
10566 for (const Use *U : CallbackUses)
10567 ProcessCalledOperand(U->get(), CB);
10568
10569 return Change;
10570 }
10571};
10572
10573struct AACallEdgesFunction : public AACallEdgesImpl {
10574 AACallEdgesFunction(const IRPosition &IRP, Attributor &A)
10575 : AACallEdgesImpl(IRP, A) {}
10576
10577 /// See AbstractAttribute::updateImpl(...).
10578 ChangeStatus updateImpl(Attributor &A) override {
10579 ChangeStatus Change = ChangeStatus::UNCHANGED;
10580
10581 auto ProcessCallInst = [&](Instruction &Inst) {
10582 CallBase &CB = cast<CallBase>(Inst);
10583
10584 auto *CBEdges = A.getAAFor<AACallEdges>(
10585 *this, IRPosition::callsite_function(CB), DepClassTy::REQUIRED);
10586 if (!CBEdges)
10587 return false;
10588 if (CBEdges->hasNonAsmUnknownCallee())
10589 setHasUnknownCallee(true, Change);
10590 if (CBEdges->hasUnknownCallee())
10591 setHasUnknownCallee(false, Change);
10592
10593 for (Function *F : CBEdges->getOptimisticEdges())
10594 addCalledFunction(F, Change);
10595
10596 return true;
10597 };
10598
10599 // Visit all callable instructions.
10600 bool UsedAssumedInformation = false;
10601 if (!A.checkForAllCallLikeInstructions(ProcessCallInst, *this,
10602 UsedAssumedInformation,
10603 /* CheckBBLivenessOnly */ true)) {
10604 // If we haven't looked at all call like instructions, assume that there
10605 // are unknown callees.
10606 setHasUnknownCallee(true, Change);
10607 }
10608
10609 return Change;
10610 }
10611};
10612
10613/// -------------------AAInterFnReachability Attribute--------------------------
10614
10615struct AAInterFnReachabilityFunction
10616 : public CachedReachabilityAA<AAInterFnReachability, Function> {
10617 using Base = CachedReachabilityAA<AAInterFnReachability, Function>;
10618 AAInterFnReachabilityFunction(const IRPosition &IRP, Attributor &A)
10619 : Base(IRP, A) {}
10620
10621 bool instructionCanReach(
10622 Attributor &A, const Instruction &From, const Function &To,
10623 const AA::InstExclusionSetTy *ExclusionSet) const override {
10624 assert(From.getFunction() == getAnchorScope() && "Queried the wrong AA!");
10625 auto *NonConstThis = const_cast<AAInterFnReachabilityFunction *>(this);
10626
10627 RQITy StackRQI(A, From, To, ExclusionSet, false);
10628 typename RQITy::Reachable Result;
10629 if (!NonConstThis->checkQueryCache(A, StackRQI, Result))
10630 return NonConstThis->isReachableImpl(A, StackRQI,
10631 /*IsTemporaryRQI=*/true);
10632 return Result == RQITy::Reachable::Yes;
10633 }
10634
10635 bool isReachableImpl(Attributor &A, RQITy &RQI,
10636 bool IsTemporaryRQI) override {
10637 const Instruction *EntryI =
10638 &RQI.From->getFunction()->getEntryBlock().front();
10639 if (EntryI != RQI.From &&
10640 !instructionCanReach(A, *EntryI, *RQI.To, nullptr))
10641 return rememberResult(A, RQITy::Reachable::No, RQI, false,
10642 IsTemporaryRQI);
10643
10644 auto CheckReachableCallBase = [&](CallBase *CB) {
10645 auto *CBEdges = A.getAAFor<AACallEdges>(
10646 *this, IRPosition::callsite_function(*CB), DepClassTy::OPTIONAL);
10647 if (!CBEdges || !CBEdges->getState().isValidState())
10648 return false;
10649 // TODO Check To backwards in this case.
10650 if (CBEdges->hasUnknownCallee())
10651 return false;
10652
10653 for (Function *Fn : CBEdges->getOptimisticEdges()) {
10654 if (Fn == RQI.To)
10655 return false;
10656
10657 if (Fn->isDeclaration()) {
10658 if (Fn->hasFnAttribute(Attribute::NoCallback))
10659 continue;
10660 // TODO Check To backwards in this case.
10661 return false;
10662 }
10663
10664 if (Fn == getAnchorScope()) {
10665 if (EntryI == RQI.From)
10666 continue;
10667 return false;
10668 }
10669
10670 const AAInterFnReachability *InterFnReachability =
10671 A.getAAFor<AAInterFnReachability>(*this, IRPosition::function(*Fn),
10672 DepClassTy::OPTIONAL);
10673
10674 const Instruction &FnFirstInst = Fn->getEntryBlock().front();
10675 if (!InterFnReachability ||
10676 InterFnReachability->instructionCanReach(A, FnFirstInst, *RQI.To,
10677 RQI.ExclusionSet))
10678 return false;
10679 }
10680 return true;
10681 };
10682
10683 const auto *IntraFnReachability = A.getAAFor<AAIntraFnReachability>(
10684 *this, IRPosition::function(*RQI.From->getFunction()),
10685 DepClassTy::OPTIONAL);
10686
10687 // Determine call like instructions that we can reach from the inst.
10688 auto CheckCallBase = [&](Instruction &CBInst) {
10689 // There are usually less nodes in the call graph, check inter function
10690 // reachability first.
10691 if (CheckReachableCallBase(cast<CallBase>(&CBInst)))
10692 return true;
10693 return IntraFnReachability && !IntraFnReachability->isAssumedReachable(
10694 A, *RQI.From, CBInst, RQI.ExclusionSet);
10695 };
10696
10697 bool UsedExclusionSet = /* conservative */ true;
10698 bool UsedAssumedInformation = false;
10699 if (!A.checkForAllCallLikeInstructions(CheckCallBase, *this,
10700 UsedAssumedInformation,
10701 /* CheckBBLivenessOnly */ true))
10702 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
10703 IsTemporaryRQI);
10704
10705 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
10706 IsTemporaryRQI);
10707 }
10708
10709 void trackStatistics() const override {}
10710};
10711} // namespace
10712
10713template <typename AAType>
10714static std::optional<Constant *>
10716 const IRPosition &IRP, Type &Ty) {
10717 if (!Ty.isIntegerTy())
10718 return nullptr;
10719
10720 // This will also pass the call base context.
10721 const auto *AA = A.getAAFor<AAType>(QueryingAA, IRP, DepClassTy::NONE);
10722 if (!AA)
10723 return nullptr;
10724
10725 std::optional<Constant *> COpt = AA->getAssumedConstant(A);
10726
10727 if (!COpt.has_value()) {
10728 A.recordDependence(*AA, QueryingAA, DepClassTy::OPTIONAL);
10729 return std::nullopt;
10730 }
10731 if (auto *C = *COpt) {
10732 A.recordDependence(*AA, QueryingAA, DepClassTy::OPTIONAL);
10733 return C;
10734 }
10735 return nullptr;
10736}
10737
10739 Attributor &A, const AbstractAttribute &AA, const IRPosition &IRP,
10741 Type &Ty = *IRP.getAssociatedType();
10742 std::optional<Value *> V;
10743 for (auto &It : Values) {
10744 V = AA::combineOptionalValuesInAAValueLatice(V, It.getValue(), &Ty);
10745 if (V.has_value() && !*V)
10746 break;
10747 }
10748 if (!V.has_value())
10749 return UndefValue::get(&Ty);
10750 return *V;
10751}
10752
10753namespace {
10754struct AAPotentialValuesImpl : AAPotentialValues {
10755 using StateType = PotentialLLVMValuesState;
10756
10757 AAPotentialValuesImpl(const IRPosition &IRP, Attributor &A)
10758 : AAPotentialValues(IRP, A) {}
10759
10760 /// See AbstractAttribute::initialize(..).
10761 void initialize(Attributor &A) override {
10762 if (A.hasSimplificationCallback(getIRPosition())) {
10763 indicatePessimisticFixpoint();
10764 return;
10765 }
10766 Value *Stripped = getAssociatedValue().stripPointerCasts();
10767 if (isa<Constant>(Stripped) && !isa<ConstantExpr>(Stripped)) {
10768 addValue(A, getState(), *Stripped, getCtxI(), AA::AnyScope,
10769 getAnchorScope());
10770 indicateOptimisticFixpoint();
10771 return;
10772 }
10773 AAPotentialValues::initialize(A);
10774 }
10775
10776 /// See AbstractAttribute::getAsStr().
10777 const std::string getAsStr(Attributor *A) const override {
10778 std::string Str;
10780 OS << getState();
10781 return OS.str();
10782 }
10783
10784 template <typename AAType>
10785 static std::optional<Value *> askOtherAA(Attributor &A,
10786 const AbstractAttribute &AA,
10787 const IRPosition &IRP, Type &Ty) {
10788 if (isa<Constant>(IRP.getAssociatedValue()))
10789 return &IRP.getAssociatedValue();
10790 std::optional<Constant *> C = askForAssumedConstant<AAType>(A, AA, IRP, Ty);
10791 if (!C)
10792 return std::nullopt;
10793 if (*C)
10794 if (auto *CC = AA::getWithType(**C, Ty))
10795 return CC;
10796 return nullptr;
10797 }
10798
10799 virtual void addValue(Attributor &A, StateType &State, Value &V,
10800 const Instruction *CtxI, AA::ValueScope S,
10801 Function *AnchorScope) const {
10802
10803 IRPosition ValIRP = IRPosition::value(V);
10804 if (auto *CB = dyn_cast_or_null<CallBase>(CtxI)) {
10805 for (const auto &U : CB->args()) {
10806 if (U.get() != &V)
10807 continue;
10808 ValIRP = IRPosition::callsite_argument(*CB, CB->getArgOperandNo(&U));
10809 break;
10810 }
10811 }
10812
10813 Value *VPtr = &V;
10814 if (ValIRP.getAssociatedType()->isIntegerTy()) {
10815 Type &Ty = *getAssociatedType();
10816 std::optional<Value *> SimpleV =
10817 askOtherAA<AAValueConstantRange>(A, *this, ValIRP, Ty);
10818 if (SimpleV.has_value() && !*SimpleV) {
10819 auto *PotentialConstantsAA = A.getAAFor<AAPotentialConstantValues>(
10820 *this, ValIRP, DepClassTy::OPTIONAL);
10821 if (PotentialConstantsAA && PotentialConstantsAA->isValidState()) {
10822 for (const auto &It : PotentialConstantsAA->getAssumedSet())
10823 State.unionAssumed({{*ConstantInt::get(&Ty, It), nullptr}, S});
10824 if (PotentialConstantsAA->undefIsContained())
10825 State.unionAssumed({{*UndefValue::get(&Ty), nullptr}, S});
10826 return;
10827 }
10828 }
10829 if (!SimpleV.has_value())
10830 return;
10831
10832 if (*SimpleV)
10833 VPtr = *SimpleV;
10834 }
10835
10836 if (isa<ConstantInt>(VPtr))
10837 CtxI = nullptr;
10838 if (!AA::isValidInScope(*VPtr, AnchorScope))
10840
10841 State.unionAssumed({{*VPtr, CtxI}, S});
10842 }
10843
10844 /// Helper struct to tie a value+context pair together with the scope for
10845 /// which this is the simplified version.
10846 struct ItemInfo {
10849
10850 bool operator==(const ItemInfo &II) const {
10851 return II.I == I && II.S == S;
10852 };
10853 bool operator<(const ItemInfo &II) const {
10854 if (I == II.I)
10855 return S < II.S;
10856 return I < II.I;
10857 };
10858 };
10859
10860 bool recurseForValue(Attributor &A, const IRPosition &IRP, AA::ValueScope S) {
10862 for (auto CS : {AA::Intraprocedural, AA::Interprocedural}) {
10863 if (!(CS & S))
10864 continue;
10865
10866 bool UsedAssumedInformation = false;
10868 if (!A.getAssumedSimplifiedValues(IRP, this, Values, CS,
10869 UsedAssumedInformation))
10870 return false;
10871
10872 for (auto &It : Values)
10873 ValueScopeMap[It] += CS;
10874 }
10875 for (auto &It : ValueScopeMap)
10876 addValue(A, getState(), *It.first.getValue(), It.first.getCtxI(),
10877 AA::ValueScope(It.second), getAnchorScope());
10878
10879 return true;
10880 }
10881
10882 void giveUpOnIntraprocedural(Attributor &A) {
10883 auto NewS = StateType::getBestState(getState());
10884 for (const auto &It : getAssumedSet()) {
10885 if (It.second == AA::Intraprocedural)
10886 continue;
10887 addValue(A, NewS, *It.first.getValue(), It.first.getCtxI(),
10888 AA::Interprocedural, getAnchorScope());
10889 }
10890 assert(!undefIsContained() && "Undef should be an explicit value!");
10891 addValue(A, NewS, getAssociatedValue(), getCtxI(), AA::Intraprocedural,
10892 getAnchorScope());
10893 getState() = NewS;
10894 }
10895
10896 /// See AbstractState::indicatePessimisticFixpoint(...).
10897 ChangeStatus indicatePessimisticFixpoint() override {
10898 getState() = StateType::getBestState(getState());
10899 getState().unionAssumed({{getAssociatedValue(), getCtxI()}, AA::AnyScope});
10901 return ChangeStatus::CHANGED;
10902 }
10903
10904 /// See AbstractAttribute::updateImpl(...).
10905 ChangeStatus updateImpl(Attributor &A) override {
10906 return indicatePessimisticFixpoint();
10907 }
10908
10909 /// See AbstractAttribute::manifest(...).
10910 ChangeStatus manifest(Attributor &A) override {
10913 Values.clear();
10914 if (!getAssumedSimplifiedValues(A, Values, S))
10915 continue;
10916 Value &OldV = getAssociatedValue();
10917 if (isa<UndefValue>(OldV))
10918 continue;
10919 Value *NewV = getSingleValue(A, *this, getIRPosition(), Values);
10920 if (!NewV || NewV == &OldV)
10921 continue;
10922 if (getCtxI() &&
10923 !AA::isValidAtPosition({*NewV, *getCtxI()}, A.getInfoCache()))
10924 continue;
10925 if (A.changeAfterManifest(getIRPosition(), *NewV))
10926 return ChangeStatus::CHANGED;
10927 }
10929 }
10930
10931 bool getAssumedSimplifiedValues(
10933 AA::ValueScope S, bool RecurseForSelectAndPHI = false) const override {
10934 if (!isValidState())
10935 return false;
10936 bool UsedAssumedInformation = false;
10937 for (const auto &It : getAssumedSet())
10938 if (It.second & S) {
10939 if (RecurseForSelectAndPHI && (isa<PHINode>(It.first.getValue()) ||
10940 isa<SelectInst>(It.first.getValue()))) {
10941 if (A.getAssumedSimplifiedValues(
10942 IRPosition::inst(*cast<Instruction>(It.first.getValue())),
10943 this, Values, S, UsedAssumedInformation))
10944 continue;
10945 }
10946 Values.push_back(It.first);
10947 }
10948 assert(!undefIsContained() && "Undef should be an explicit value!");
10949 return true;
10950 }
10951};
10952
10953struct AAPotentialValuesFloating : AAPotentialValuesImpl {
10954 AAPotentialValuesFloating(const IRPosition &IRP, Attributor &A)
10955 : AAPotentialValuesImpl(IRP, A) {}
10956
10957 /// See AbstractAttribute::updateImpl(...).
10958 ChangeStatus updateImpl(Attributor &A) override {
10959 auto AssumedBefore = getAssumed();
10960
10961 genericValueTraversal(A, &getAssociatedValue());
10962
10963 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
10964 : ChangeStatus::CHANGED;
10965 }
10966
10967 /// Helper struct to remember which AAIsDead instances we actually used.
10968 struct LivenessInfo {
10969 const AAIsDead *LivenessAA = nullptr;
10970 bool AnyDead = false;
10971 };
10972
10973 /// Check if \p Cmp is a comparison we can simplify.
10974 ///
10975 /// We handle multiple cases, one in which at least one operand is an
10976 /// (assumed) nullptr. If so, try to simplify it using AANonNull on the other
10977 /// operand. Return true if successful, in that case Worklist will be updated.
10978 bool handleCmp(Attributor &A, Value &Cmp, Value *LHS, Value *RHS,
10979 CmpInst::Predicate Pred, ItemInfo II,
10980 SmallVectorImpl<ItemInfo> &Worklist) {
10981
10982 // Simplify the operands first.
10983 bool UsedAssumedInformation = false;
10984 SmallVector<AA::ValueAndContext> LHSValues, RHSValues;
10985 auto GetSimplifiedValues = [&](Value &V,
10987 if (!A.getAssumedSimplifiedValues(
10988 IRPosition::value(V, getCallBaseContext()), this, Values,
10989 AA::Intraprocedural, UsedAssumedInformation)) {
10990 Values.clear();
10991 Values.push_back(AA::ValueAndContext{V, II.I.getCtxI()});
10992 }
10993 return Values.empty();
10994 };
10995 if (GetSimplifiedValues(*LHS, LHSValues))
10996 return true;
10997 if (GetSimplifiedValues(*RHS, RHSValues))
10998 return true;
10999
11000 LLVMContext &Ctx = LHS->getContext();
11001
11002 InformationCache &InfoCache = A.getInfoCache();
11003 Instruction *CmpI = dyn_cast<Instruction>(&Cmp);
11004 Function *F = CmpI ? CmpI->getFunction() : nullptr;
11005 const auto *DT =
11007 : nullptr;
11008 const auto *TLI =
11009 F ? A.getInfoCache().getTargetLibraryInfoForFunction(*F) : nullptr;
11010 auto *AC =
11012 : nullptr;
11013
11014 const DataLayout &DL = A.getDataLayout();
11015 SimplifyQuery Q(DL, TLI, DT, AC, CmpI);
11016
11017 auto CheckPair = [&](Value &LHSV, Value &RHSV) {
11018 if (isa<UndefValue>(LHSV) || isa<UndefValue>(RHSV)) {
11019 addValue(A, getState(), *UndefValue::get(Cmp.getType()),
11020 /* CtxI */ nullptr, II.S, getAnchorScope());
11021 return true;
11022 }
11023
11024 // Handle the trivial case first in which we don't even need to think
11025 // about null or non-null.
11026 if (&LHSV == &RHSV &&
11028 Constant *NewV = ConstantInt::get(Type::getInt1Ty(Ctx),
11030 addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S,
11031 getAnchorScope());
11032 return true;
11033 }
11034
11035 auto *TypedLHS = AA::getWithType(LHSV, *LHS->getType());
11036 auto *TypedRHS = AA::getWithType(RHSV, *RHS->getType());
11037 if (TypedLHS && TypedRHS) {
11038 Value *NewV = simplifyCmpInst(Pred, TypedLHS, TypedRHS, Q);
11039 if (NewV && NewV != &Cmp) {
11040 addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S,
11041 getAnchorScope());
11042 return true;
11043 }
11044 }
11045
11046 // From now on we only handle equalities (==, !=).
11047 if (!CmpInst::isEquality(Pred))
11048 return false;
11049
11050 bool LHSIsNull = isa<ConstantPointerNull>(LHSV);
11051 bool RHSIsNull = isa<ConstantPointerNull>(RHSV);
11052 if (!LHSIsNull && !RHSIsNull)
11053 return false;
11054
11055 // Left is the nullptr ==/!= non-nullptr case. We'll use AANonNull on the
11056 // non-nullptr operand and if we assume it's non-null we can conclude the
11057 // result of the comparison.
11058 assert((LHSIsNull || RHSIsNull) &&
11059 "Expected nullptr versus non-nullptr comparison at this point");
11060
11061 // The index is the operand that we assume is not null.
11062 unsigned PtrIdx = LHSIsNull;
11063 bool IsKnownNonNull;
11064 bool IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>(
11065 A, this, IRPosition::value(*(PtrIdx ? &RHSV : &LHSV)),
11066 DepClassTy::REQUIRED, IsKnownNonNull);
11067 if (!IsAssumedNonNull)
11068 return false;
11069
11070 // The new value depends on the predicate, true for != and false for ==.
11071 Constant *NewV =
11072 ConstantInt::get(Type::getInt1Ty(Ctx), Pred == CmpInst::ICMP_NE);
11073 addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S,
11074 getAnchorScope());
11075 return true;
11076 };
11077
11078 for (auto &LHSValue : LHSValues)
11079 for (auto &RHSValue : RHSValues)
11080 if (!CheckPair(*LHSValue.getValue(), *RHSValue.getValue()))
11081 return false;
11082 return true;
11083 }
11084
11085 bool handleSelectInst(Attributor &A, SelectInst &SI, ItemInfo II,
11086 SmallVectorImpl<ItemInfo> &Worklist) {
11087 const Instruction *CtxI = II.I.getCtxI();
11088 bool UsedAssumedInformation = false;
11089
11090 std::optional<Constant *> C =
11091 A.getAssumedConstant(*SI.getCondition(), *this, UsedAssumedInformation);
11092 bool NoValueYet = !C.has_value();
11093 if (NoValueYet || isa_and_nonnull<UndefValue>(*C))
11094 return true;
11095 if (auto *CI = dyn_cast_or_null<ConstantInt>(*C)) {
11096 if (CI->isZero())
11097 Worklist.push_back({{*SI.getFalseValue(), CtxI}, II.S});
11098 else
11099 Worklist.push_back({{*SI.getTrueValue(), CtxI}, II.S});
11100 } else if (&SI == &getAssociatedValue()) {
11101 // We could not simplify the condition, assume both values.
11102 Worklist.push_back({{*SI.getTrueValue(), CtxI}, II.S});
11103 Worklist.push_back({{*SI.getFalseValue(), CtxI}, II.S});
11104 } else {
11105 std::optional<Value *> SimpleV = A.getAssumedSimplified(
11106 IRPosition::inst(SI), *this, UsedAssumedInformation, II.S);
11107 if (!SimpleV.has_value())
11108 return true;
11109 if (*SimpleV) {
11110 addValue(A, getState(), **SimpleV, CtxI, II.S, getAnchorScope());
11111 return true;
11112 }
11113 return false;
11114 }
11115 return true;
11116 }
11117
11118 bool handleLoadInst(Attributor &A, LoadInst &LI, ItemInfo II,
11119 SmallVectorImpl<ItemInfo> &Worklist) {
11120 SmallSetVector<Value *, 4> PotentialCopies;
11121 SmallSetVector<Instruction *, 4> PotentialValueOrigins;
11122 bool UsedAssumedInformation = false;
11123 if (!AA::getPotentiallyLoadedValues(A, LI, PotentialCopies,
11124 PotentialValueOrigins, *this,
11125 UsedAssumedInformation,
11126 /* OnlyExact */ true)) {
11127 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Failed to get potentially "
11128 "loaded values for load instruction "
11129 << LI << "\n");
11130 return false;
11131 }
11132
11133 // Do not simplify loads that are only used in llvm.assume if we cannot also
11134 // remove all stores that may feed into the load. The reason is that the
11135 // assume is probably worth something as long as the stores are around.
11136 InformationCache &InfoCache = A.getInfoCache();
11137 if (InfoCache.isOnlyUsedByAssume(LI)) {
11138 if (!llvm::all_of(PotentialValueOrigins, [&](Instruction *I) {
11139 if (!I || isa<AssumeInst>(I))
11140 return true;
11141 if (auto *SI = dyn_cast<StoreInst>(I))
11142 return A.isAssumedDead(SI->getOperandUse(0), this,
11143 /* LivenessAA */ nullptr,
11144 UsedAssumedInformation,
11145 /* CheckBBLivenessOnly */ false);
11146 return A.isAssumedDead(*I, this, /* LivenessAA */ nullptr,
11147 UsedAssumedInformation,
11148 /* CheckBBLivenessOnly */ false);
11149 })) {
11150 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Load is onl used by assumes "
11151 "and we cannot delete all the stores: "
11152 << LI << "\n");
11153 return false;
11154 }
11155 }
11156
11157 // Values have to be dynamically unique or we loose the fact that a
11158 // single llvm::Value might represent two runtime values (e.g.,
11159 // stack locations in different recursive calls).
11160 const Instruction *CtxI = II.I.getCtxI();
11161 bool ScopeIsLocal = (II.S & AA::Intraprocedural);
11162 bool AllLocal = ScopeIsLocal;
11163 bool DynamicallyUnique = llvm::all_of(PotentialCopies, [&](Value *PC) {
11164 AllLocal &= AA::isValidInScope(*PC, getAnchorScope());
11165 return AA::isDynamicallyUnique(A, *this, *PC);
11166 });
11167 if (!DynamicallyUnique) {
11168 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Not all potentially loaded "
11169 "values are dynamically unique: "
11170 << LI << "\n");
11171 return false;
11172 }
11173
11174 for (auto *PotentialCopy : PotentialCopies) {
11175 if (AllLocal) {
11176 Worklist.push_back({{*PotentialCopy, CtxI}, II.S});
11177 } else {
11178 Worklist.push_back({{*PotentialCopy, CtxI}, AA::Interprocedural});
11179 }
11180 }
11181 if (!AllLocal && ScopeIsLocal)
11182 addValue(A, getState(), LI, CtxI, AA::Intraprocedural, getAnchorScope());
11183 return true;
11184 }
11185
11186 bool handlePHINode(
11187 Attributor &A, PHINode &PHI, ItemInfo II,
11188 SmallVectorImpl<ItemInfo> &Worklist,
11190 auto GetLivenessInfo = [&](const Function &F) -> LivenessInfo & {
11191 LivenessInfo &LI = LivenessAAs[&F];
11192 if (!LI.LivenessAA)
11193 LI.LivenessAA = A.getAAFor<AAIsDead>(*this, IRPosition::function(F),
11194 DepClassTy::NONE);
11195 return LI;
11196 };
11197
11198 if (&PHI == &getAssociatedValue()) {
11199 LivenessInfo &LI = GetLivenessInfo(*PHI.getFunction());
11200 const auto *CI =
11201 A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>(
11202 *PHI.getFunction());
11203
11204 Cycle *C = nullptr;
11205 bool CyclePHI = mayBeInCycle(CI, &PHI, /* HeaderOnly */ true, &C);
11206 for (unsigned u = 0, e = PHI.getNumIncomingValues(); u < e; u++) {
11207 BasicBlock *IncomingBB = PHI.getIncomingBlock(u);
11208 if (LI.LivenessAA &&
11209 LI.LivenessAA->isEdgeDead(IncomingBB, PHI.getParent())) {
11210 LI.AnyDead = true;
11211 continue;
11212 }
11213 Value *V = PHI.getIncomingValue(u);
11214 if (V == &PHI)
11215 continue;
11216
11217 // If the incoming value is not the PHI but an instruction in the same
11218 // cycle we might have multiple versions of it flying around.
11219 if (CyclePHI && isa<Instruction>(V) &&
11220 (!C || C->contains(cast<Instruction>(V)->getParent())))
11221 return false;
11222
11223 Worklist.push_back({{*V, IncomingBB->getTerminator()}, II.S});
11224 }
11225 return true;
11226 }
11227
11228 bool UsedAssumedInformation = false;
11229 std::optional<Value *> SimpleV = A.getAssumedSimplified(
11230 IRPosition::inst(PHI), *this, UsedAssumedInformation, II.S);
11231 if (!SimpleV.has_value())
11232 return true;
11233 if (!(*SimpleV))
11234 return false;
11235 addValue(A, getState(), **SimpleV, &PHI, II.S, getAnchorScope());
11236 return true;
11237 }
11238
11239 /// Use the generic, non-optimistic InstSimplfy functionality if we managed to
11240 /// simplify any operand of the instruction \p I. Return true if successful,
11241 /// in that case Worklist will be updated.
11242 bool handleGenericInst(Attributor &A, Instruction &I, ItemInfo II,
11243 SmallVectorImpl<ItemInfo> &Worklist) {
11244 bool SomeSimplified = false;
11245 bool UsedAssumedInformation = false;
11246
11247 SmallVector<Value *, 8> NewOps(I.getNumOperands());
11248 int Idx = 0;
11249 for (Value *Op : I.operands()) {
11250 const auto &SimplifiedOp = A.getAssumedSimplified(
11251 IRPosition::value(*Op, getCallBaseContext()), *this,
11252 UsedAssumedInformation, AA::Intraprocedural);
11253 // If we are not sure about any operand we are not sure about the entire
11254 // instruction, we'll wait.
11255 if (!SimplifiedOp.has_value())
11256 return true;
11257
11258 if (*SimplifiedOp)
11259 NewOps[Idx] = *SimplifiedOp;
11260 else
11261 NewOps[Idx] = Op;
11262
11263 SomeSimplified |= (NewOps[Idx] != Op);
11264 ++Idx;
11265 }
11266
11267 // We won't bother with the InstSimplify interface if we didn't simplify any
11268 // operand ourselves.
11269 if (!SomeSimplified)
11270 return false;
11271
11272 InformationCache &InfoCache = A.getInfoCache();
11273 Function *F = I.getFunction();
11274 const auto *DT =
11276 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
11277 auto *AC = InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F);
11278
11279 const DataLayout &DL = I.getDataLayout();
11280 SimplifyQuery Q(DL, TLI, DT, AC, &I);
11281 Value *NewV = simplifyInstructionWithOperands(&I, NewOps, Q);
11282 if (!NewV || NewV == &I)
11283 return false;
11284
11285 LLVM_DEBUG(dbgs() << "Generic inst " << I << " assumed simplified to "
11286 << *NewV << "\n");
11287 Worklist.push_back({{*NewV, II.I.getCtxI()}, II.S});
11288 return true;
11289 }
11290
11292 Attributor &A, Instruction &I, ItemInfo II,
11293 SmallVectorImpl<ItemInfo> &Worklist,
11295 if (auto *CI = dyn_cast<CmpInst>(&I))
11296 return handleCmp(A, *CI, CI->getOperand(0), CI->getOperand(1),
11297 CI->getPredicate(), II, Worklist);
11298
11299 switch (I.getOpcode()) {
11300 case Instruction::Select:
11301 return handleSelectInst(A, cast<SelectInst>(I), II, Worklist);
11302 case Instruction::PHI:
11303 return handlePHINode(A, cast<PHINode>(I), II, Worklist, LivenessAAs);
11304 case Instruction::Load:
11305 return handleLoadInst(A, cast<LoadInst>(I), II, Worklist);
11306 default:
11307 return handleGenericInst(A, I, II, Worklist);
11308 };
11309 return false;
11310 }
11311
11312 void genericValueTraversal(Attributor &A, Value *InitialV) {
11314
11315 SmallSet<ItemInfo, 16> Visited;
11317 Worklist.push_back({{*InitialV, getCtxI()}, AA::AnyScope});
11318
11319 int Iteration = 0;
11320 do {
11321 ItemInfo II = Worklist.pop_back_val();
11322 Value *V = II.I.getValue();
11323 assert(V);
11324 const Instruction *CtxI = II.I.getCtxI();
11325 AA::ValueScope S = II.S;
11326
11327 // Check if we should process the current value. To prevent endless
11328 // recursion keep a record of the values we followed!
11329 if (!Visited.insert(II).second)
11330 continue;
11331
11332 // Make sure we limit the compile time for complex expressions.
11333 if (Iteration++ >= MaxPotentialValuesIterations) {
11334 LLVM_DEBUG(dbgs() << "Generic value traversal reached iteration limit: "
11335 << Iteration << "!\n");
11336 addValue(A, getState(), *V, CtxI, S, getAnchorScope());
11337 continue;
11338 }
11339
11340 // Explicitly look through calls with a "returned" attribute if we do
11341 // not have a pointer as stripPointerCasts only works on them.
11342 Value *NewV = nullptr;
11343 if (V->getType()->isPointerTy()) {
11344 NewV = AA::getWithType(*V->stripPointerCasts(), *V->getType());
11345 } else {
11346 if (auto *CB = dyn_cast<CallBase>(V))
11347 if (auto *Callee =
11348 dyn_cast_if_present<Function>(CB->getCalledOperand())) {
11349 for (Argument &Arg : Callee->args())
11350 if (Arg.hasReturnedAttr()) {
11351 NewV = CB->getArgOperand(Arg.getArgNo());
11352 break;
11353 }
11354 }
11355 }
11356 if (NewV && NewV != V) {
11357 Worklist.push_back({{*NewV, CtxI}, S});
11358 continue;
11359 }
11360
11361 if (auto *I = dyn_cast<Instruction>(V)) {
11362 if (simplifyInstruction(A, *I, II, Worklist, LivenessAAs))
11363 continue;
11364 }
11365
11366 if (V != InitialV || isa<Argument>(V))
11367 if (recurseForValue(A, IRPosition::value(*V), II.S))
11368 continue;
11369
11370 // If we haven't stripped anything we give up.
11371 if (V == InitialV && CtxI == getCtxI()) {
11372 indicatePessimisticFixpoint();
11373 return;
11374 }
11375
11376 addValue(A, getState(), *V, CtxI, S, getAnchorScope());
11377 } while (!Worklist.empty());
11378
11379 // If we actually used liveness information so we have to record a
11380 // dependence.
11381 for (auto &It : LivenessAAs)
11382 if (It.second.AnyDead)
11383 A.recordDependence(*It.second.LivenessAA, *this, DepClassTy::OPTIONAL);
11384 }
11385
11386 /// See AbstractAttribute::trackStatistics()
11387 void trackStatistics() const override {
11388 STATS_DECLTRACK_FLOATING_ATTR(potential_values)
11389 }
11390};
11391
11392struct AAPotentialValuesArgument final : AAPotentialValuesImpl {
11393 using Base = AAPotentialValuesImpl;
11394 AAPotentialValuesArgument(const IRPosition &IRP, Attributor &A)
11395 : Base(IRP, A) {}
11396
11397 /// See AbstractAttribute::initialize(..).
11398 void initialize(Attributor &A) override {
11399 auto &Arg = cast<Argument>(getAssociatedValue());
11401 indicatePessimisticFixpoint();
11402 }
11403
11404 /// See AbstractAttribute::updateImpl(...).
11405 ChangeStatus updateImpl(Attributor &A) override {
11406 auto AssumedBefore = getAssumed();
11407
11408 unsigned ArgNo = getCalleeArgNo();
11409
11410 bool UsedAssumedInformation = false;
11412 auto CallSitePred = [&](AbstractCallSite ACS) {
11413 const auto CSArgIRP = IRPosition::callsite_argument(ACS, ArgNo);
11414 if (CSArgIRP.getPositionKind() == IRP_INVALID)
11415 return false;
11416
11417 if (!A.getAssumedSimplifiedValues(CSArgIRP, this, Values,
11419 UsedAssumedInformation))
11420 return false;
11421
11422 return isValidState();
11423 };
11424
11425 if (!A.checkForAllCallSites(CallSitePred, *this,
11426 /* RequireAllCallSites */ true,
11427 UsedAssumedInformation))
11428 return indicatePessimisticFixpoint();
11429
11430 Function *Fn = getAssociatedFunction();
11431 bool AnyNonLocal = false;
11432 for (auto &It : Values) {
11433 if (isa<Constant>(It.getValue())) {
11434 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::AnyScope,
11435 getAnchorScope());
11436 continue;
11437 }
11438 if (!AA::isDynamicallyUnique(A, *this, *It.getValue()))
11439 return indicatePessimisticFixpoint();
11440
11441 if (auto *Arg = dyn_cast<Argument>(It.getValue()))
11442 if (Arg->getParent() == Fn) {
11443 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::AnyScope,
11444 getAnchorScope());
11445 continue;
11446 }
11447 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::Interprocedural,
11448 getAnchorScope());
11449 AnyNonLocal = true;
11450 }
11451 assert(!undefIsContained() && "Undef should be an explicit value!");
11452 if (AnyNonLocal)
11453 giveUpOnIntraprocedural(A);
11454
11455 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
11456 : ChangeStatus::CHANGED;
11457 }
11458
11459 /// See AbstractAttribute::trackStatistics()
11460 void trackStatistics() const override {
11461 STATS_DECLTRACK_ARG_ATTR(potential_values)
11462 }
11463};
11464
11465struct AAPotentialValuesReturned : public AAPotentialValuesFloating {
11466 using Base = AAPotentialValuesFloating;
11467 AAPotentialValuesReturned(const IRPosition &IRP, Attributor &A)
11468 : Base(IRP, A) {}
11469
11470 /// See AbstractAttribute::initialize(..).
11471 void initialize(Attributor &A) override {
11472 Function *F = getAssociatedFunction();
11473 if (!F || F->isDeclaration() || F->getReturnType()->isVoidTy()) {
11474 indicatePessimisticFixpoint();
11475 return;
11476 }
11477
11478 for (Argument &Arg : F->args())
11479 if (Arg.hasReturnedAttr()) {
11480 addValue(A, getState(), Arg, nullptr, AA::AnyScope, F);
11481 ReturnedArg = &Arg;
11482 break;
11483 }
11484 if (!A.isFunctionIPOAmendable(*F) ||
11485 A.hasSimplificationCallback(getIRPosition())) {
11486 if (!ReturnedArg)
11487 indicatePessimisticFixpoint();
11488 else
11489 indicateOptimisticFixpoint();
11490 }
11491 }
11492
11493 /// See AbstractAttribute::updateImpl(...).
11494 ChangeStatus updateImpl(Attributor &A) override {
11495 auto AssumedBefore = getAssumed();
11496 bool UsedAssumedInformation = false;
11497
11499 Function *AnchorScope = getAnchorScope();
11500 auto HandleReturnedValue = [&](Value &V, Instruction *CtxI,
11501 bool AddValues) {
11503 Values.clear();
11504 if (!A.getAssumedSimplifiedValues(IRPosition::value(V), this, Values, S,
11505 UsedAssumedInformation,
11506 /* RecurseForSelectAndPHI */ true))
11507 return false;
11508 if (!AddValues)
11509 continue;
11510 for (const AA::ValueAndContext &VAC : Values)
11511 addValue(A, getState(), *VAC.getValue(),
11512 VAC.getCtxI() ? VAC.getCtxI() : CtxI, S, AnchorScope);
11513 }
11514 return true;
11515 };
11516
11517 if (ReturnedArg) {
11518 HandleReturnedValue(*ReturnedArg, nullptr, true);
11519 } else {
11520 auto RetInstPred = [&](Instruction &RetI) {
11521 bool AddValues = true;
11522 if (isa<PHINode>(RetI.getOperand(0)) ||
11523 isa<SelectInst>(RetI.getOperand(0))) {
11524 addValue(A, getState(), *RetI.getOperand(0), &RetI, AA::AnyScope,
11525 AnchorScope);
11526 AddValues = false;
11527 }
11528 return HandleReturnedValue(*RetI.getOperand(0), &RetI, AddValues);
11529 };
11530
11531 if (!A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret},
11532 UsedAssumedInformation,
11533 /* CheckBBLivenessOnly */ true))
11534 return indicatePessimisticFixpoint();
11535 }
11536
11537 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
11538 : ChangeStatus::CHANGED;
11539 }
11540
11541 void addValue(Attributor &A, StateType &State, Value &V,
11542 const Instruction *CtxI, AA::ValueScope S,
11543 Function *AnchorScope) const override {
11544 Function *F = getAssociatedFunction();
11545 if (auto *CB = dyn_cast<CallBase>(&V))
11546 if (CB->getCalledOperand() == F)
11547 return;
11548 Base::addValue(A, State, V, CtxI, S, AnchorScope);
11549 }
11550
11551 ChangeStatus manifest(Attributor &A) override {
11552 if (ReturnedArg)
11553 return ChangeStatus::UNCHANGED;
11555 if (!getAssumedSimplifiedValues(A, Values, AA::ValueScope::Intraprocedural,
11556 /* RecurseForSelectAndPHI */ true))
11557 return ChangeStatus::UNCHANGED;
11558 Value *NewVal = getSingleValue(A, *this, getIRPosition(), Values);
11559 if (!NewVal)
11560 return ChangeStatus::UNCHANGED;
11561
11562 ChangeStatus Changed = ChangeStatus::UNCHANGED;
11563 if (auto *Arg = dyn_cast<Argument>(NewVal)) {
11564 STATS_DECLTRACK(UniqueReturnValue, FunctionReturn,
11565 "Number of function with unique return");
11566 Changed |= A.manifestAttrs(
11568 {Attribute::get(Arg->getContext(), Attribute::Returned)});
11569 STATS_DECLTRACK_ARG_ATTR(returned);
11570 }
11571
11572 auto RetInstPred = [&](Instruction &RetI) {
11573 Value *RetOp = RetI.getOperand(0);
11574 if (isa<UndefValue>(RetOp) || RetOp == NewVal)
11575 return true;
11576 if (AA::isValidAtPosition({*NewVal, RetI}, A.getInfoCache()))
11577 if (A.changeUseAfterManifest(RetI.getOperandUse(0), *NewVal))
11578 Changed = ChangeStatus::CHANGED;
11579 return true;
11580 };
11581 bool UsedAssumedInformation = false;
11582 (void)A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret},
11583 UsedAssumedInformation,
11584 /* CheckBBLivenessOnly */ true);
11585 return Changed;
11586 }
11587
11588 ChangeStatus indicatePessimisticFixpoint() override {
11590 }
11591
11592 /// See AbstractAttribute::trackStatistics()
11593 void trackStatistics() const override{
11594 STATS_DECLTRACK_FNRET_ATTR(potential_values)}
11595
11596 /// The argumented with an existing `returned` attribute.
11597 Argument *ReturnedArg = nullptr;
11598};
11599
11600struct AAPotentialValuesFunction : AAPotentialValuesImpl {
11601 AAPotentialValuesFunction(const IRPosition &IRP, Attributor &A)
11602 : AAPotentialValuesImpl(IRP, A) {}
11603
11604 /// See AbstractAttribute::updateImpl(...).
11605 ChangeStatus updateImpl(Attributor &A) override {
11606 llvm_unreachable("AAPotentialValues(Function|CallSite)::updateImpl will "
11607 "not be called");
11608 }
11609
11610 /// See AbstractAttribute::trackStatistics()
11611 void trackStatistics() const override {
11612 STATS_DECLTRACK_FN_ATTR(potential_values)
11613 }
11614};
11615
11616struct AAPotentialValuesCallSite : AAPotentialValuesFunction {
11617 AAPotentialValuesCallSite(const IRPosition &IRP, Attributor &A)
11618 : AAPotentialValuesFunction(IRP, A) {}
11619
11620 /// See AbstractAttribute::trackStatistics()
11621 void trackStatistics() const override {
11622 STATS_DECLTRACK_CS_ATTR(potential_values)
11623 }
11624};
11625
11626struct AAPotentialValuesCallSiteReturned : AAPotentialValuesImpl {
11627 AAPotentialValuesCallSiteReturned(const IRPosition &IRP, Attributor &A)
11628 : AAPotentialValuesImpl(IRP, A) {}
11629
11630 /// See AbstractAttribute::updateImpl(...).
11631 ChangeStatus updateImpl(Attributor &A) override {
11632 auto AssumedBefore = getAssumed();
11633
11634 Function *Callee = getAssociatedFunction();
11635 if (!Callee)
11636 return indicatePessimisticFixpoint();
11637
11638 bool UsedAssumedInformation = false;
11639 auto *CB = cast<CallBase>(getCtxI());
11640 if (CB->isMustTailCall() &&
11641 !A.isAssumedDead(IRPosition::inst(*CB), this, nullptr,
11642 UsedAssumedInformation))
11643 return indicatePessimisticFixpoint();
11644
11646 if (!A.getAssumedSimplifiedValues(IRPosition::returned(*Callee), this,
11647 Values, AA::Intraprocedural,
11648 UsedAssumedInformation))
11649 return indicatePessimisticFixpoint();
11650
11651 Function *Caller = CB->getCaller();
11652
11653 bool AnyNonLocal = false;
11654 for (auto &It : Values) {
11655 Value *V = It.getValue();
11656 std::optional<Value *> CallerV = A.translateArgumentToCallSiteContent(
11657 V, *CB, *this, UsedAssumedInformation);
11658 if (!CallerV.has_value()) {
11659 // Nothing to do as long as no value was determined.
11660 continue;
11661 }
11662 V = *CallerV ? *CallerV : V;
11663 if (AA::isDynamicallyUnique(A, *this, *V) &&
11664 AA::isValidInScope(*V, Caller)) {
11665 if (*CallerV) {
11667 IRPosition IRP = IRPosition::value(*V);
11668 if (auto *Arg = dyn_cast<Argument>(V))
11669 if (Arg->getParent() == CB->getCalledOperand())
11670 IRP = IRPosition::callsite_argument(*CB, Arg->getArgNo());
11671 if (recurseForValue(A, IRP, AA::AnyScope))
11672 continue;
11673 }
11674 addValue(A, getState(), *V, CB, AA::AnyScope, getAnchorScope());
11675 } else {
11676 AnyNonLocal = true;
11677 break;
11678 }
11679 }
11680 if (AnyNonLocal) {
11681 Values.clear();
11682 if (!A.getAssumedSimplifiedValues(IRPosition::returned(*Callee), this,
11683 Values, AA::Interprocedural,
11684 UsedAssumedInformation))
11685 return indicatePessimisticFixpoint();
11686 AnyNonLocal = false;
11688 for (auto &It : Values) {
11689 Value *V = It.getValue();
11690 if (!AA::isDynamicallyUnique(A, *this, *V))
11691 return indicatePessimisticFixpoint();
11692 if (AA::isValidInScope(*V, Caller)) {
11693 addValue(A, getState(), *V, CB, AA::AnyScope, getAnchorScope());
11694 } else {
11695 AnyNonLocal = true;
11696 addValue(A, getState(), *V, CB, AA::Interprocedural,
11697 getAnchorScope());
11698 }
11699 }
11700 if (AnyNonLocal)
11701 giveUpOnIntraprocedural(A);
11702 }
11703 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
11704 : ChangeStatus::CHANGED;
11705 }
11706
11707 ChangeStatus indicatePessimisticFixpoint() override {
11708 return AAPotentialValues::indicatePessimisticFixpoint();
11709 }
11710
11711 /// See AbstractAttribute::trackStatistics()
11712 void trackStatistics() const override {
11713 STATS_DECLTRACK_CSRET_ATTR(potential_values)
11714 }
11715};
11716
11717struct AAPotentialValuesCallSiteArgument : AAPotentialValuesFloating {
11718 AAPotentialValuesCallSiteArgument(const IRPosition &IRP, Attributor &A)
11719 : AAPotentialValuesFloating(IRP, A) {}
11720
11721 /// See AbstractAttribute::trackStatistics()
11722 void trackStatistics() const override {
11723 STATS_DECLTRACK_CSARG_ATTR(potential_values)
11724 }
11725};
11726} // namespace
11727
11728/// ---------------------- Assumption Propagation ------------------------------
11729namespace {
11730struct AAAssumptionInfoImpl : public AAAssumptionInfo {
11731 AAAssumptionInfoImpl(const IRPosition &IRP, Attributor &A,
11732 const DenseSet<StringRef> &Known)
11733 : AAAssumptionInfo(IRP, A, Known) {}
11734
11735 /// See AbstractAttribute::manifest(...).
11736 ChangeStatus manifest(Attributor &A) override {
11737 // Don't manifest a universal set if it somehow made it here.
11738 if (getKnown().isUniversal())
11739 return ChangeStatus::UNCHANGED;
11740
11741 const IRPosition &IRP = getIRPosition();
11742 SmallVector<StringRef, 0> Set(getAssumed().getSet().begin(),
11743 getAssumed().getSet().end());
11744 llvm::sort(Set);
11745 return A.manifestAttrs(IRP,
11748 llvm::join(Set, ",")),
11749 /*ForceReplace=*/true);
11750 }
11751
11752 bool hasAssumption(const StringRef Assumption) const override {
11753 return isValidState() && setContains(Assumption);
11754 }
11755
11756 /// See AbstractAttribute::getAsStr()
11757 const std::string getAsStr(Attributor *A) const override {
11758 const SetContents &Known = getKnown();
11759 const SetContents &Assumed = getAssumed();
11760
11761 SmallVector<StringRef, 0> Set(Known.getSet().begin(), Known.getSet().end());
11762 llvm::sort(Set);
11763 const std::string KnownStr = llvm::join(Set, ",");
11764
11765 std::string AssumedStr = "Universal";
11766 if (!Assumed.isUniversal()) {
11767 Set.assign(Assumed.getSet().begin(), Assumed.getSet().end());
11768 AssumedStr = llvm::join(Set, ",");
11769 }
11770 return "Known [" + KnownStr + "]," + " Assumed [" + AssumedStr + "]";
11771 }
11772};
11773
11774/// Propagates assumption information from parent functions to all of their
11775/// successors. An assumption can be propagated if the containing function
11776/// dominates the called function.
11777///
11778/// We start with a "known" set of assumptions already valid for the associated
11779/// function and an "assumed" set that initially contains all possible
11780/// assumptions. The assumed set is inter-procedurally updated by narrowing its
11781/// contents as concrete values are known. The concrete values are seeded by the
11782/// first nodes that are either entries into the call graph, or contains no
11783/// assumptions. Each node is updated as the intersection of the assumed state
11784/// with all of its predecessors.
11785struct AAAssumptionInfoFunction final : AAAssumptionInfoImpl {
11786 AAAssumptionInfoFunction(const IRPosition &IRP, Attributor &A)
11787 : AAAssumptionInfoImpl(IRP, A,
11788 getAssumptions(*IRP.getAssociatedFunction())) {}
11789
11790 /// See AbstractAttribute::updateImpl(...).
11791 ChangeStatus updateImpl(Attributor &A) override {
11792 bool Changed = false;
11793
11794 auto CallSitePred = [&](AbstractCallSite ACS) {
11795 const auto *AssumptionAA = A.getAAFor<AAAssumptionInfo>(
11796 *this, IRPosition::callsite_function(*ACS.getInstruction()),
11797 DepClassTy::REQUIRED);
11798 if (!AssumptionAA)
11799 return false;
11800 // Get the set of assumptions shared by all of this function's callers.
11801 Changed |= getIntersection(AssumptionAA->getAssumed());
11802 return !getAssumed().empty() || !getKnown().empty();
11803 };
11804
11805 bool UsedAssumedInformation = false;
11806 // Get the intersection of all assumptions held by this node's predecessors.
11807 // If we don't know all the call sites then this is either an entry into the
11808 // call graph or an empty node. This node is known to only contain its own
11809 // assumptions and can be propagated to its successors.
11810 if (!A.checkForAllCallSites(CallSitePred, *this, true,
11811 UsedAssumedInformation))
11812 return indicatePessimisticFixpoint();
11813
11814 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
11815 }
11816
11817 void trackStatistics() const override {}
11818};
11819
11820/// Assumption Info defined for call sites.
11821struct AAAssumptionInfoCallSite final : AAAssumptionInfoImpl {
11822
11823 AAAssumptionInfoCallSite(const IRPosition &IRP, Attributor &A)
11824 : AAAssumptionInfoImpl(IRP, A, getInitialAssumptions(IRP)) {}
11825
11826 /// See AbstractAttribute::initialize(...).
11827 void initialize(Attributor &A) override {
11828 const IRPosition &FnPos = IRPosition::function(*getAnchorScope());
11829 A.getAAFor<AAAssumptionInfo>(*this, FnPos, DepClassTy::REQUIRED);
11830 }
11831
11832 /// See AbstractAttribute::updateImpl(...).
11833 ChangeStatus updateImpl(Attributor &A) override {
11834 const IRPosition &FnPos = IRPosition::function(*getAnchorScope());
11835 auto *AssumptionAA =
11836 A.getAAFor<AAAssumptionInfo>(*this, FnPos, DepClassTy::REQUIRED);
11837 if (!AssumptionAA)
11838 return indicatePessimisticFixpoint();
11839 bool Changed = getIntersection(AssumptionAA->getAssumed());
11840 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
11841 }
11842
11843 /// See AbstractAttribute::trackStatistics()
11844 void trackStatistics() const override {}
11845
11846private:
11847 /// Helper to initialized the known set as all the assumptions this call and
11848 /// the callee contain.
11849 DenseSet<StringRef> getInitialAssumptions(const IRPosition &IRP) {
11850 const CallBase &CB = cast<CallBase>(IRP.getAssociatedValue());
11851 auto Assumptions = getAssumptions(CB);
11852 if (const Function *F = CB.getCaller())
11853 set_union(Assumptions, getAssumptions(*F));
11854 if (Function *F = IRP.getAssociatedFunction())
11855 set_union(Assumptions, getAssumptions(*F));
11856 return Assumptions;
11857 }
11858};
11859} // namespace
11860
11862 return static_cast<AACallGraphNode *>(const_cast<AACallEdges *>(
11863 A.getOrCreateAAFor<AACallEdges>(IRPosition::function(**I))));
11864}
11865
11867
11868/// ------------------------ UnderlyingObjects ---------------------------------
11869
11870namespace {
11871struct AAUnderlyingObjectsImpl
11872 : StateWrapper<BooleanState, AAUnderlyingObjects> {
11874 AAUnderlyingObjectsImpl(const IRPosition &IRP, Attributor &A) : BaseTy(IRP) {}
11875
11876 /// See AbstractAttribute::getAsStr().
11877 const std::string getAsStr(Attributor *A) const override {
11878 return std::string("UnderlyingObjects ") +
11879 (isValidState()
11880 ? (std::string("inter #") +
11881 std::to_string(InterAssumedUnderlyingObjects.size()) +
11882 " objs" + std::string(", intra #") +
11883 std::to_string(IntraAssumedUnderlyingObjects.size()) +
11884 " objs")
11885 : "<invalid>");
11886 }
11887
11888 /// See AbstractAttribute::trackStatistics()
11889 void trackStatistics() const override {}
11890
11891 /// See AbstractAttribute::updateImpl(...).
11892 ChangeStatus updateImpl(Attributor &A) override {
11893 auto &Ptr = getAssociatedValue();
11894
11895 auto DoUpdate = [&](SmallSetVector<Value *, 8> &UnderlyingObjects,
11897 bool UsedAssumedInformation = false;
11898 SmallPtrSet<Value *, 8> SeenObjects;
11900
11901 if (!A.getAssumedSimplifiedValues(IRPosition::value(Ptr), *this, Values,
11902 Scope, UsedAssumedInformation))
11903 return UnderlyingObjects.insert(&Ptr);
11904
11905 bool Changed = false;
11906
11907 for (unsigned I = 0; I < Values.size(); ++I) {
11908 auto &VAC = Values[I];
11909 auto *Obj = VAC.getValue();
11910 Value *UO = getUnderlyingObject(Obj);
11911 if (UO && UO != VAC.getValue() && SeenObjects.insert(UO).second) {
11912 const auto *OtherAA = A.getAAFor<AAUnderlyingObjects>(
11913 *this, IRPosition::value(*UO), DepClassTy::OPTIONAL);
11914 auto Pred = [&Values](Value &V) {
11915 Values.emplace_back(V, nullptr);
11916 return true;
11917 };
11918
11919 if (!OtherAA || !OtherAA->forallUnderlyingObjects(Pred, Scope))
11921 "The forall call should not return false at this position");
11922
11923 continue;
11924 }
11925
11926 if (isa<SelectInst>(Obj)) {
11927 Changed |= handleIndirect(A, *Obj, UnderlyingObjects, Scope);
11928 continue;
11929 }
11930 if (auto *PHI = dyn_cast<PHINode>(Obj)) {
11931 // Explicitly look through PHIs as we do not care about dynamically
11932 // uniqueness.
11933 for (unsigned u = 0, e = PHI->getNumIncomingValues(); u < e; u++) {
11934 Changed |= handleIndirect(A, *PHI->getIncomingValue(u),
11935 UnderlyingObjects, Scope);
11936 }
11937 continue;
11938 }
11939
11940 Changed |= UnderlyingObjects.insert(Obj);
11941 }
11942
11943 return Changed;
11944 };
11945
11946 bool Changed = false;
11947 Changed |= DoUpdate(IntraAssumedUnderlyingObjects, AA::Intraprocedural);
11948 Changed |= DoUpdate(InterAssumedUnderlyingObjects, AA::Interprocedural);
11949
11950 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
11951 }
11952
11953 bool forallUnderlyingObjects(
11954 function_ref<bool(Value &)> Pred,
11955 AA::ValueScope Scope = AA::Interprocedural) const override {
11956 if (!isValidState())
11957 return Pred(getAssociatedValue());
11958
11959 auto &AssumedUnderlyingObjects = Scope == AA::Intraprocedural
11960 ? IntraAssumedUnderlyingObjects
11961 : InterAssumedUnderlyingObjects;
11962 for (Value *Obj : AssumedUnderlyingObjects)
11963 if (!Pred(*Obj))
11964 return false;
11965
11966 return true;
11967 }
11968
11969private:
11970 /// Handle the case where the value is not the actual underlying value, such
11971 /// as a phi node or a select instruction.
11972 bool handleIndirect(Attributor &A, Value &V,
11973 SmallSetVector<Value *, 8> &UnderlyingObjects,
11974 AA::ValueScope Scope) {
11975 bool Changed = false;
11976 const auto *AA = A.getAAFor<AAUnderlyingObjects>(
11977 *this, IRPosition::value(V), DepClassTy::OPTIONAL);
11978 auto Pred = [&](Value &V) {
11979 Changed |= UnderlyingObjects.insert(&V);
11980 return true;
11981 };
11982 if (!AA || !AA->forallUnderlyingObjects(Pred, Scope))
11984 "The forall call should not return false at this position");
11985 return Changed;
11986 }
11987
11988 /// All the underlying objects collected so far via intra procedural scope.
11989 SmallSetVector<Value *, 8> IntraAssumedUnderlyingObjects;
11990 /// All the underlying objects collected so far via inter procedural scope.
11991 SmallSetVector<Value *, 8> InterAssumedUnderlyingObjects;
11992};
11993
11994struct AAUnderlyingObjectsFloating final : AAUnderlyingObjectsImpl {
11995 AAUnderlyingObjectsFloating(const IRPosition &IRP, Attributor &A)
11996 : AAUnderlyingObjectsImpl(IRP, A) {}
11997};
11998
11999struct AAUnderlyingObjectsArgument final : AAUnderlyingObjectsImpl {
12000 AAUnderlyingObjectsArgument(const IRPosition &IRP, Attributor &A)
12001 : AAUnderlyingObjectsImpl(IRP, A) {}
12002};
12003
12004struct AAUnderlyingObjectsCallSite final : AAUnderlyingObjectsImpl {
12005 AAUnderlyingObjectsCallSite(const IRPosition &IRP, Attributor &A)
12006 : AAUnderlyingObjectsImpl(IRP, A) {}
12007};
12008
12009struct AAUnderlyingObjectsCallSiteArgument final : AAUnderlyingObjectsImpl {
12010 AAUnderlyingObjectsCallSiteArgument(const IRPosition &IRP, Attributor &A)
12011 : AAUnderlyingObjectsImpl(IRP, A) {}
12012};
12013
12014struct AAUnderlyingObjectsReturned final : AAUnderlyingObjectsImpl {
12015 AAUnderlyingObjectsReturned(const IRPosition &IRP, Attributor &A)
12016 : AAUnderlyingObjectsImpl(IRP, A) {}
12017};
12018
12019struct AAUnderlyingObjectsCallSiteReturned final : AAUnderlyingObjectsImpl {
12020 AAUnderlyingObjectsCallSiteReturned(const IRPosition &IRP, Attributor &A)
12021 : AAUnderlyingObjectsImpl(IRP, A) {}
12022};
12023
12024struct AAUnderlyingObjectsFunction final : AAUnderlyingObjectsImpl {
12025 AAUnderlyingObjectsFunction(const IRPosition &IRP, Attributor &A)
12026 : AAUnderlyingObjectsImpl(IRP, A) {}
12027};
12028} // namespace
12029
12030/// ------------------------ Global Value Info -------------------------------
12031namespace {
12032struct AAGlobalValueInfoFloating : public AAGlobalValueInfo {
12033 AAGlobalValueInfoFloating(const IRPosition &IRP, Attributor &A)
12034 : AAGlobalValueInfo(IRP, A) {}
12035
12036 /// See AbstractAttribute::initialize(...).
12037 void initialize(Attributor &A) override {}
12038
12039 bool checkUse(Attributor &A, const Use &U, bool &Follow,
12041 Instruction *UInst = dyn_cast<Instruction>(U.getUser());
12042 if (!UInst) {
12043 Follow = true;
12044 return true;
12045 }
12046
12047 LLVM_DEBUG(dbgs() << "[AAGlobalValueInfo] Check use: " << *U.get() << " in "
12048 << *UInst << "\n");
12049
12050 if (auto *Cmp = dyn_cast<ICmpInst>(U.getUser())) {
12051 int Idx = &Cmp->getOperandUse(0) == &U;
12052 if (isa<Constant>(Cmp->getOperand(Idx)))
12053 return true;
12054 return U == &getAnchorValue();
12055 }
12056
12057 // Explicitly catch return instructions.
12058 if (isa<ReturnInst>(UInst)) {
12059 auto CallSitePred = [&](AbstractCallSite ACS) {
12060 Worklist.push_back(ACS.getInstruction());
12061 return true;
12062 };
12063 bool UsedAssumedInformation = false;
12064 // TODO: We should traverse the uses or add a "non-call-site" CB.
12065 if (!A.checkForAllCallSites(CallSitePred, *UInst->getFunction(),
12066 /*RequireAllCallSites=*/true, this,
12067 UsedAssumedInformation))
12068 return false;
12069 return true;
12070 }
12071
12072 // For now we only use special logic for call sites. However, the tracker
12073 // itself knows about a lot of other non-capturing cases already.
12074 auto *CB = dyn_cast<CallBase>(UInst);
12075 if (!CB)
12076 return false;
12077 // Direct calls are OK uses.
12078 if (CB->isCallee(&U))
12079 return true;
12080 // Non-argument uses are scary.
12081 if (!CB->isArgOperand(&U))
12082 return false;
12083 // TODO: Iterate callees.
12084 auto *Fn = dyn_cast<Function>(CB->getCalledOperand());
12085 if (!Fn || !A.isFunctionIPOAmendable(*Fn))
12086 return false;
12087
12088 unsigned ArgNo = CB->getArgOperandNo(&U);
12089 Worklist.push_back(Fn->getArg(ArgNo));
12090 return true;
12091 }
12092
12093 ChangeStatus updateImpl(Attributor &A) override {
12094 unsigned NumUsesBefore = Uses.size();
12095
12098 Worklist.push_back(&getAnchorValue());
12099
12100 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
12101 Uses.insert(&U);
12102 switch (DetermineUseCaptureKind(U, nullptr)) {
12103 case UseCaptureKind::NO_CAPTURE:
12104 return checkUse(A, U, Follow, Worklist);
12105 case UseCaptureKind::MAY_CAPTURE:
12106 return checkUse(A, U, Follow, Worklist);
12107 case UseCaptureKind::PASSTHROUGH:
12108 Follow = true;
12109 return true;
12110 }
12111 return true;
12112 };
12113 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) {
12114 Uses.insert(&OldU);
12115 return true;
12116 };
12117
12118 while (!Worklist.empty()) {
12119 const Value *V = Worklist.pop_back_val();
12120 if (!Visited.insert(V).second)
12121 continue;
12122 if (!A.checkForAllUses(UsePred, *this, *V,
12123 /* CheckBBLivenessOnly */ true,
12124 DepClassTy::OPTIONAL,
12125 /* IgnoreDroppableUses */ true, EquivalentUseCB)) {
12126 return indicatePessimisticFixpoint();
12127 }
12128 }
12129
12130 return Uses.size() == NumUsesBefore ? ChangeStatus::UNCHANGED
12131 : ChangeStatus::CHANGED;
12132 }
12133
12134 bool isPotentialUse(const Use &U) const override {
12135 return !isValidState() || Uses.contains(&U);
12136 }
12137
12138 /// See AbstractAttribute::manifest(...).
12139 ChangeStatus manifest(Attributor &A) override {
12140 return ChangeStatus::UNCHANGED;
12141 }
12142
12143 /// See AbstractAttribute::getAsStr().
12144 const std::string getAsStr(Attributor *A) const override {
12145 return "[" + std::to_string(Uses.size()) + " uses]";
12146 }
12147
12148 void trackStatistics() const override {
12149 STATS_DECLTRACK_FLOATING_ATTR(GlobalValuesTracked);
12150 }
12151
12152private:
12153 /// Set of (transitive) uses of this GlobalValue.
12155};
12156} // namespace
12157
12158/// ------------------------ Indirect Call Info -------------------------------
12159namespace {
12160struct AAIndirectCallInfoCallSite : public AAIndirectCallInfo {
12161 AAIndirectCallInfoCallSite(const IRPosition &IRP, Attributor &A)
12162 : AAIndirectCallInfo(IRP, A) {}
12163
12164 /// See AbstractAttribute::initialize(...).
12165 void initialize(Attributor &A) override {
12166 auto *MD = getCtxI()->getMetadata(LLVMContext::MD_callees);
12167 if (!MD && !A.isClosedWorldModule())
12168 return;
12169
12170 if (MD) {
12171 for (const auto &Op : MD->operands())
12172 if (Function *Callee = mdconst::dyn_extract_or_null<Function>(Op))
12173 PotentialCallees.insert(Callee);
12174 } else if (A.isClosedWorldModule()) {
12175 ArrayRef<Function *> IndirectlyCallableFunctions =
12176 A.getInfoCache().getIndirectlyCallableFunctions(A);
12177 PotentialCallees.insert(IndirectlyCallableFunctions.begin(),
12178 IndirectlyCallableFunctions.end());
12179 }
12180
12181 if (PotentialCallees.empty())
12182 indicateOptimisticFixpoint();
12183 }
12184
12185 ChangeStatus updateImpl(Attributor &A) override {
12186 CallBase *CB = cast<CallBase>(getCtxI());
12187 const Use &CalleeUse = CB->getCalledOperandUse();
12188 Value *FP = CB->getCalledOperand();
12189
12190 SmallSetVector<Function *, 4> AssumedCalleesNow;
12191 bool AllCalleesKnownNow = AllCalleesKnown;
12192
12193 auto CheckPotentialCalleeUse = [&](Function &PotentialCallee,
12194 bool &UsedAssumedInformation) {
12195 const auto *GIAA = A.getAAFor<AAGlobalValueInfo>(
12196 *this, IRPosition::value(PotentialCallee), DepClassTy::OPTIONAL);
12197 if (!GIAA || GIAA->isPotentialUse(CalleeUse))
12198 return true;
12199 UsedAssumedInformation = !GIAA->isAtFixpoint();
12200 return false;
12201 };
12202
12203 auto AddPotentialCallees = [&]() {
12204 for (auto *PotentialCallee : PotentialCallees) {
12205 bool UsedAssumedInformation = false;
12206 if (CheckPotentialCalleeUse(*PotentialCallee, UsedAssumedInformation))
12207 AssumedCalleesNow.insert(PotentialCallee);
12208 }
12209 };
12210
12211 // Use simplification to find potential callees, if !callees was present,
12212 // fallback to that set if necessary.
12213 bool UsedAssumedInformation = false;
12215 if (!A.getAssumedSimplifiedValues(IRPosition::value(*FP), this, Values,
12216 AA::ValueScope::AnyScope,
12217 UsedAssumedInformation)) {
12218 if (PotentialCallees.empty())
12219 return indicatePessimisticFixpoint();
12220 AddPotentialCallees();
12221 }
12222
12223 // Try to find a reason for \p Fn not to be a potential callee. If none was
12224 // found, add it to the assumed callees set.
12225 auto CheckPotentialCallee = [&](Function &Fn) {
12226 if (!PotentialCallees.empty() && !PotentialCallees.count(&Fn))
12227 return false;
12228
12229 auto &CachedResult = FilterResults[&Fn];
12230 if (CachedResult.has_value())
12231 return CachedResult.value();
12232
12233 bool UsedAssumedInformation = false;
12234 if (!CheckPotentialCalleeUse(Fn, UsedAssumedInformation)) {
12235 if (!UsedAssumedInformation)
12236 CachedResult = false;
12237 return false;
12238 }
12239
12240 int NumFnArgs = Fn.arg_size();
12241 int NumCBArgs = CB->arg_size();
12242
12243 // Check if any excess argument (which we fill up with poison) is known to
12244 // be UB on undef.
12245 for (int I = NumCBArgs; I < NumFnArgs; ++I) {
12246 bool IsKnown = false;
12247 if (AA::hasAssumedIRAttr<Attribute::NoUndef>(
12248 A, this, IRPosition::argument(*Fn.getArg(I)),
12249 DepClassTy::OPTIONAL, IsKnown)) {
12250 if (IsKnown)
12251 CachedResult = false;
12252 return false;
12253 }
12254 }
12255
12256 CachedResult = true;
12257 return true;
12258 };
12259
12260 // Check simplification result, prune known UB callees, also restrict it to
12261 // the !callees set, if present.
12262 for (auto &VAC : Values) {
12263 if (isa<UndefValue>(VAC.getValue()))
12264 continue;
12265 if (isa<ConstantPointerNull>(VAC.getValue()) &&
12266 VAC.getValue()->getType()->getPointerAddressSpace() == 0)
12267 continue;
12268 // TODO: Check for known UB, e.g., poison + noundef.
12269 if (auto *VACFn = dyn_cast<Function>(VAC.getValue())) {
12270 if (CheckPotentialCallee(*VACFn))
12271 AssumedCalleesNow.insert(VACFn);
12272 continue;
12273 }
12274 if (!PotentialCallees.empty()) {
12275 AddPotentialCallees();
12276 break;
12277 }
12278 AllCalleesKnownNow = false;
12279 }
12280
12281 if (AssumedCalleesNow == AssumedCallees &&
12282 AllCalleesKnown == AllCalleesKnownNow)
12283 return ChangeStatus::UNCHANGED;
12284
12285 std::swap(AssumedCallees, AssumedCalleesNow);
12286 AllCalleesKnown = AllCalleesKnownNow;
12287 return ChangeStatus::CHANGED;
12288 }
12289
12290 /// See AbstractAttribute::manifest(...).
12291 ChangeStatus manifest(Attributor &A) override {
12292 // If we can't specialize at all, give up now.
12293 if (!AllCalleesKnown && AssumedCallees.empty())
12294 return ChangeStatus::UNCHANGED;
12295
12296 CallBase *CB = cast<CallBase>(getCtxI());
12297 bool UsedAssumedInformation = false;
12298 if (A.isAssumedDead(*CB, this, /*LivenessAA=*/nullptr,
12299 UsedAssumedInformation))
12300 return ChangeStatus::UNCHANGED;
12301
12302 ChangeStatus Changed = ChangeStatus::UNCHANGED;
12303 Value *FP = CB->getCalledOperand();
12304 if (FP->getType()->getPointerAddressSpace())
12305 FP = new AddrSpaceCastInst(FP, PointerType::get(FP->getType(), 0),
12306 FP->getName() + ".as0", CB->getIterator());
12307
12308 bool CBIsVoid = CB->getType()->isVoidTy();
12310 FunctionType *CSFT = CB->getFunctionType();
12311 SmallVector<Value *> CSArgs(CB->arg_begin(), CB->arg_end());
12312
12313 // If we know all callees and there are none, the call site is (effectively)
12314 // dead (or UB).
12315 if (AssumedCallees.empty()) {
12316 assert(AllCalleesKnown &&
12317 "Expected all callees to be known if there are none.");
12318 A.changeToUnreachableAfterManifest(CB);
12319 return ChangeStatus::CHANGED;
12320 }
12321
12322 // Special handling for the single callee case.
12323 if (AllCalleesKnown && AssumedCallees.size() == 1) {
12324 auto *NewCallee = AssumedCallees.front();
12325 if (isLegalToPromote(*CB, NewCallee)) {
12326 promoteCall(*CB, NewCallee, nullptr);
12327 return ChangeStatus::CHANGED;
12328 }
12329 Instruction *NewCall =
12330 CallInst::Create(FunctionCallee(CSFT, NewCallee), CSArgs,
12331 CB->getName(), CB->getIterator());
12332 if (!CBIsVoid)
12333 A.changeAfterManifest(IRPosition::callsite_returned(*CB), *NewCall);
12334 A.deleteAfterManifest(*CB);
12335 return ChangeStatus::CHANGED;
12336 }
12337
12338 // For each potential value we create a conditional
12339 //
12340 // ```
12341 // if (ptr == value) value(args);
12342 // else ...
12343 // ```
12344 //
12345 bool SpecializedForAnyCallees = false;
12346 bool SpecializedForAllCallees = AllCalleesKnown;
12347 ICmpInst *LastCmp = nullptr;
12348 SmallVector<Function *, 8> SkippedAssumedCallees;
12350 for (Function *NewCallee : AssumedCallees) {
12351 if (!A.shouldSpecializeCallSiteForCallee(*this, *CB, *NewCallee)) {
12352 SkippedAssumedCallees.push_back(NewCallee);
12353 SpecializedForAllCallees = false;
12354 continue;
12355 }
12356 SpecializedForAnyCallees = true;
12357
12358 LastCmp = new ICmpInst(IP, llvm::CmpInst::ICMP_EQ, FP, NewCallee);
12359 Instruction *ThenTI =
12360 SplitBlockAndInsertIfThen(LastCmp, IP, /* Unreachable */ false);
12361 BasicBlock *CBBB = CB->getParent();
12362 A.registerManifestAddedBasicBlock(*ThenTI->getParent());
12363 A.registerManifestAddedBasicBlock(*IP->getParent());
12364 auto *SplitTI = cast<BranchInst>(LastCmp->getNextNode());
12365 BasicBlock *ElseBB;
12366 if (&*IP == CB) {
12367 ElseBB = BasicBlock::Create(ThenTI->getContext(), "",
12368 ThenTI->getFunction(), CBBB);
12369 A.registerManifestAddedBasicBlock(*ElseBB);
12370 IP = BranchInst::Create(CBBB, ElseBB)->getIterator();
12371 SplitTI->replaceUsesOfWith(CBBB, ElseBB);
12372 } else {
12373 ElseBB = IP->getParent();
12374 ThenTI->replaceUsesOfWith(ElseBB, CBBB);
12375 }
12376 CastInst *RetBC = nullptr;
12377 CallInst *NewCall = nullptr;
12378 if (isLegalToPromote(*CB, NewCallee)) {
12379 auto *CBClone = cast<CallBase>(CB->clone());
12380 CBClone->insertBefore(ThenTI);
12381 NewCall = &cast<CallInst>(promoteCall(*CBClone, NewCallee, &RetBC));
12382 } else {
12383 NewCall = CallInst::Create(FunctionCallee(CSFT, NewCallee), CSArgs,
12384 CB->getName(), ThenTI->getIterator());
12385 }
12386 NewCalls.push_back({NewCall, RetBC});
12387 }
12388
12389 auto AttachCalleeMetadata = [&](CallBase &IndirectCB) {
12390 if (!AllCalleesKnown)
12391 return ChangeStatus::UNCHANGED;
12392 MDBuilder MDB(IndirectCB.getContext());
12393 MDNode *Callees = MDB.createCallees(SkippedAssumedCallees);
12394 IndirectCB.setMetadata(LLVMContext::MD_callees, Callees);
12395 return ChangeStatus::CHANGED;
12396 };
12397
12398 if (!SpecializedForAnyCallees)
12399 return AttachCalleeMetadata(*CB);
12400
12401 // Check if we need the fallback indirect call still.
12402 if (SpecializedForAllCallees) {
12404 LastCmp->eraseFromParent();
12405 new UnreachableInst(IP->getContext(), IP);
12406 IP->eraseFromParent();
12407 } else {
12408 auto *CBClone = cast<CallInst>(CB->clone());
12409 CBClone->setName(CB->getName());
12410 CBClone->insertBefore(*IP->getParent(), IP);
12411 NewCalls.push_back({CBClone, nullptr});
12412 AttachCalleeMetadata(*CBClone);
12413 }
12414
12415 // Check if we need a PHI to merge the results.
12416 if (!CBIsVoid) {
12417 auto *PHI = PHINode::Create(CB->getType(), NewCalls.size(),
12418 CB->getName() + ".phi",
12419 CB->getParent()->getFirstInsertionPt());
12420 for (auto &It : NewCalls) {
12421 CallBase *NewCall = It.first;
12422 Instruction *CallRet = It.second ? It.second : It.first;
12423 if (CallRet->getType() == CB->getType())
12424 PHI->addIncoming(CallRet, CallRet->getParent());
12425 else if (NewCall->getType()->isVoidTy())
12426 PHI->addIncoming(PoisonValue::get(CB->getType()),
12427 NewCall->getParent());
12428 else
12429 llvm_unreachable("Call return should match or be void!");
12430 }
12431 A.changeAfterManifest(IRPosition::callsite_returned(*CB), *PHI);
12432 }
12433
12434 A.deleteAfterManifest(*CB);
12435 Changed = ChangeStatus::CHANGED;
12436
12437 return Changed;
12438 }
12439
12440 /// See AbstractAttribute::getAsStr().
12441 const std::string getAsStr(Attributor *A) const override {
12442 return std::string(AllCalleesKnown ? "eliminate" : "specialize") +
12443 " indirect call site with " + std::to_string(AssumedCallees.size()) +
12444 " functions";
12445 }
12446
12447 void trackStatistics() const override {
12448 if (AllCalleesKnown) {
12450 Eliminated, CallSites,
12451 "Number of indirect call sites eliminated via specialization")
12452 } else {
12453 STATS_DECLTRACK(Specialized, CallSites,
12454 "Number of indirect call sites specialized")
12455 }
12456 }
12457
12458 bool foreachCallee(function_ref<bool(Function *)> CB) const override {
12459 return isValidState() && AllCalleesKnown && all_of(AssumedCallees, CB);
12460 }
12461
12462private:
12463 /// Map to remember filter results.
12465
12466 /// If the !callee metadata was present, this set will contain all potential
12467 /// callees (superset).
12468 SmallSetVector<Function *, 4> PotentialCallees;
12469
12470 /// This set contains all currently assumed calllees, which might grow over
12471 /// time.
12472 SmallSetVector<Function *, 4> AssumedCallees;
12473
12474 /// Flag to indicate if all possible callees are in the AssumedCallees set or
12475 /// if there could be others.
12476 bool AllCalleesKnown = true;
12477};
12478} // namespace
12479
12480/// ------------------------ Address Space ------------------------------------
12481namespace {
12482struct AAAddressSpaceImpl : public AAAddressSpace {
12483 AAAddressSpaceImpl(const IRPosition &IRP, Attributor &A)
12484 : AAAddressSpace(IRP, A) {}
12485
12486 int32_t getAddressSpace() const override {
12487 assert(isValidState() && "the AA is invalid");
12488 return AssumedAddressSpace;
12489 }
12490
12491 /// See AbstractAttribute::initialize(...).
12492 void initialize(Attributor &A) override {
12493 assert(getAssociatedType()->isPtrOrPtrVectorTy() &&
12494 "Associated value is not a pointer");
12495 }
12496
12497 ChangeStatus updateImpl(Attributor &A) override {
12498 int32_t OldAddressSpace = AssumedAddressSpace;
12499 auto *AUO = A.getOrCreateAAFor<AAUnderlyingObjects>(getIRPosition(), this,
12500 DepClassTy::REQUIRED);
12501 auto Pred = [&](Value &Obj) {
12502 if (isa<UndefValue>(&Obj))
12503 return true;
12504 return takeAddressSpace(Obj.getType()->getPointerAddressSpace());
12505 };
12506
12507 if (!AUO->forallUnderlyingObjects(Pred))
12508 return indicatePessimisticFixpoint();
12509
12510 return OldAddressSpace == AssumedAddressSpace ? ChangeStatus::UNCHANGED
12511 : ChangeStatus::CHANGED;
12512 }
12513
12514 /// See AbstractAttribute::manifest(...).
12515 ChangeStatus manifest(Attributor &A) override {
12516 Value *AssociatedValue = &getAssociatedValue();
12517 Value *OriginalValue = peelAddrspacecast(AssociatedValue);
12518 if (getAddressSpace() == NoAddressSpace ||
12519 static_cast<uint32_t>(getAddressSpace()) ==
12520 getAssociatedType()->getPointerAddressSpace())
12521 return ChangeStatus::UNCHANGED;
12522
12523 Type *NewPtrTy = PointerType::get(getAssociatedType()->getContext(),
12524 static_cast<uint32_t>(getAddressSpace()));
12525 bool UseOriginalValue =
12526 OriginalValue->getType()->getPointerAddressSpace() ==
12527 static_cast<uint32_t>(getAddressSpace());
12528
12529 bool Changed = false;
12530
12531 auto MakeChange = [&](Instruction *I, Use &U) {
12532 Changed = true;
12533 if (UseOriginalValue) {
12534 A.changeUseAfterManifest(U, *OriginalValue);
12535 return;
12536 }
12537 Instruction *CastInst = new AddrSpaceCastInst(OriginalValue, NewPtrTy);
12538 CastInst->insertBefore(cast<Instruction>(I));
12539 A.changeUseAfterManifest(U, *CastInst);
12540 };
12541
12542 auto Pred = [&](const Use &U, bool &) {
12543 if (U.get() != AssociatedValue)
12544 return true;
12545 auto *Inst = dyn_cast<Instruction>(U.getUser());
12546 if (!Inst)
12547 return true;
12548 // This is a WA to make sure we only change uses from the corresponding
12549 // CGSCC if the AA is run on CGSCC instead of the entire module.
12550 if (!A.isRunOn(Inst->getFunction()))
12551 return true;
12552 if (isa<LoadInst>(Inst))
12553 MakeChange(Inst, const_cast<Use &>(U));
12554 if (isa<StoreInst>(Inst)) {
12555 // We only make changes if the use is the pointer operand.
12556 if (U.getOperandNo() == 1)
12557 MakeChange(Inst, const_cast<Use &>(U));
12558 }
12559 return true;
12560 };
12561
12562 // It doesn't matter if we can't check all uses as we can simply
12563 // conservatively ignore those that can not be visited.
12564 (void)A.checkForAllUses(Pred, *this, getAssociatedValue(),
12565 /* CheckBBLivenessOnly */ true);
12566
12567 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
12568 }
12569
12570 /// See AbstractAttribute::getAsStr().
12571 const std::string getAsStr(Attributor *A) const override {
12572 if (!isValidState())
12573 return "addrspace(<invalid>)";
12574 return "addrspace(" +
12575 (AssumedAddressSpace == NoAddressSpace
12576 ? "none"
12577 : std::to_string(AssumedAddressSpace)) +
12578 ")";
12579 }
12580
12581private:
12582 int32_t AssumedAddressSpace = NoAddressSpace;
12583
12584 bool takeAddressSpace(int32_t AS) {
12585 if (AssumedAddressSpace == NoAddressSpace) {
12586 AssumedAddressSpace = AS;
12587 return true;
12588 }
12589 return AssumedAddressSpace == AS;
12590 }
12591
12592 static Value *peelAddrspacecast(Value *V) {
12593 if (auto *I = dyn_cast<AddrSpaceCastInst>(V))
12594 return peelAddrspacecast(I->getPointerOperand());
12595 if (auto *C = dyn_cast<ConstantExpr>(V))
12596 if (C->getOpcode() == Instruction::AddrSpaceCast)
12597 return peelAddrspacecast(C->getOperand(0));
12598 return V;
12599 }
12600};
12601
12602struct AAAddressSpaceFloating final : AAAddressSpaceImpl {
12603 AAAddressSpaceFloating(const IRPosition &IRP, Attributor &A)
12604 : AAAddressSpaceImpl(IRP, A) {}
12605
12606 void trackStatistics() const override {
12608 }
12609};
12610
12611struct AAAddressSpaceReturned final : AAAddressSpaceImpl {
12612 AAAddressSpaceReturned(const IRPosition &IRP, Attributor &A)
12613 : AAAddressSpaceImpl(IRP, A) {}
12614
12615 /// See AbstractAttribute::initialize(...).
12616 void initialize(Attributor &A) override {
12617 // TODO: we don't rewrite function argument for now because it will need to
12618 // rewrite the function signature and all call sites.
12619 (void)indicatePessimisticFixpoint();
12620 }
12621
12622 void trackStatistics() const override {
12623 STATS_DECLTRACK_FNRET_ATTR(addrspace);
12624 }
12625};
12626
12627struct AAAddressSpaceCallSiteReturned final : AAAddressSpaceImpl {
12628 AAAddressSpaceCallSiteReturned(const IRPosition &IRP, Attributor &A)
12629 : AAAddressSpaceImpl(IRP, A) {}
12630
12631 void trackStatistics() const override {
12632 STATS_DECLTRACK_CSRET_ATTR(addrspace);
12633 }
12634};
12635
12636struct AAAddressSpaceArgument final : AAAddressSpaceImpl {
12637 AAAddressSpaceArgument(const IRPosition &IRP, Attributor &A)
12638 : AAAddressSpaceImpl(IRP, A) {}
12639
12640 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(addrspace); }
12641};
12642
12643struct AAAddressSpaceCallSiteArgument final : AAAddressSpaceImpl {
12644 AAAddressSpaceCallSiteArgument(const IRPosition &IRP, Attributor &A)
12645 : AAAddressSpaceImpl(IRP, A) {}
12646
12647 /// See AbstractAttribute::initialize(...).
12648 void initialize(Attributor &A) override {
12649 // TODO: we don't rewrite call site argument for now because it will need to
12650 // rewrite the function signature of the callee.
12651 (void)indicatePessimisticFixpoint();
12652 }
12653
12654 void trackStatistics() const override {
12655 STATS_DECLTRACK_CSARG_ATTR(addrspace);
12656 }
12657};
12658} // namespace
12659
12660/// ----------- Allocation Info ----------
12661namespace {
12662struct AAAllocationInfoImpl : public AAAllocationInfo {
12663 AAAllocationInfoImpl(const IRPosition &IRP, Attributor &A)
12664 : AAAllocationInfo(IRP, A) {}
12665
12666 std::optional<TypeSize> getAllocatedSize() const override {
12667 assert(isValidState() && "the AA is invalid");
12668 return AssumedAllocatedSize;
12669 }
12670
12671 std::optional<TypeSize> findInitialAllocationSize(Instruction *I,
12672 const DataLayout &DL) {
12673
12674 // TODO: implement case for malloc like instructions
12675 switch (I->getOpcode()) {
12676 case Instruction::Alloca: {
12677 AllocaInst *AI = cast<AllocaInst>(I);
12678 return AI->getAllocationSize(DL);
12679 }
12680 default:
12681 return std::nullopt;
12682 }
12683 }
12684
12685 ChangeStatus updateImpl(Attributor &A) override {
12686
12687 const IRPosition &IRP = getIRPosition();
12688 Instruction *I = IRP.getCtxI();
12689
12690 // TODO: update check for malloc like calls
12691 if (!isa<AllocaInst>(I))
12692 return indicatePessimisticFixpoint();
12693
12694 bool IsKnownNoCapture;
12695 if (!AA::hasAssumedIRAttr<Attribute::NoCapture>(
12696 A, this, IRP, DepClassTy::OPTIONAL, IsKnownNoCapture))
12697 return indicatePessimisticFixpoint();
12698
12699 const AAPointerInfo *PI =
12700 A.getOrCreateAAFor<AAPointerInfo>(IRP, *this, DepClassTy::REQUIRED);
12701
12702 if (!PI)
12703 return indicatePessimisticFixpoint();
12704
12705 if (!PI->getState().isValidState())
12706 return indicatePessimisticFixpoint();
12707
12708 const DataLayout &DL = A.getDataLayout();
12709 const auto AllocationSize = findInitialAllocationSize(I, DL);
12710
12711 // If allocation size is nullopt, we give up.
12712 if (!AllocationSize)
12713 return indicatePessimisticFixpoint();
12714
12715 // For zero sized allocations, we give up.
12716 // Since we can't reduce further
12717 if (*AllocationSize == 0)
12718 return indicatePessimisticFixpoint();
12719
12720 int64_t BinSize = PI->numOffsetBins();
12721
12722 // TODO: implement for multiple bins
12723 if (BinSize > 1)
12724 return indicatePessimisticFixpoint();
12725
12726 if (BinSize == 0) {
12727 auto NewAllocationSize = std::optional<TypeSize>(TypeSize(0, false));
12728 if (!changeAllocationSize(NewAllocationSize))
12729 return ChangeStatus::UNCHANGED;
12730 return ChangeStatus::CHANGED;
12731 }
12732
12733 // TODO: refactor this to be part of multiple bin case
12734 const auto &It = PI->begin();
12735
12736 // TODO: handle if Offset is not zero
12737 if (It->first.Offset != 0)
12738 return indicatePessimisticFixpoint();
12739
12740 uint64_t SizeOfBin = It->first.Offset + It->first.Size;
12741
12742 if (SizeOfBin >= *AllocationSize)
12743 return indicatePessimisticFixpoint();
12744
12745 auto NewAllocationSize =
12746 std::optional<TypeSize>(TypeSize(SizeOfBin * 8, false));
12747
12748 if (!changeAllocationSize(NewAllocationSize))
12749 return ChangeStatus::UNCHANGED;
12750
12751 return ChangeStatus::CHANGED;
12752 }
12753
12754 /// See AbstractAttribute::manifest(...).
12755 ChangeStatus manifest(Attributor &A) override {
12756
12757 assert(isValidState() &&
12758 "Manifest should only be called if the state is valid.");
12759
12760 Instruction *I = getIRPosition().getCtxI();
12761
12762 auto FixedAllocatedSizeInBits = getAllocatedSize()->getFixedValue();
12763
12764 unsigned long NumBytesToAllocate = (FixedAllocatedSizeInBits + 7) / 8;
12765
12766 switch (I->getOpcode()) {
12767 // TODO: add case for malloc like calls
12768 case Instruction::Alloca: {
12769
12770 AllocaInst *AI = cast<AllocaInst>(I);
12771
12772 Type *CharType = Type::getInt8Ty(I->getContext());
12773
12774 auto *NumBytesToValue =
12775 ConstantInt::get(I->getContext(), APInt(32, NumBytesToAllocate));
12776
12777 BasicBlock::iterator insertPt = AI->getIterator();
12778 insertPt = std::next(insertPt);
12779 AllocaInst *NewAllocaInst =
12780 new AllocaInst(CharType, AI->getAddressSpace(), NumBytesToValue,
12781 AI->getAlign(), AI->getName(), insertPt);
12782
12783 if (A.changeAfterManifest(IRPosition::inst(*AI), *NewAllocaInst))
12784 return ChangeStatus::CHANGED;
12785
12786 break;
12787 }
12788 default:
12789 break;
12790 }
12791
12792 return ChangeStatus::UNCHANGED;
12793 }
12794
12795 /// See AbstractAttribute::getAsStr().
12796 const std::string getAsStr(Attributor *A) const override {
12797 if (!isValidState())
12798 return "allocationinfo(<invalid>)";
12799 return "allocationinfo(" +
12800 (AssumedAllocatedSize == HasNoAllocationSize
12801 ? "none"
12802 : std::to_string(AssumedAllocatedSize->getFixedValue())) +
12803 ")";
12804 }
12805
12806private:
12807 std::optional<TypeSize> AssumedAllocatedSize = HasNoAllocationSize;
12808
12809 // Maintain the computed allocation size of the object.
12810 // Returns (bool) weather the size of the allocation was modified or not.
12811 bool changeAllocationSize(std::optional<TypeSize> Size) {
12812 if (AssumedAllocatedSize == HasNoAllocationSize ||
12813 AssumedAllocatedSize != Size) {
12814 AssumedAllocatedSize = Size;
12815 return true;
12816 }
12817 return false;
12818 }
12819};
12820
12821struct AAAllocationInfoFloating : AAAllocationInfoImpl {
12822 AAAllocationInfoFloating(const IRPosition &IRP, Attributor &A)
12823 : AAAllocationInfoImpl(IRP, A) {}
12824
12825 void trackStatistics() const override {
12826 STATS_DECLTRACK_FLOATING_ATTR(allocationinfo);
12827 }
12828};
12829
12830struct AAAllocationInfoReturned : AAAllocationInfoImpl {
12831 AAAllocationInfoReturned(const IRPosition &IRP, Attributor &A)
12832 : AAAllocationInfoImpl(IRP, A) {}
12833
12834 /// See AbstractAttribute::initialize(...).
12835 void initialize(Attributor &A) override {
12836 // TODO: we don't rewrite function argument for now because it will need to
12837 // rewrite the function signature and all call sites
12838 (void)indicatePessimisticFixpoint();
12839 }
12840
12841 void trackStatistics() const override {
12842 STATS_DECLTRACK_FNRET_ATTR(allocationinfo);
12843 }
12844};
12845
12846struct AAAllocationInfoCallSiteReturned : AAAllocationInfoImpl {
12847 AAAllocationInfoCallSiteReturned(const IRPosition &IRP, Attributor &A)
12848 : AAAllocationInfoImpl(IRP, A) {}
12849
12850 void trackStatistics() const override {
12851 STATS_DECLTRACK_CSRET_ATTR(allocationinfo);
12852 }
12853};
12854
12855struct AAAllocationInfoArgument : AAAllocationInfoImpl {
12856 AAAllocationInfoArgument(const IRPosition &IRP, Attributor &A)
12857 : AAAllocationInfoImpl(IRP, A) {}
12858
12859 void trackStatistics() const override {
12860 STATS_DECLTRACK_ARG_ATTR(allocationinfo);
12861 }
12862};
12863
12864struct AAAllocationInfoCallSiteArgument : AAAllocationInfoImpl {
12865 AAAllocationInfoCallSiteArgument(const IRPosition &IRP, Attributor &A)
12866 : AAAllocationInfoImpl(IRP, A) {}
12867
12868 /// See AbstractAttribute::initialize(...).
12869 void initialize(Attributor &A) override {
12870
12871 (void)indicatePessimisticFixpoint();
12872 }
12873
12874 void trackStatistics() const override {
12875 STATS_DECLTRACK_CSARG_ATTR(allocationinfo);
12876 }
12877};
12878} // namespace
12879
12880const char AANoUnwind::ID = 0;
12881const char AANoSync::ID = 0;
12882const char AANoFree::ID = 0;
12883const char AANonNull::ID = 0;
12884const char AAMustProgress::ID = 0;
12885const char AANoRecurse::ID = 0;
12886const char AANonConvergent::ID = 0;
12887const char AAWillReturn::ID = 0;
12888const char AAUndefinedBehavior::ID = 0;
12889const char AANoAlias::ID = 0;
12890const char AAIntraFnReachability::ID = 0;
12891const char AANoReturn::ID = 0;
12892const char AAIsDead::ID = 0;
12893const char AADereferenceable::ID = 0;
12894const char AAAlign::ID = 0;
12895const char AAInstanceInfo::ID = 0;
12896const char AANoCapture::ID = 0;
12897const char AAValueSimplify::ID = 0;
12898const char AAHeapToStack::ID = 0;
12899const char AAPrivatizablePtr::ID = 0;
12900const char AAMemoryBehavior::ID = 0;
12901const char AAMemoryLocation::ID = 0;
12902const char AAValueConstantRange::ID = 0;
12903const char AAPotentialConstantValues::ID = 0;
12904const char AAPotentialValues::ID = 0;
12905const char AANoUndef::ID = 0;
12906const char AANoFPClass::ID = 0;
12907const char AACallEdges::ID = 0;
12908const char AAInterFnReachability::ID = 0;
12909const char AAPointerInfo::ID = 0;
12910const char AAAssumptionInfo::ID = 0;
12911const char AAUnderlyingObjects::ID = 0;
12912const char AAAddressSpace::ID = 0;
12913const char AAAllocationInfo::ID = 0;
12914const char AAIndirectCallInfo::ID = 0;
12915const char AAGlobalValueInfo::ID = 0;
12916const char AADenormalFPMath::ID = 0;
12917
12918// Macro magic to create the static generator function for attributes that
12919// follow the naming scheme.
12920
12921#define SWITCH_PK_INV(CLASS, PK, POS_NAME) \
12922 case IRPosition::PK: \
12923 llvm_unreachable("Cannot create " #CLASS " for a " POS_NAME " position!");
12924
12925#define SWITCH_PK_CREATE(CLASS, IRP, PK, SUFFIX) \
12926 case IRPosition::PK: \
12927 AA = new (A.Allocator) CLASS##SUFFIX(IRP, A); \
12928 ++NumAAs; \
12929 break;
12930
12931#define CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
12932 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
12933 CLASS *AA = nullptr; \
12934 switch (IRP.getPositionKind()) { \
12935 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
12936 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
12937 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
12938 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
12939 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
12940 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
12941 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
12942 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
12943 } \
12944 return *AA; \
12945 }
12946
12947#define CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
12948 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
12949 CLASS *AA = nullptr; \
12950 switch (IRP.getPositionKind()) { \
12951 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
12952 SWITCH_PK_INV(CLASS, IRP_FUNCTION, "function") \
12953 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
12954 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
12955 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
12956 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
12957 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
12958 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
12959 } \
12960 return *AA; \
12961 }
12962
12963#define CREATE_ABSTRACT_ATTRIBUTE_FOR_ONE_POSITION(POS, SUFFIX, CLASS) \
12964 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
12965 CLASS *AA = nullptr; \
12966 switch (IRP.getPositionKind()) { \
12967 SWITCH_PK_CREATE(CLASS, IRP, POS, SUFFIX) \
12968 default: \
12969 llvm_unreachable("Cannot create " #CLASS " for position otherthan " #POS \
12970 " position!"); \
12971 } \
12972 return *AA; \
12973 }
12974
12975#define CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
12976 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
12977 CLASS *AA = nullptr; \
12978 switch (IRP.getPositionKind()) { \
12979 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
12980 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
12981 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
12982 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
12983 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
12984 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
12985 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
12986 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
12987 } \
12988 return *AA; \
12989 }
12990
12991#define CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
12992 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
12993 CLASS *AA = nullptr; \
12994 switch (IRP.getPositionKind()) { \
12995 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
12996 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
12997 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
12998 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
12999 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
13000 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
13001 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
13002 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
13003 } \
13004 return *AA; \
13005 }
13006
13007#define CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13008 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13009 CLASS *AA = nullptr; \
13010 switch (IRP.getPositionKind()) { \
13011 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13012 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
13013 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
13014 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
13015 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
13016 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
13017 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
13018 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
13019 } \
13020 return *AA; \
13021 }
13022
13032
13048
13053
13058
13065
13067
13068#undef CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION
13069#undef CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION
13070#undef CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION
13071#undef CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION
13072#undef CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION
13073#undef CREATE_ABSTRACT_ATTRIBUTE_FOR_ONE_POSITION
13074#undef SWITCH_PK_CREATE
13075#undef SWITCH_PK_INV
#define Success
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
amdgpu AMDGPU Register Bank Select
Rewrite undef for PHI
This file implements a class to represent arbitrary precision integral constant values and operations...
ReachingDefAnalysis InstSet & ToRemove
This file contains the simple types necessary to represent the attributes associated with functions a...
#define STATS_DECLTRACK(NAME, TYPE, MSG)
static std::optional< Constant * > askForAssumedConstant(Attributor &A, const AbstractAttribute &QueryingAA, const IRPosition &IRP, Type &Ty)
static cl::opt< unsigned, true > MaxPotentialValues("attributor-max-potential-values", cl::Hidden, cl::desc("Maximum number of potential values to be " "tracked for each position."), cl::location(llvm::PotentialConstantIntValuesState::MaxPotentialValues), cl::init(7))
static const Value * getPointerOperand(const Instruction *I, bool AllowVolatile)
Get pointer operand of memory accessing instruction.
static void clampReturnedValueStates(Attributor &A, const AAType &QueryingAA, StateType &S, const IRPosition::CallBaseContext *CBContext=nullptr)
Clamp the information known for all returned values of a function (identified by QueryingAA) into S.
#define STATS_DECLTRACK_FN_ATTR(NAME)
#define CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
static cl::opt< int > MaxPotentialValuesIterations("attributor-max-potential-values-iterations", cl::Hidden, cl::desc("Maximum number of iterations we keep dismantling potential values."), cl::init(64))
#define STATS_DECLTRACK_CS_ATTR(NAME)
#define PIPE_OPERATOR(CLASS)
#define DefineKeys(ToTy)
static bool mayBeInCycle(const CycleInfo *CI, const Instruction *I, bool HeaderOnly, Cycle **CPtr=nullptr)
#define STATS_DECLTRACK_ARG_ATTR(NAME)
static const Value * stripAndAccumulateOffsets(Attributor &A, const AbstractAttribute &QueryingAA, const Value *Val, const DataLayout &DL, APInt &Offset, bool GetMinOffset, bool AllowNonInbounds, bool UseAssumed=false)
#define STATS_DECLTRACK_CSRET_ATTR(NAME)
static cl::opt< bool > ManifestInternal("attributor-manifest-internal", cl::Hidden, cl::desc("Manifest Attributor internal string attributes."), cl::init(false))
static Value * constructPointer(Value *Ptr, int64_t Offset, IRBuilder< NoFolder > &IRB)
Helper function to create a pointer based on Ptr, and advanced by Offset bytes.
#define CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
#define BUILD_STAT_NAME(NAME, TYPE)
static bool isDenselyPacked(Type *Ty, const DataLayout &DL)
Checks if a type could have padding bytes.
#define CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
static const Value * getMinimalBaseOfPointer(Attributor &A, const AbstractAttribute &QueryingAA, const Value *Ptr, int64_t &BytesOffset, const DataLayout &DL, bool AllowNonInbounds=false)
#define STATS_DECLTRACK_FNRET_ATTR(NAME)
#define STATS_DECLTRACK_CSARG_ATTR(NAME)
#define CREATE_ABSTRACT_ATTRIBUTE_FOR_ONE_POSITION(POS, SUFFIX, CLASS)
#define CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
static cl::opt< int > MaxHeapToStackSize("max-heap-to-stack-size", cl::init(128), cl::Hidden)
#define CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
#define STATS_DECLTRACK_FLOATING_ATTR(NAME)
#define STATS_DECL(NAME, TYPE, MSG)
basic Basic Alias true
BlockVerifier::State From
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static bool isReachableImpl(SmallVectorImpl< BasicBlock * > &Worklist, const StopSetT &StopSet, const SmallPtrSetImpl< BasicBlock * > *ExclusionSet, const DominatorTree *DT, const LoopInfo *LI)
Definition: CFG.cpp:134
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file declares an analysis pass that computes CycleInfo for LLVM IR, specialized from GenericCycl...
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
Given that RA is a live propagate it s liveness to any other values it uses(according to Uses). void DeadArgumentEliminationPass
Performs the initial survey of the specified function
Given that RA is a live value
#define LLVM_DEBUG(X)
Definition: Debug.h:101
This file defines DenseMapInfo traits for DenseMap.
T Content
uint64_t Size
Rewrite Partial Register Uses
#define Check(C,...)
Hexagon Common GEP
IRTranslator LLVM IR MI
static LoopDeletionResult merge(LoopDeletionResult A, LoopDeletionResult B)
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
This file implements a map that provides insertion order iteration.
#define T
#define T1
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
uint64_t IntrinsicInst * II
if(VerifyEach)
static StringRef getName(Value *V)
Basic Register Allocator
static cl::opt< RegAllocEvictionAdvisorAnalysis::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysis::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysis::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysis::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysis::AdvisorMode::Development, "development", "for training")))
This builds on the llvm/ADT/GraphTraits.h file to find the strongly connected components (SCCs) of a ...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool IsDead
This file contains some templates that are useful if you are working with the STL at all.
raw_pwrite_stream & OS
This file defines generic set operations that may be used on set's of different types,...
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition: Statistic.h:167
This file contains some functions that are useful when dealing with strings.
static SymbolRef::Type getType(const Symbol *Sym)
Definition: TapiFile.cpp:40
static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, ArrayRef< StringLiteral > StandardNames)
Initialize the set of available library functions based on the specified target triple.
@ Floating
This pass exposes codegen information to IR-level passes.
static unsigned getBitWidth(Type *Ty, const DataLayout &DL)
Returns the bitwidth of the given scalar or pointer type.
Value * RHS
Value * LHS
static unsigned getSize(unsigned Kind)
AACallGraphNode * operator*() const
A manager for alias analyses.
bool isNoAlias(const MemoryLocation &LocA, const MemoryLocation &LocB)
A trivial helper function to check to see if the specified pointers are no-alias.
Class for arbitrary precision integers.
Definition: APInt.h:77
int64_t getSExtValue() const
Get sign extended value.
Definition: APInt.h:1521
AbstractCallSite.
CallBase * getInstruction() const
Return the underlying instruction.
bool isCallbackCall() const
Return true if this ACS represents a callback call.
bool isDirectCall() const
Return true if this ACS represents a direct call.
static void getCallbackUses(const CallBase &CB, SmallVectorImpl< const Use * > &CallbackUses)
Add operand uses of CB that represent callback uses into CallbackUses.
int getCallArgOperandNo(Argument &Arg) const
Return the operand index of the underlying instruction associated with Arg.
This class represents a conversion between pointers from one address space to another.
an instruction to allocate memory on the stack
Definition: Instructions.h:60
Align getAlign() const
Return the alignment of the memory that is being allocated by the instruction.
Definition: Instructions.h:121
unsigned getAddressSpace() const
Return the address space for the allocation.
Definition: Instructions.h:101
std::optional< TypeSize > getAllocationSize(const DataLayout &DL) const
Get allocation size in bytes.
This class represents an incoming formal argument to a Function.
Definition: Argument.h:31
bool hasPointeeInMemoryValueAttr() const
Return true if this argument has the byval, sret, inalloca, preallocated, or byref attribute.
Definition: Function.cpp:179
bool hasReturnedAttr() const
Return true if this argument has the returned attribute.
Definition: Function.cpp:304
bool hasByValAttr() const
Return true if this argument has the byval attribute.
Definition: Function.cpp:141
const Function * getParent() const
Definition: Argument.h:43
unsigned getArgNo() const
Return the index of this formal argument in its containing function.
Definition: Argument.h:49
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
iterator end() const
Definition: ArrayRef.h:154
iterator begin() const
Definition: ArrayRef.h:153
A function analysis which provides an AssumptionCache.
A cache of @llvm.assume calls within a function.
static Attribute get(LLVMContext &Context, AttrKind Kind, uint64_t Val=0)
Return a uniquified Attribute object.
Definition: Attributes.cpp:94
static Attribute getWithDereferenceableBytes(LLVMContext &Context, uint64_t Bytes)
Definition: Attributes.cpp:242
FPClassTest getNoFPClass() const
Return the FPClassTest for nofpclass.
Definition: Attributes.cpp:489
Attribute::AttrKind getKindAsEnum() const
Return the attribute's kind as an enum (Attribute::AttrKind).
Definition: Attributes.cpp:362
MemoryEffects getMemoryEffects() const
Returns memory effects.
Definition: Attributes.cpp:483
static Attribute getWithDereferenceableOrNullBytes(LLVMContext &Context, uint64_t Bytes)
Definition: Attributes.cpp:248
static Attribute getWithNoFPClass(LLVMContext &Context, FPClassTest Mask)
Definition: Attributes.cpp:284
AttrKind
This enumeration lists the attributes that can be associated with parameters, function results,...
Definition: Attributes.h:86
static bool isEnumAttrKind(AttrKind Kind)
Definition: Attributes.h:99
static Attribute getWithMemoryEffects(LLVMContext &Context, MemoryEffects ME)
Definition: Attributes.cpp:279
static Attribute getWithAlignment(LLVMContext &Context, Align Alignment)
Return a uniquified Attribute object that has the specific alignment set.
Definition: Attributes.cpp:232
LLVM Basic Block Representation.
Definition: BasicBlock.h:61
const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
Definition: BasicBlock.cpp:414
const Instruction & front() const
Definition: BasicBlock.h:461
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition: BasicBlock.h:202
const Function * getParent() const
Return the enclosing method, or null if none.
Definition: BasicBlock.h:209
InstListType::iterator iterator
Instruction iterators...
Definition: BasicBlock.h:167
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
Definition: BasicBlock.h:229
BinaryOps getOpcode() const
Definition: InstrTypes.h:442
Conditional or Unconditional Branch instruction.
unsigned getNumSuccessors() const
static BranchInst * Create(BasicBlock *IfTrue, InsertPosition InsertBefore=nullptr)
BasicBlock * getSuccessor(unsigned i) const
Value * getCondition() const
Allocate memory in an ever growing pool, as if by bump-pointer.
Definition: Allocator.h:66
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Definition: InstrTypes.h:1236
User::op_iterator arg_begin()
Return the iterator pointing to the beginning of the argument list.
Definition: InstrTypes.h:1385
bool isMustTailCall() const
Tests if this call site must be tail call optimized.
bool isIndirectCall() const
Return true if the callsite is an indirect call.
bool isCallee(Value::const_user_iterator UI) const
Determine whether the passed iterator points to the callee operand's Use.
Definition: InstrTypes.h:1476
Value * getCalledOperand() const
Definition: InstrTypes.h:1458
const Use & getCalledOperandUse() const
Definition: InstrTypes.h:1460
const Use & getArgOperandUse(unsigned i) const
Wrappers for getting the Use of a call argument.
Definition: InstrTypes.h:1421
Value * getArgOperand(unsigned i) const
Definition: InstrTypes.h:1410
User::op_iterator arg_end()
Return the iterator pointing to the end of the argument list.
Definition: InstrTypes.h:1391
bool isBundleOperand(unsigned Idx) const
Return true if the operand at index Idx is a bundle operand.
Definition: InstrTypes.h:2076
bool isConvergent() const
Determine if the invoke is convergent.
Definition: InstrTypes.h:2027
FunctionType * getFunctionType() const
Definition: InstrTypes.h:1323
Intrinsic::ID getIntrinsicID() const
Returns the intrinsic ID of the intrinsic called or Intrinsic::not_intrinsic if the called function i...
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
Definition: InstrTypes.h:1401
unsigned getArgOperandNo(const Use *U) const
Given a use for a arg operand, get the arg operand number that corresponds to it.
Definition: InstrTypes.h:1441
unsigned arg_size() const
Definition: InstrTypes.h:1408
bool isArgOperand(const Use *U) const
Definition: InstrTypes.h:1430
Function * getCaller()
Helper to get the caller (the parent function).
This class represents a function call, abstracting a target machine's calling convention.
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
This is the base class for all instructions that perform data casts.
Definition: InstrTypes.h:530
Instruction::CastOps getOpcode() const
Return the opcode of this CastInst.
Definition: InstrTypes.h:694
bool isIntegerCast() const
There are several places where we need to know if a cast instruction only deals with integer source a...
Type * getDestTy() const
Return the destination type, as a convenience.
Definition: InstrTypes.h:701
This class is the base class for the comparison instructions.
Definition: InstrTypes.h:747
bool isEquality() const
Determine if this is an equals/not equals predicate.
Definition: InstrTypes.h:997
bool isFalseWhenEqual() const
This is just a convenience.
Definition: InstrTypes.h:1062
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition: InstrTypes.h:757
@ ICMP_EQ
equal
Definition: InstrTypes.h:778
@ ICMP_NE
not equal
Definition: InstrTypes.h:779
bool isTrueWhenEqual() const
This is just a convenience.
Definition: InstrTypes.h:1056
Predicate getPredicate() const
Return the predicate for this instruction.
Definition: InstrTypes.h:847
static ConstantAsMetadata * get(Constant *C)
Definition: Metadata.h:528
A constant value that is initialized with an expression using other constant values.
Definition: Constants.h:1084
static Constant * getExtractElement(Constant *Vec, Constant *Idx, Type *OnlyIfReducedTy=nullptr)
Definition: Constants.cpp:2478
This is the shared class of boolean and integer constants.
Definition: Constants.h:81
static ConstantInt * getTrue(LLVMContext &Context)
Definition: Constants.cpp:850
This class represents a range of values.
Definition: ConstantRange.h:47
const APInt & getLower() const
Return the lower value for this range.
bool isFullSet() const
Return true if this set contains all of the elements possible for this data-type.
bool isEmptySet() const
Return true if this set contains no members.
APInt getSignedMin() const
Return the smallest signed value contained in the ConstantRange.
bool isSingleElement() const
Return true if this set contains exactly one member.
static ConstantRange makeAllowedICmpRegion(CmpInst::Predicate Pred, const ConstantRange &Other)
Produce the smallest range such that all values that may satisfy the given predicate with any value c...
const APInt & getUpper() const
Return the upper value for this range.
APInt getSignedMax() const
Return the largest signed value contained in the ConstantRange.
This is an important base class in LLVM.
Definition: Constant.h:41
Analysis pass which computes a CycleInfo.
Definition: CycleAnalysis.h:47
This class represents an Operation in the Expression.
A parsed version of the target data layout string in and methods for querying it.
Definition: DataLayout.h:110
A debug info location.
Definition: DebugLoc.h:33
iterator find(const_arg_type_t< KeyT > Val)
Definition: DenseMap.h:155
unsigned size() const
Definition: DenseMap.h:99
iterator begin()
Definition: DenseMap.h:75
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
Definition: DenseMap.h:151
iterator end()
Definition: DenseMap.h:84
bool contains(const_arg_type_t< KeyT > Val) const
Return true if the specified key is in the map, false otherwise.
Definition: DenseMap.h:145
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition: DenseMap.h:220
Implements a dense probed hash-table based set.
Definition: DenseSet.h:271
Analysis pass which computes a DominatorTree.
Definition: Dominators.h:279
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition: Dominators.h:162
bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
Definition: Dominators.cpp:122
An instruction for ordering other memory operations.
Definition: Instructions.h:419
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
Definition: DerivedTypes.h:168
const BasicBlock & getEntryBlock() const
Definition: Function.h:800
iterator_range< arg_iterator > args()
Definition: Function.h:855
const Function & getFunction() const
Definition: Function.h:163
size_t arg_size() const
Definition: Function.h:864
Argument * getArg(unsigned i) const
Definition: Function.h:849
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition: Function.cpp:690
CycleT * getCycle(const BlockT *Block) const
Find the innermost cycle containing a given block.
A possibly irreducible generalization of a Loop.
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
Definition: Globals.cpp:290
bool hasLocalLinkage() const
Definition: GlobalValue.h:528
This instruction compares its operands according to the predicate given to the constructor.
static bool compare(const APInt &LHS, const APInt &RHS, ICmpInst::Predicate Pred)
Return result of LHS Pred RHS comparison.
Value * CreatePtrAdd(Value *Ptr, Value *Offset, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
Definition: IRBuilder.h:1974
ConstantInt * getInt64(uint64_t C)
Get a constant 64-bit value.
Definition: IRBuilder.h:489
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition: IRBuilder.h:2664
Instruction * clone() const
Create a copy of 'this' instruction that is identical in all ways except the following:
bool isLifetimeStartOrEnd() const LLVM_READONLY
Return true if the instruction is a llvm.lifetime.start or llvm.lifetime.end marker.
bool mayReadOrWriteMemory() const
Return true if this instruction may read or write memory.
Definition: Instruction.h:764
bool mayWriteToMemory() const LLVM_READONLY
Return true if this instruction may modify memory.
void insertBefore(Instruction *InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified instruction.
Definition: Instruction.cpp:97
InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
Definition: Instruction.cpp:92
const Function * getFunction() const
Return the function this instruction belongs to.
Definition: Instruction.cpp:70
BasicBlock * getSuccessor(unsigned Idx) const LLVM_READONLY
Return the specified successor. This instruction must be a terminator.
bool mayHaveSideEffects() const LLVM_READONLY
Return true if the instruction may have side effects.
bool isTerminator() const
Definition: Instruction.h:277
bool mayReadFromMemory() const LLVM_READONLY
Return true if this instruction may read memory.
const Instruction * getNextNonDebugInstruction(bool SkipPseudoOp=false) const
Return a pointer to the next non-debug instruction in the same basic block as 'this',...
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
Definition: Instruction.h:274
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
Definition: Instruction.h:473
const DataLayout & getDataLayout() const
Get the data layout of the module this instruction belongs to.
Definition: Instruction.cpp:74
A wrapper class for inspecting calls to intrinsic functions.
Definition: IntrinsicInst.h:48
Invoke instruction.
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:67
Analysis to compute lazy value information.
This pass computes, caches, and vends lazy value constraint information.
Definition: LazyValueInfo.h:33
ConstantRange getConstantRange(Value *V, Instruction *CxtI, bool UndefAllowed)
Return the ConstantRange constraint that is known to hold for the specified value at the specified in...
An instruction for reading from memory.
Definition: Instructions.h:173
Analysis pass that exposes the LoopInfo for a function.
Definition: LoopInfo.h:571
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
Metadata node.
Definition: Metadata.h:1067
const MDOperand & getOperand(unsigned I) const
Definition: Metadata.h:1428
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition: Metadata.h:1541
unsigned getNumOperands() const
Return number of MDNode operands.
Definition: Metadata.h:1434
This class implements a map that also provides access to all stored values in a deterministic order.
Definition: MapVector.h:36
bool empty() const
Definition: MapVector.h:79
static MemoryEffectsBase readOnly()
Create MemoryEffectsBase that can read any memory.
Definition: ModRef.h:122
bool doesNotAccessMemory() const
Whether this function accesses no memory.
Definition: ModRef.h:192
static MemoryEffectsBase argMemOnly(ModRefInfo MR=ModRefInfo::ModRef)
Create MemoryEffectsBase that can only access argument memory.
Definition: ModRef.h:132
static MemoryEffectsBase inaccessibleMemOnly(ModRefInfo MR=ModRefInfo::ModRef)
Create MemoryEffectsBase that can only access inaccessible memory.
Definition: ModRef.h:138
bool onlyAccessesInaccessibleMem() const
Whether this function only (at most) accesses inaccessible memory.
Definition: ModRef.h:211
ModRefInfo getModRef(Location Loc) const
Get ModRefInfo for the given Location.
Definition: ModRef.h:165
bool onlyAccessesArgPointees() const
Whether this function only (at most) accesses argument memory.
Definition: ModRef.h:201
bool onlyReadsMemory() const
Whether this function only (at most) reads memory.
Definition: ModRef.h:195
static MemoryEffectsBase writeOnly()
Create MemoryEffectsBase that can write any memory.
Definition: ModRef.h:127
static MemoryEffectsBase inaccessibleOrArgMemOnly(ModRefInfo MR=ModRefInfo::ModRef)
Create MemoryEffectsBase that can only access inaccessible or argument memory.
Definition: ModRef.h:145
static MemoryEffectsBase none()
Create MemoryEffectsBase that cannot read or write any memory.
Definition: ModRef.h:117
bool onlyAccessesInaccessibleOrArgMem() const
Whether this function only (at most) accesses argument and inaccessible memory.
Definition: ModRef.h:217
static MemoryEffectsBase unknown()
Create MemoryEffectsBase that can read and write any memory.
Definition: ModRef.h:112
static std::optional< MemoryLocation > getOrNone(const Instruction *Inst)
Root of the metadata hierarchy.
Definition: Metadata.h:62
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
Evaluate the size and offset of an object pointed to by a Value*.
static SizeOffsetValue unknown()
Diagnostic information for missed-optimization remarks.
Diagnostic information for applied optimization remarks.
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
static PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
Definition: Constants.cpp:1814
Return a value (possibly void), from a function.
Value * getReturnValue() const
Convenience accessor. Returns null if there is no return value.
This class represents an analyzed expression in the program.
Analysis pass that exposes the ScalarEvolution for a function.
The main scalar evolution driver.
const SCEV * getSCEVAtScope(const SCEV *S, const Loop *L)
Return a SCEV expression for the specified value at the specified scope in the program.
const SCEV * getSCEV(Value *V)
Return a SCEV expression for the full generality of the specified expression.
unsigned getSmallConstantMaxTripCount(const Loop *L)
Returns the upper bound of the loop trip count as a normal unsigned value.
ConstantRange getUnsignedRange(const SCEV *S)
Determine the unsigned range for a particular SCEV.
This class represents the LLVM 'select' instruction.
A vector that has set insertion semantics.
Definition: SetVector.h:57
size_type size() const
Determine the number of elements in the SetVector.
Definition: SetVector.h:98
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition: SetVector.h:162
bool erase(PtrType Ptr)
Remove pointer from the set.
Definition: SmallPtrSet.h:361
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
Definition: SmallPtrSet.h:412
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
Definition: SmallPtrSet.h:344
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
Definition: SmallPtrSet.h:479
A SetVector that performs no allocations if smaller than a certain size.
Definition: SetVector.h:370
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
Definition: SmallSet.h:135
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
Definition: SmallSet.h:179
bool empty() const
Definition: SmallVector.h:94
size_t size() const
Definition: SmallVector.h:91
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:586
reference emplace_back(ArgTypes &&... Args)
Definition: SmallVector.h:950
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
Definition: SmallVector.h:696
void push_back(const T &Elt)
Definition: SmallVector.h:426
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1209
An instruction for storing to memory.
Definition: Instructions.h:289
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
Used to lazily calculate structure layout information for a target machine, based on the DataLayout s...
Definition: DataLayout.h:622
TypeSize getElementOffset(unsigned Idx) const
Definition: DataLayout.h:651
TypeSize getElementOffsetInBits(unsigned Idx) const
Definition: DataLayout.h:656
Class to represent struct types.
Definition: DerivedTypes.h:216
unsigned getNumElements() const
Random access to the elements.
Definition: DerivedTypes.h:341
Type * getElementType(unsigned N) const
Definition: DerivedTypes.h:342
Multiway switch.
Analysis pass providing the TargetTransformInfo.
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
bool areTypesABICompatible(const Function *Caller, const Function *Callee, const ArrayRef< Type * > &Types) const
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
unsigned getIntegerBitWidth() const
bool isPointerTy() const
True if this is an instance of PointerType.
Definition: Type.h:255
static IntegerType * getInt1Ty(LLVMContext &C)
unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
Definition: Type.h:302
static IntegerType * getInt8Ty(LLVMContext &C)
bool isPtrOrPtrVectorTy() const
Return true if this is a pointer type or a vector of pointer types.
Definition: Type.h:262
static IntegerType * getInt32Ty(LLVMContext &C)
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition: Type.h:228
bool isVoidTy() const
Return true if this is 'void'.
Definition: Type.h:140
'undef' values are things that do not have specified contents.
Definition: Constants.h:1385
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
Definition: Constants.cpp:1795
This function has undefined behavior.
A Use represents the edge between a Value definition and its users.
Definition: Use.h:43
User * getUser() const
Returns the User that contains this Use.
Definition: Use.h:72
bool replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
Definition: User.cpp:21
const Use & getOperandUse(unsigned i) const
Definition: User.h:182
Value * getOperand(unsigned i) const
Definition: User.h:169
unsigned getNumOperands() const
Definition: User.h:191
bool isDroppable() const
A droppable user is a user for which uses can be dropped without affecting correctness and should be ...
Definition: User.cpp:115
ValueT lookup(const KeyT &Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
Definition: ValueMap.h:164
LLVM Value Representation.
Definition: Value.h:74
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:255
static constexpr uint64_t MaximumAlignment
Definition: Value.h:807
const Value * stripAndAccumulateConstantOffsets(const DataLayout &DL, APInt &Offset, bool AllowNonInbounds, bool AllowInvariantGroup=false, function_ref< bool(Value &Value, APInt &Offset)> ExternalAnalysis=nullptr) const
Accumulate the constant offset this value has compared to a base pointer.
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition: Value.cpp:534
iterator_range< user_iterator > users()
Definition: Value.h:421
LLVMContext & getContext() const
All values hold a context through their type.
Definition: Value.cpp:1074
iterator_range< use_iterator > uses()
Definition: Value.h:376
StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:309
std::pair< iterator, bool > insert(const ValueT &V)
Definition: DenseSet.h:206
constexpr ScalarTy getFixedValue() const
Definition: TypeSize.h:199
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
Definition: TypeSize.h:171
An efficient, type-erasing, non-owning reference to a callable.
const ParentTy * getParent() const
Definition: ilist_node.h:32
self_iterator getIterator()
Definition: ilist_node.h:132
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
Definition: ilist_node.h:353
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:661
Enumerate the SCCs of a directed graph in reverse topological order of the SCC DAG.
Definition: SCCIterator.h:49
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool isAssumedReadNone(Attributor &A, const IRPosition &IRP, const AbstractAttribute &QueryingAA, bool &IsKnown)
Return true if IRP is readnone.
Definition: Attributor.cpp:654
bool isAssumedReadOnly(Attributor &A, const IRPosition &IRP, const AbstractAttribute &QueryingAA, bool &IsKnown)
Return true if IRP is readonly.
Definition: Attributor.cpp:649
raw_ostream & operator<<(raw_ostream &OS, const RangeTy &R)
Definition: Attributor.h:314
std::optional< Value * > combineOptionalValuesInAAValueLatice(const std::optional< Value * > &A, const std::optional< Value * > &B, Type *Ty)
Return the combination of A and B such that the result is a possible value of both.
Definition: Attributor.cpp:340
bool isValidAtPosition(const ValueAndContext &VAC, InformationCache &InfoCache)
Return true if the value of VAC is a valid at the position of VAC, that is a constant,...
Definition: Attributor.cpp:291
bool isAssumedThreadLocalObject(Attributor &A, Value &Obj, const AbstractAttribute &QueryingAA)
Return true if Obj is assumed to be a thread local object.
Definition: Attributor.cpp:836
bool isDynamicallyUnique(Attributor &A, const AbstractAttribute &QueryingAA, const Value &V, bool ForAnalysisOnly=true)
Return true if V is dynamically unique, that is, there are no two "instances" of V at runtime with di...
Definition: Attributor.cpp:232
bool getPotentialCopiesOfStoredValue(Attributor &A, StoreInst &SI, SmallSetVector< Value *, 4 > &PotentialCopies, const AbstractAttribute &QueryingAA, bool &UsedAssumedInformation, bool OnlyExact=false)
Collect all potential values of the one stored by SI into PotentialCopies.
Definition: Attributor.cpp:600
bool isGPU(const Module &M)
Return true iff M target a GPU (and we can use GPU AS reasoning).
Definition: Attributor.cpp:201
ValueScope
Flags to distinguish intra-procedural queries from potentially inter-procedural queries.
Definition: Attributor.h:180
@ Intraprocedural
Definition: Attributor.h:181
@ Interprocedural
Definition: Attributor.h:182
bool isValidInScope(const Value &V, const Function *Scope)
Return true if V is a valid value in Scope, that is a constant or an instruction/argument of Scope.
Definition: Attributor.cpp:281
bool isPotentiallyReachable(Attributor &A, const Instruction &FromI, const Instruction &ToI, const AbstractAttribute &QueryingAA, const AA::InstExclusionSetTy *ExclusionSet=nullptr, std::function< bool(const Function &F)> GoBackwardsCB=nullptr)
Return true if ToI is potentially reachable from FromI without running into any instruction in Exclus...
Definition: Attributor.cpp:817
bool isNoSyncInst(Attributor &A, const Instruction &I, const AbstractAttribute &QueryingAA)
Return true if I is a nosync instruction.
Definition: Attributor.cpp:206
bool getPotentiallyLoadedValues(Attributor &A, LoadInst &LI, SmallSetVector< Value *, 4 > &PotentialValues, SmallSetVector< Instruction *, 4 > &PotentialValueOrigins, const AbstractAttribute &QueryingAA, bool &UsedAssumedInformation, bool OnlyExact=false)
Collect all potential values LI could read into PotentialValues.
Definition: Attributor.cpp:590
Value * getWithType(Value &V, Type &Ty)
Try to convert V to type Ty without introducing new instructions.
Definition: Attributor.cpp:317
constexpr char Attrs[]
Key for Kernel::Metadata::mAttrs.
AddressSpace getAddressSpace(T *V)
Definition: AVR.h:65
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
@ Unsupported
This operation is completely unsupported on the target.
@ Undef
Value of the register doesn't matter.
Offsets
Offsets in bytes from the start of the input buffer.
Definition: SIInstrInfo.h:1542
@ SingleThread
Synchronized with respect to signal handlers executing in the same thread.
Definition: LLVMContext.h:54
@ CE
Windows NT (Windows on ARM)
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:443
LocationClass< Ty > location(Ty &L)
Definition: CommandLine.h:463
unsigned combineHashValue(unsigned a, unsigned b)
Simplistic combination of 32-bit hash values into 32-bit hash values.
Definition: DenseMapInfo.h:39
ElementType
The element type of an SRV or UAV resource.
Definition: DXILABI.h:75
constexpr double e
Definition: MathExtras.h:31
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
Definition: Path.cpp:227
const_iterator end(StringRef path)
Get end iterator over path.
Definition: Path.cpp:236
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
pred_iterator pred_end(BasicBlock *BB)
Definition: CFG.h:114
@ Offset
Definition: DWP.cpp:480
@ Length
Definition: DWP.cpp:480
bool operator<(int64_t V1, const APSInt &V2)
Definition: APSInt.h:361
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt gcd(const DynamicAPInt &A, const DynamicAPInt &B)
Definition: DynamicAPInt.h:383
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1722
bool isLegalToPromote(const CallBase &CB, Function *Callee, const char **FailureReason=nullptr)
Return true if the given indirect call site can be made to call Callee.
Constant * getInitialValueOfAllocation(const Value *V, const TargetLibraryInfo *TLI, Type *Ty)
If this is a call to an allocation function that initializes memory to a fixed value,...
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
Definition: STLExtras.h:1680
unsigned getPointerAddressSpace(const Type *T)
Definition: SPIRVUtils.h:126
auto successors(const MachineBasicBlock *BB)
bool isRemovableAlloc(const CallBase *V, const TargetLibraryInfo *TLI)
Return true if this is a call to an allocation function that does not have side effects that we are r...
APFloat abs(APFloat X)
Returns the absolute value of the argument.
Definition: APFloat.h:1434
raw_fd_ostream & outs()
This returns a reference to a raw_fd_ostream for standard output.
bool operator!=(uint64_t V1, const APInt &V2)
Definition: APInt.h:2058
UseCaptureKind DetermineUseCaptureKind(const Use &U, llvm::function_ref< bool(Value *, const DataLayout &)> IsDereferenceableOrNull)
Determine what kind of capture behaviour U may exhibit.
Value * getAllocAlignment(const CallBase *V, const TargetLibraryInfo *TLI)
Gets the alignment argument for an aligned_alloc-like function, using either built-in knowledge based...
Value * simplifyInstructionWithOperands(Instruction *I, ArrayRef< Value * > NewOps, const SimplifyQuery &Q)
Like simplifyInstruction but the operands of I are replaced with NewOps.
Value * GetPointerBaseWithConstantOffset(Value *Ptr, int64_t &Offset, const DataLayout &DL, bool AllowNonInbounds=true)
Analyze the specified pointer to see if it can be expressed as a base pointer plus a constant offset.
const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=6)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
scc_iterator< T > scc_begin(const T &G)
Construct the begin iterator for a deduced graph type T.
Definition: SCCIterator.h:233
PotentialValuesState< std::pair< AA::ValueAndContext, AA::ValueScope > > PotentialLLVMValuesState
Definition: Attributor.h:5222
bool isNoAliasCall(const Value *V)
Return true if this pointer is returned by a noalias function.
raw_ostream & WriteGraph(raw_ostream &O, const GraphType &G, bool ShortNames=false, const Twine &Title="")
Definition: GraphWriter.h:359
auto unique(Range &&R, Predicate P)
Definition: STLExtras.h:2013
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
ConstantRange getConstantRangeFromMetadata(const MDNode &RangeMD)
Parse out a conservative ConstantRange from !range metadata.
@ NONE
Definition: Attributor.h:6425
const Value * getPointerOperand(const Value *V)
A helper function that returns the pointer operand of a load, store or GEP instruction.
Value * simplifyInstruction(Instruction *I, const SimplifyQuery &Q)
See if we can compute a simplified version of this instruction.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1729
pred_iterator pred_begin(BasicBlock *BB)
Definition: CFG.h:110
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Definition: MathExtras.h:324
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition: MathExtras.h:275
void sort(IteratorTy Start, IteratorTy End)
Definition: STLExtras.h:1647
MemoryEffectsBase< IRMemLocation > MemoryEffects
Summary of how a function affects memory in the program.
Definition: ModRef.h:268
bool NullPointerIsDefined(const Function *F, unsigned AS=0)
Check whether null pointer dereferencing is considered undefined behavior for a given function or an ...
Definition: Function.cpp:2073
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
bool isPointerTy(const Type *T)
Definition: SPIRVUtils.h:120
bool wouldInstructionBeTriviallyDead(const Instruction *I, const TargetLibraryInfo *TLI=nullptr)
Return true if the result produced by the instruction would have no side effects if it was not used.
Definition: Local.cpp:419
bool set_union(S1Ty &S1, const S2Ty &S2)
set_union(A, B) - Compute A := A u B, return whether A changed.
Definition: SetOperations.h:34
void RemapInstruction(Instruction *I, ValueToValueMapTy &VM, RemapFlags Flags=RF_None, ValueMapTypeRemapper *TypeMapper=nullptr, ValueMaterializer *Materializer=nullptr)
Convert the instruction operands from referencing the current values into those specified by VM.
Definition: ValueMapper.h:263
CallBase & promoteCall(CallBase &CB, Function *Callee, CastInst **RetBitCast=nullptr)
Promote the given indirect call site to unconditionally call Callee.
bool hasAssumption(const Function &F, const KnownAssumptionString &AssumptionStr)
Return true if F has the assumption AssumptionStr attached.
Definition: Assumptions.cpp:70
RetainedKnowledge getKnowledgeFromUse(const Use *U, ArrayRef< Attribute::AttrKind > AttrKinds)
Return a valid Knowledge associated to the Use U if its Attribute kind is in AttrKinds.
bool isKnownNonZero(const Value *V, const SimplifyQuery &Q, unsigned Depth=0)
Return true if the given value is known to be non-zero when defined.
AtomicOrdering
Atomic ordering for LLVM's memory model.
@ Other
Any other memory.
ChangeStatus clampStateAndIndicateChange< DerefState >(DerefState &S, const DerefState &R)
Value * simplifyCmpInst(unsigned Predicate, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for a CmpInst, fold the result or return null.
PotentialValuesState< APInt > PotentialConstantIntValuesState
Definition: Attributor.h:5220
DWARFExpression::Operation Op
bool isGuaranteedNotToBeUndefOrPoison(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Return true if this function can prove that V does not have undef bits and is never poison.
Value * getFreedOperand(const CallBase *CB, const TargetLibraryInfo *TLI)
If this if a call to a free function, return the freed operand.
ChangeStatus clampStateAndIndicateChange(StateType &S, const StateType &R)
Helper function to clamp a state S of type StateType with the information in R and indicate/return if...
Definition: Attributor.h:3463
bool isSafeToSpeculativelyExecute(const Instruction *I, const Instruction *CtxI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr, const TargetLibraryInfo *TLI=nullptr)
Return true if the instruction does not have any effects besides calculating the result and does not ...
constexpr unsigned BitWidth
Definition: BitmaskEnum.h:191
ChangeStatus
{
Definition: Attributor.h:484
std::optional< APInt > getAllocSize(const CallBase *CB, const TargetLibraryInfo *TLI, function_ref< const Value *(const Value *)> Mapper=[](const Value *V) { return V;})
Return the size of the requested allocation.
DenseSet< StringRef > getAssumptions(const Function &F)
Return the set of all assumptions for the function F.
Definition: Assumptions.cpp:86
Align assumeAligned(uint64_t Value)
Treats the value 0 as a 1, so Align is always at least 1.
Definition: Alignment.h:111
Instruction * SplitBlockAndInsertIfThen(Value *Cond, BasicBlock::iterator SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, BasicBlock *ThenBlock=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...
@ OPTIONAL
The target may be valid if the source is not.
@ NONE
Do not track a dependence between source and target.
@ REQUIRED
The target cannot be valid if the source is not.
bool mayContainIrreducibleControl(const Function &F, const LoopInfo *LI)
T bit_floor(T Value)
Returns the largest integral power of two no greater than Value if Value is nonzero.
Definition: bit.h:327
KnownFPClass computeKnownFPClass(const Value *V, const APInt &DemandedElts, FPClassTest InterestedClasses, unsigned Depth, const SimplifyQuery &SQ)
Determine which floating-point classes are valid for V, and return them in KnownFPClass bit sets.
bool isIdentifiedObject(const Value *V)
Return true if this pointer refers to a distinct and identifiable object.
constexpr StringRef AssumptionAttrKey
The key we use for assumption attributes.
Definition: Assumptions.h:28
Implement std::hash so that hash_code can be used in STL containers.
Definition: BitVector.h:858
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition: BitVector.h:860
A type to track pointer/struct usage and accesses for AAPointerInfo.
AAPointerInfo::const_bin_iterator end() const
ChangeStatus addAccess(Attributor &A, const AAPointerInfo::RangeList &Ranges, Instruction &I, std::optional< Value * > Content, AAPointerInfo::AccessKind Kind, Type *Ty, Instruction *RemoteI=nullptr)
Add a new Access to the state at offset Offset and with size Size.
DenseMap< const Instruction *, SmallVector< unsigned > > RemoteIMap
AAPointerInfo::const_bin_iterator begin() const
bool forallInterferingAccesses(Instruction &I, function_ref< bool(const AAPointerInfo::Access &, bool)> CB, AA::RangeTy &Range) const
See AAPointerInfo::forallInterferingAccesses.
State(State &&SIS)=default
const AAPointerInfo::Access & getAccess(unsigned Index) const
bool forallInterferingAccesses(AA::RangeTy Range, function_ref< bool(const AAPointerInfo::Access &, bool)> CB) const
See AAPointerInfo::forallInterferingAccesses.
SmallVector< AAPointerInfo::Access > AccessList
bool isAtFixpoint() const override
See AbstractState::isAtFixpoint().
static State getWorstState(const State &SIS)
Return the worst possible representable state.
AAPointerInfo::OffsetBinsTy OffsetBins
ChangeStatus indicateOptimisticFixpoint() override
See AbstractState::indicateOptimisticFixpoint().
State & operator=(const State &R)
ChangeStatus indicatePessimisticFixpoint() override
See AbstractState::indicatePessimisticFixpoint().
static State getBestState(const State &SIS)
Return the best possible representable state.
bool isValidState() const override
See AbstractState::isValidState().
----------------—AAIntraFnReachability Attribute-----------------------—
ReachabilityQueryInfo(const ReachabilityQueryInfo &RQI)
unsigned Hash
Precomputed hash for this RQI.
ReachabilityQueryInfo(const Instruction *From, const ToTy *To)
ReachabilityQueryInfo(Attributor &A, const Instruction &From, const ToTy &To, const AA::InstExclusionSetTy *ES, bool MakeUnique)
Constructor replacement to ensure unique and stable sets are used for the cache.
An abstract interface for address space information.
Definition: Attributor.h:6236
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:6275
An abstract interface for all align attributes.
Definition: Attributor.h:4271
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:4302
Align getKnownAlign() const
Return known alignment.
Definition: Attributor.h:4285
static const char ID
Definition: Attributor.h:6310
An abstract attribute for getting assumption information.
Definition: Attributor.h:6162
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:6190
An abstract state for querying live call edges.
Definition: Attributor.h:5486
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:5529
An abstract Attribute for specializing "dynamic" components of "denormal-fp-math" and "denormal-fp-ma...
Definition: Attributor.h:6396
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:6418
An abstract interface for all dereferenceable attribute.
Definition: Attributor.h:4217
uint32_t getKnownDereferenceableBytes() const
Return known dereferenceable bytes.
Definition: Attributor.h:4241
uint32_t getAssumedDereferenceableBytes() const
Return assumed dereferenceable bytes.
Definition: Attributor.h:4236
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:4262
An abstract interface for llvm::GlobalValue information interference.
Definition: Attributor.h:6315
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:6349
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:4564
An abstract interface for indirect call information interference.
Definition: Attributor.h:6354
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:6390
An abstract interface to track if a value leaves it's defining function instance.
Definition: Attributor.h:4309
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:4342
An abstract Attribute for computing reachability between functions.
Definition: Attributor.h:5682
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:5717
bool canReach(Attributor &A, const Function &Fn) const
If the function represented by this possition can reach Fn.
Definition: Attributor.h:5688
virtual bool instructionCanReach(Attributor &A, const Instruction &Inst, const Function &Fn, const AA::InstExclusionSetTy *ExclusionSet=nullptr) const =0
Can Inst reach Fn.
An abstract interface to determine reachability of point A to B.
Definition: Attributor.h:3815
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:3843
virtual bool isAssumedReachable(Attributor &A, const Instruction &From, const Instruction &To, const AA::InstExclusionSetTy *ExclusionSet=nullptr) const =0
Returns true if 'From' instruction is assumed to reach, 'To' instruction.
An abstract interface for liveness abstract attribute.
Definition: Attributor.h:3975
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:4065
An abstract interface for memory access kind related attributes (readnone/readonly/writeonly).
Definition: Attributor.h:4629
bool isAssumedReadOnly() const
Return true if we assume that the underlying value is not accessed (=written) in its respective scope...
Definition: Attributor.h:4668
bool isKnownReadNone() const
Return true if we know that the underlying value is not read or accessed in its respective scope.
Definition: Attributor.h:4656
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:4695
bool isAssumedReadNone() const
Return true if we assume that the underlying value is not read or accessed in its respective scope.
Definition: Attributor.h:4660
An abstract interface for all memory location attributes (readnone/argmemonly/inaccessiblememonly/ina...
Definition: Attributor.h:4704
static std::string getMemoryLocationsAsStr(MemoryLocationsKind MLK)
Return the locations encoded by MLK as a readable string.
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:4880
StateType::base_t MemoryLocationsKind
Definition: Attributor.h:4705
An abstract interface for all nonnull attributes.
Definition: Attributor.h:3591
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:3626
An abstract interface for all noalias attributes.
Definition: Attributor.h:3850
static bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
See IRAttribute::isImpliedByIR.
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:3889
An abstract interface for all nocapture attributes.
Definition: Attributor.h:4350
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:4423
bool isAssumedNoCaptureMaybeReturned() const
Return true if we assume that the underlying value is not captured in its respective scope but we all...
Definition: Attributor.h:4404
static bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
See IRAttribute::isImpliedByIR.
@ NO_CAPTURE_MAYBE_RETURNED
If we do not capture the value in memory or through integers we can only communicate it back as a der...
Definition: Attributor.h:4380
static void determineFunctionCaptureCapabilities(const IRPosition &IRP, const Function &F, BitIntegerState &State)
Update State according to the capture capabilities of F for position IRP.
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:5440
An AbstractAttribute for nofree.
Definition: Attributor.h:3896
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:3939
An abstract attribute for norecurse.
Definition: Attributor.h:3684
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:3708
An AbstractAttribute for noreturn.
Definition: Attributor.h:3946
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:3970
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:3584
static bool isAlignedBarrier(const CallBase &CB, bool ExecutedAligned)
Helper function to determine if CB is an aligned (GPU) barrier.
static bool isNonRelaxedAtomic(const Instruction *I)
Helper function used to determine whether an instruction is non-relaxed atomic.
static bool isNoSyncIntrinsic(const Instruction *I)
Helper function specific for intrinsics which are potentially volatile.
An abstract interface for all noundef attributes.
Definition: Attributor.h:5354
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:5389
static bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
See IRAttribute::isImpliedByIR.
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:3501
An abstract Attribute for determining the necessity of the convergent attribute.
Definition: Attributor.h:5722
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:5750
bool isAssumedNotConvergent() const
Return true if "non-convergent" is assumed.
Definition: Attributor.h:5732
An abstract interface for all nonnull attributes.
Definition: Attributor.h:3633
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:3677
static bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
See AbstractAttribute::isImpliedByIR(...).
An access description.
Definition: Attributor.h:5940
A container for a list of ranges.
Definition: Attributor.h:5789
static void set_difference(const RangeList &L, const RangeList &R, RangeList &D)
Copy ranges from L that are not in R, into D.
Definition: Attributor.h:5825
An abstract interface for struct information.
Definition: Attributor.h:5754
virtual const_bin_iterator begin() const =0
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:6154
virtual int64_t numOffsetBins() const =0
An abstract interface for potential values analysis.
Definition: Attributor.h:5244
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:5303
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:5340
static Value * getSingleValue(Attributor &A, const AbstractAttribute &AA, const IRPosition &IRP, SmallVectorImpl< AA::ValueAndContext > &Values)
Extract the single value in Values if any.
An abstract interface for privatizability.
Definition: Attributor.h:4578
virtual std::optional< Type * > getPrivatizableType() const =0
Return the type we can choose for a private copy of the underlying value.
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:4620
An abstract attribute for undefined behavior.
Definition: Attributor.h:3777
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:3810
An abstract attribute for getting all assumption underlying objects.
Definition: Attributor.h:6194
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:6224
An abstract interface for range value analysis.
Definition: Attributor.h:4885
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:4948
An abstract interface for value simplify abstract attribute.
Definition: Attributor.h:4502
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:4524
An abstract attribute for willreturn.
Definition: Attributor.h:3715
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:3772
Helper to represent an access offset and size, with logic to deal with uncertainty and check for over...
Definition: Attributor.h:237
static constexpr int64_t Unknown
Definition: Attributor.h:311
static RangeTy getUnknown()
Definition: Attributor.h:243
Base struct for all "concrete attribute" deductions.
Definition: Attributor.h:3283
void print(raw_ostream &OS) const
Helper functions, for debug purposes only.
Definition: Attributor.h:3367
virtual StateType & getState()=0
Return the internal abstract state for inspection.
An interface to query the internal state of an abstract attribute.
Definition: Attributor.h:2603
virtual ChangeStatus indicatePessimisticFixpoint()=0
Indicate that the abstract state should converge to the pessimistic state.
virtual bool isValidState() const =0
Return if this abstract state is in a valid state.
virtual ChangeStatus indicateOptimisticFixpoint()=0
Indicate that the abstract state should converge to the optimistic state.
Helper for AA::PointerInfo::Access DenseMap/Set usage ignoring everythign but the instruction.
static unsigned getHashValue(const Access &A)
static Access getTombstoneKey()
static bool isEqual(const Access &LHS, const Access &RHS)
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
uint64_t value() const
This is a hole in the type system and should not be abused.
Definition: Alignment.h:85
Helper struct used in the communication between an abstract attribute (AA) that wants to change the s...
Definition: Attributor.h:2211
std::function< void(const ArgumentReplacementInfo &, AbstractCallSite, SmallVectorImpl< Value * > &)> ACSRepairCBTy
Abstract call site (ACS) repair callback type.
Definition: Attributor.h:2234
const Argument & getReplacedArg() const
Definition: Attributor.h:2241
std::function< void(const ArgumentReplacementInfo &, Function &, Function::arg_iterator)> CalleeRepairCBTy
Callee repair callback type.
Definition: Attributor.h:2220
The fixpoint analysis framework that orchestrates the attribute deduction.
Definition: Attributor.h:1508
std::function< std::optional< Value * >(const IRPosition &, const AbstractAttribute *, bool &)> SimplifictionCallbackTy
Register CB as a simplification callback.
Definition: Attributor.h:2016
Specialization of the integer state for a bit-wise encoding.
Definition: Attributor.h:2744
BitIntegerState & removeAssumedBits(base_t BitsEncoding)
Remove the bits in BitsEncoding from the "assumed bits" if not known.
Definition: Attributor.h:2769
BitIntegerState & addKnownBits(base_t Bits)
Add the bits in BitsEncoding to the "known bits".
Definition: Attributor.h:2761
Simple wrapper for a single bit (boolean) state.
Definition: Attributor.h:2887
Represent subnormal handling kind for floating point instruction inputs and outputs.
static constexpr DenormalMode getDefault()
Return the assumed default mode for a function without denormal-fp-math.
static constexpr DenormalMode getInvalid()
static unsigned getHashValue(const Access &A)
static bool isEqual(const Access &LHS, const Access &RHS)
static bool isEqual(const AA::RangeTy &A, const AA::RangeTy B)
static unsigned getHashValue(const AA::RangeTy &Range)
static ReachabilityQueryInfo< ToTy > * getEmptyKey()
static ReachabilityQueryInfo< ToTy > * getTombstoneKey()
static bool isEqual(const ReachabilityQueryInfo< ToTy > *LHS, const ReachabilityQueryInfo< ToTy > *RHS)
static unsigned getHashValue(const ReachabilityQueryInfo< ToTy > *RQI)
An information struct used to provide DenseMap with the various necessary components for a given valu...
Definition: DenseMapInfo.h:52
State for dereferenceable attribute.
Definition: Attributor.h:4071
IncIntegerState DerefBytesState
State representing for dereferenceable bytes.
Definition: Attributor.h:4087
ChangeStatus manifest(Attributor &A) override
See AbstractAttribute::manifest(...).
Definition: Attributor.h:3220
Helper to describe and deal with positions in the LLVM-IR.
Definition: Attributor.h:581
Function * getAssociatedFunction() const
Return the associated function, if any.
Definition: Attributor.h:712
static const IRPosition callsite_returned(const CallBase &CB)
Create a position describing the returned value of CB.
Definition: Attributor.h:649
static const IRPosition returned(const Function &F, const CallBaseContext *CBContext=nullptr)
Create a position describing the returned value of F.
Definition: Attributor.h:631
Argument * getAssociatedArgument() const
Return the associated argument, if any.
Definition: Attributor.cpp:996
static const IRPosition value(const Value &V, const CallBaseContext *CBContext=nullptr)
Create a position describing the value of V.
Definition: Attributor.h:605
int getCalleeArgNo() const
Return the callee argument number of the associated value if it is an argument or call site argument,...
Definition: Attributor.h:799
static const IRPosition inst(const Instruction &I, const CallBaseContext *CBContext=nullptr)
Create a position describing the instruction I.
Definition: Attributor.h:617
static const IRPosition callsite_argument(const CallBase &CB, unsigned ArgNo)
Create a position describing the argument of CB at position ArgNo.
Definition: Attributor.h:654
@ IRP_ARGUMENT
An attribute for a function argument.
Definition: Attributor.h:595
@ IRP_RETURNED
An attribute for the function return value.
Definition: Attributor.h:591
@ IRP_CALL_SITE
An attribute for a call site (function scope).
Definition: Attributor.h:594
@ IRP_CALL_SITE_RETURNED
An attribute for a call site return value.
Definition: Attributor.h:592
@ IRP_FUNCTION
An attribute for a function (scope).
Definition: Attributor.h:593
@ IRP_CALL_SITE_ARGUMENT
An attribute for a call site argument.
Definition: Attributor.h:596
@ IRP_INVALID
An invalid position.
Definition: Attributor.h:588
Instruction * getCtxI() const
Return the context instruction, if any.
Definition: Attributor.h:765
static const IRPosition argument(const Argument &Arg, const CallBaseContext *CBContext=nullptr)
Create a position describing the argument Arg.
Definition: Attributor.h:638
Type * getAssociatedType() const
Return the type this abstract attribute is associated with.
Definition: Attributor.h:788
static const IRPosition function(const Function &F, const CallBaseContext *CBContext=nullptr)
Create a position describing the function scope of F.
Definition: Attributor.h:624
const CallBaseContext * getCallBaseContext() const
Get the call base context from the position.
Definition: Attributor.h:927
Value & getAssociatedValue() const
Return the value this abstract attribute is associated with.
Definition: Attributor.h:779
Value & getAnchorValue() const
Return the value this abstract attribute is anchored with.
Definition: Attributor.h:698
int getCallSiteArgNo() const
Return the call site argument number of the associated value if it is an argument or call site argume...
Definition: Attributor.h:808
static const IRPosition function_scope(const IRPosition &IRP, const CallBaseContext *CBContext=nullptr)
Create a position with function scope matching the "context" of IRP.
Definition: Attributor.h:677
Kind getPositionKind() const
Return the associated position kind.
Definition: Attributor.h:877
bool isArgumentPosition() const
Return true if the position is an argument or call site argument.
Definition: Attributor.h:909
static const IRPosition callsite_function(const CallBase &CB)
Create a position describing the function scope of CB.
Definition: Attributor.h:644
Function * getAnchorScope() const
Return the Function surrounding the anchor value.
Definition: Attributor.h:753
Incoming for lane maks phi as machine instruction, incoming register Reg and incoming block Block are...
Data structure to hold cached (LLVM-IR) information.
Definition: Attributor.h:1198
bool isOnlyUsedByAssume(const Instruction &I) const
Definition: Attributor.h:1292
AP::Result * getAnalysisResultForFunction(const Function &F, bool CachedOnly=false)
Return the analysis result from a pass AP for function F.
Definition: Attributor.h:1302
State for an integer range.
Definition: Attributor.h:2929
ConstantRange getKnown() const
Return the known state encoding.
Definition: Attributor.h:2985
ConstantRange getAssumed() const
Return the assumed state encoding.
Definition: Attributor.h:2988
bool isValidState() const override
See AbstractState::isValidState() NOTE: For now we simply pretend that the worst possible state is in...
Definition: Attributor.h:2662
bool isAtFixpoint() const override
See AbstractState::isAtFixpoint()
Definition: Attributor.h:2665
ChangeStatus indicateOptimisticFixpoint() override
See AbstractState::indicateOptimisticFixpoint(...)
Definition: Attributor.h:2668
base_t getAssumed() const
Return the assumed state encoding.
Definition: Attributor.h:2683
static constexpr base_t getWorstState()
Return the worst possible representable state.
Definition: Attributor.h:2655
ChangeStatus indicatePessimisticFixpoint() override
See AbstractState::indicatePessimisticFixpoint(...)
Definition: Attributor.h:2674
Helper that allows to insert a new assumption string in the known assumption set by creating a (stati...
Definition: Assumptions.h:36
FPClassTest KnownFPClasses
Floating-point classes the value could be one of.
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Definition: Alignment.h:117
A "must be executed context" for a given program point PP is the set of instructions,...
Definition: MustExecute.h:386
iterator & end()
Return an universal end iterator.
Definition: MustExecute.h:434
bool findInContextOf(const Instruction *I, const Instruction *PP)
Helper to look for I in the context of PP.
Definition: MustExecute.h:470
iterator & begin(const Instruction *PP)
Return an iterator to explore the context around PP.
Definition: MustExecute.h:420
bool checkForAllContext(const Instruction *PP, function_ref< bool(const Instruction *)> Pred)
}
Definition: MustExecute.h:456
Various options to control the behavior of getObjectSize.
A class for a set state.
Definition: Attributor.h:4959
static unsigned MaxPotentialValues
Maximum number of potential values to be tracked.
Definition: Attributor.h:5012
void unionAssumed(const MemberTy &C)
Union assumed set with the passed value.
Definition: Attributor.h:5029
static PotentialValuesState getBestState()
Return empty set as the best state of potential values.
Definition: Attributor.h:5015
const SetTy & getAssumedSet() const
Return this set.
Definition: Attributor.h:4989
Represent one information held inside an operand bundle of an llvm.assume.
A MapVector that performs no allocations if smaller than a certain size.
Definition: MapVector.h:254
Helper to tie a abstract state implementation to an abstract attribute.
Definition: Attributor.h:3172
StateType & getState() override
See AbstractAttribute::getState(...).
Definition: Attributor.h:3180
bool unionAssumed(std::optional< Value * > Other)
Merge Other into the currently assumed simplified value.