LLVM 24.0.0git
Attributor.h
Go to the documentation of this file.
1//===- Attributor.h --- Module-wide attribute deduction ---------*- C++ -*-===//
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// Attributor: An inter procedural (abstract) "attribute" deduction framework.
10//
11// The Attributor framework is an inter procedural abstract analysis (fixpoint
12// iteration analysis). The goal is to allow easy deduction of new attributes as
13// well as information exchange between abstract attributes in-flight.
14//
15// The Attributor class is the driver and the link between the various abstract
16// attributes. The Attributor will iterate until a fixpoint state is reached by
17// all abstract attributes in-flight, or until it will enforce a pessimistic fix
18// point because an iteration limit is reached.
19//
20// Abstract attributes, derived from the AbstractAttribute class, actually
21// describe properties of the code. They can correspond to actual LLVM-IR
22// attributes, or they can be more general, ultimately unrelated to LLVM-IR
23// attributes. The latter is useful when an abstract attributes provides
24// information to other abstract attributes in-flight but we might not want to
25// manifest the information. The Attributor allows to query in-flight abstract
26// attributes through the `Attributor::getAAFor` method (see the method
27// description for an example). If the method is used by an abstract attribute
28// P, and it results in an abstract attribute Q, the Attributor will
29// automatically capture a potential dependence from Q to P. This dependence
30// will cause P to be reevaluated whenever Q changes in the future.
31//
32// The Attributor will only reevaluate abstract attributes that might have
33// changed since the last iteration. That means that the Attribute will not
34// revisit all instructions/blocks/functions in the module but only query
35// an update from a subset of the abstract attributes.
36//
37// The update method `AbstractAttribute::updateImpl` is implemented by the
38// specific "abstract attribute" subclasses. The method is invoked whenever the
39// currently assumed state (see the AbstractState class) might not be valid
40// anymore. This can, for example, happen if the state was dependent on another
41// abstract attribute that changed. In every invocation, the update method has
42// to adjust the internal state of an abstract attribute to a point that is
43// justifiable by the underlying IR and the current state of abstract attributes
44// in-flight. Since the IR is given and assumed to be valid, the information
45// derived from it can be assumed to hold. However, information derived from
46// other abstract attributes is conditional on various things. If the justifying
47// state changed, the `updateImpl` has to revisit the situation and potentially
48// find another justification or limit the optimistic assumes made.
49//
50// Change is the key in this framework. Until a state of no-change, thus a
51// fixpoint, is reached, the Attributor will query the abstract attributes
52// in-flight to re-evaluate their state. If the (current) state is too
53// optimistic, hence it cannot be justified anymore through other abstract
54// attributes or the state of the IR, the state of the abstract attribute will
55// have to change. Generally, we assume abstract attribute state to be a finite
56// height lattice and the update function to be monotone. However, these
57// conditions are not enforced because the iteration limit will guarantee
58// termination. If an optimistic fixpoint is reached, or a pessimistic fix
59// point is enforced after a timeout, the abstract attributes are tasked to
60// manifest their result in the IR for passes to come.
61//
62// Attribute manifestation is not mandatory. If desired, there is support to
63// generate a single or multiple LLVM-IR attributes already in the helper struct
64// IRAttribute. In the simplest case, a subclass inherits from IRAttribute with
65// a proper Attribute::AttrKind as template parameter. The Attributor
66// manifestation framework will then create and place a new attribute if it is
67// allowed to do so (based on the abstract state). Other use cases can be
68// achieved by overloading AbstractAttribute or IRAttribute methods.
69//
70//
71// The "mechanics" of adding a new "abstract attribute":
72// - Define a class (transitively) inheriting from AbstractAttribute and one
73// (which could be the same) that (transitively) inherits from AbstractState.
74// For the latter, consider the already available BooleanState and
75// {Inc,Dec,Bit}IntegerState if they fit your needs, e.g., you require only a
76// number tracking or bit-encoding.
77// - Implement all pure methods. Also use overloading if the attribute is not
78// conforming with the "default" behavior: A (set of) LLVM-IR attribute(s) for
79// an argument, call site argument, function return value, or function. See
80// the class and method descriptions for more information on the two
81// "Abstract" classes and their respective methods.
82// - Register opportunities for the new abstract attribute in the
83// `Attributor::identifyDefaultAbstractAttributes` method if it should be
84// counted as a 'default' attribute.
85// - Add sufficient tests.
86// - Add a Statistics object for bookkeeping. If it is a simple (set of)
87// attribute(s) manifested through the Attributor manifestation framework, see
88// the bookkeeping function in Attributor.cpp.
89// - If instructions with a certain opcode are interesting to the attribute, add
90// that opcode to the switch in `Attributor::identifyAbstractAttributes`. This
91// will make it possible to query all those instructions through the
92// `InformationCache::getOpcodeInstMapForFunction` interface and eliminate the
93// need to traverse the IR repeatedly.
94//
95//===----------------------------------------------------------------------===//
96
97#ifndef LLVM_TRANSFORMS_IPO_ATTRIBUTOR_H
98#define LLVM_TRANSFORMS_IPO_ATTRIBUTOR_H
99
100#include "llvm/ADT/DenseSet.h"
101#include "llvm/ADT/GraphTraits.h"
102#include "llvm/ADT/IntervalMap.h"
103#include "llvm/ADT/MapVector.h"
104#include "llvm/ADT/STLExtras.h"
106#include "llvm/ADT/SetVector.h"
107#include "llvm/ADT/SmallSet.h"
108#include "llvm/ADT/iterator.h"
110#include "llvm/Analysis/CFG.h"
120#include "llvm/IR/Attributes.h"
122#include "llvm/IR/Constants.h"
123#include "llvm/IR/GlobalValue.h"
124#include "llvm/IR/InstIterator.h"
125#include "llvm/IR/Instruction.h"
126#include "llvm/IR/Instructions.h"
127#include "llvm/IR/Module.h"
128#include "llvm/IR/PassManager.h"
129#include "llvm/IR/Value.h"
132#include "llvm/Support/Casting.h"
136#include "llvm/Support/ModRef.h"
141
142#include <array>
143#include <limits>
144#include <map>
145#include <optional>
146
147namespace llvm {
148
149class DataLayout;
150class LLVMContext;
151class Pass;
152template <typename Fn> class function_ref;
153struct AADepGraphNode;
154struct AADepGraph;
155struct Attributor;
156struct AbstractAttribute;
157struct InformationCache;
158struct AAIsDead;
160struct IRPosition;
161
162class Function;
163
164/// Abstract Attribute helper functions.
165namespace AA {
167
168/// Return true iff \p M target a GPU (and we can use GPU AS reasoning).
169LLVM_ABI bool isGPU(const Module &M);
170
171/// Check if the given address space \p AS corresponds to a GPU shared
172/// address space for the target triple in module \p M.
173LLVM_ABI bool isGPUSharedAddressSpace(const Module &M, unsigned AS);
174
175/// Check if the given address space \p AS corresponds to a GPU constant
176/// address space for the target triple in module \p M.
177LLVM_ABI bool isGPUConstantAddressSpace(const Module &M, unsigned AS);
178
179/// Check if the given address space \p AS corresponds to a GPU local/private
180/// address space for the target triple in module \p M.
181LLVM_ABI bool isGPULocalAddressSpace(const Module &M, unsigned AS);
182
183/// Flags to distinguish intra-procedural queries from *potentially*
184/// inter-procedural queries. Not that information can be valid for both and
185/// therefore both bits might be set.
191
192struct ValueAndContext : public std::pair<Value *, const Instruction *> {
193 using Base = std::pair<Value *, const Instruction *>;
195 ValueAndContext(Value &V, const Instruction *CtxI) : Base(&V, CtxI) {}
196 ValueAndContext(Value &V, const Instruction &CtxI) : Base(&V, &CtxI) {}
197
198 Value *getValue() const { return this->first; }
199 const Instruction *getCtxI() const { return this->second; }
200};
201
202/// Return true if \p I is a `nosync` instruction. Use generic reasoning and
203/// potentially the corresponding AANoSync.
205 const AbstractAttribute &QueryingAA);
206
207/// Return true if \p V is dynamically unique, that is, there are no two
208/// "instances" of \p V at runtime with different values.
209/// Note: If \p ForAnalysisOnly is set we only check that the Attributor will
210/// never use \p V to represent two "instances" not that \p V could not
211/// technically represent them.
213 const AbstractAttribute &QueryingAA,
214 const Value &V, bool ForAnalysisOnly = true);
215
216/// Return true if \p V is a valid value in \p Scope, that is a constant or an
217/// instruction/argument of \p Scope.
218LLVM_ABI bool isValidInScope(const Value &V, const Function *Scope);
219
220/// Return true if the value of \p VAC is a valid at the position of \p VAC,
221/// that is a constant, an argument of the same function, or an instruction in
222/// that function that dominates the position.
223LLVM_ABI bool isValidAtPosition(const ValueAndContext &VAC,
224 InformationCache &InfoCache);
225
226/// Try to convert \p V to type \p Ty without introducing new instructions. If
227/// this is not possible return `nullptr`. Note: this function basically knows
228/// how to cast various constants.
230
231/// Return the combination of \p A and \p B such that the result is a possible
232/// value of both. \p B is potentially casted to match the type \p Ty or the
233/// type of \p A if \p Ty is null.
234///
235/// Examples:
236/// X + none => X
237/// not_none + undef => not_none
238/// V1 + V2 => nullptr
239LLVM_ABI std::optional<Value *>
240combineOptionalValuesInAAValueLatice(const std::optional<Value *> &A,
241 const std::optional<Value *> &B, Type *Ty);
242
243/// Helper to represent an access offset and size, with logic to deal with
244/// uncertainty and check for overlapping accesses.
245struct RangeTy {
247 int64_t Size = Unassigned;
248
249 RangeTy(int64_t Offset, int64_t Size) : Offset(Offset), Size(Size) {}
250 RangeTy() = default;
251 static RangeTy getUnknown() { return RangeTy{Unknown, Unknown}; }
252
253 /// Return true if offset or size are unknown.
256 }
257
258 /// Return true if offset and size are unknown, thus this is the default
259 /// unknown object.
262 }
263
264 /// Return true if the offset and size are unassigned.
265 bool isUnassigned() const {
267 "Inconsistent state!");
268 return Offset == RangeTy::Unassigned;
269 }
270
271 /// Return true if this offset and size pair might describe an address that
272 /// overlaps with \p Range.
273 bool mayOverlap(const RangeTy &Range) const {
274 // Any unknown value and we are giving up -> overlap.
275 if (offsetOrSizeAreUnknown() || Range.offsetOrSizeAreUnknown())
276 return true;
277
278 // Check if one offset point is in the other interval [offset,
279 // offset+size].
280 return Range.Offset + Range.Size > Offset && Range.Offset < Offset + Size;
281 }
282
284 if (R.isUnassigned())
285 return *this;
286 if (isUnassigned())
287 return *this = R;
288 if (Offset == Unknown || R.Offset == Unknown)
289 Offset = Unknown;
290 if (Size == Unknown || R.Size == Unknown)
291 Size = Unknown;
293 return *this;
294 if (Offset == Unknown) {
295 Size = std::max(Size, R.Size);
296 } else if (Size == Unknown) {
297 Offset = std::min(Offset, R.Offset);
298 } else {
299 Offset = std::min(Offset, R.Offset);
300 Size = std::max(Offset + Size, R.Offset + R.Size) - Offset;
301 }
302 return *this;
303 }
304
305 /// Comparison for sorting ranges.
306 ///
307 /// Returns true if the offset of \p L is less than that of \p R. If the two
308 /// offsets are same, compare the sizes instead.
309 inline static bool LessThan(const RangeTy &L, const RangeTy &R) {
310 if (L.Offset < R.Offset)
311 return true;
312 if (L.Offset == R.Offset)
313 return L.Size < R.Size;
314 return false;
315 }
316
317 /// Constants used to represent special offsets or sizes.
318 /// - We cannot assume that Offsets and Size are non-negative.
319 /// - The constants should not clash with DenseMapInfo, such as EmptyKey
320 /// (INT64_MAX).
321 /// We use values "in the middle" of the 64 bit range to represent these
322 /// special cases.
323 static constexpr int64_t Unassigned = std::numeric_limits<int32_t>::min();
324 static constexpr int64_t Unknown = std::numeric_limits<int32_t>::max();
325};
326
328 OS << "[" << R.Offset << ", " << R.Size << "]";
329 return OS;
330}
331
332inline bool operator==(const RangeTy &A, const RangeTy &B) {
333 return A.Offset == B.Offset && A.Size == B.Size;
334}
335
336inline bool operator!=(const RangeTy &A, const RangeTy &B) { return !(A == B); }
337
338/// Return the initial value of \p Obj with type \p Ty if that is a constant.
341 Value &Obj, Type &Ty, const TargetLibraryInfo *TLI,
342 const DataLayout &DL, RangeTy *RangePtr = nullptr);
343
344/// Collect all potential values \p LI could read into \p PotentialValues. That
345/// is, the only values read by \p LI are assumed to be known and all are in
346/// \p PotentialValues. \p PotentialValueOrigins will contain all the
347/// instructions that might have put a potential value into \p PotentialValues.
348/// Dependences onto \p QueryingAA are properly tracked, \p
349/// UsedAssumedInformation will inform the caller if assumed information was
350/// used.
351///
352/// \returns True if the assumed potential copies are all in \p PotentialValues,
353/// false if something went wrong and the copies could not be
354/// determined.
356 Attributor &A, LoadInst &LI, SmallSetVector<Value *, 4> &PotentialValues,
357 SmallSetVector<Instruction *, 4> &PotentialValueOrigins,
358 const AbstractAttribute &QueryingAA, bool &UsedAssumedInformation,
359 bool OnlyExact = false);
360
361/// Collect all potential values of the one stored by \p SI into
362/// \p PotentialCopies. That is, the only copies that were made via the
363/// store are assumed to be known and all are in \p PotentialCopies. Dependences
364/// onto \p QueryingAA are properly tracked, \p UsedAssumedInformation will
365/// inform the caller if assumed information was used.
366///
367/// \returns True if the assumed potential copies are all in \p PotentialCopies,
368/// false if something went wrong and the copies could not be
369/// determined.
372 const AbstractAttribute &QueryingAA, bool &UsedAssumedInformation,
373 bool OnlyExact = false);
374
375/// Return true if \p IRP is readonly. This will query respective AAs that
376/// deduce the information and introduce dependences for \p QueryingAA.
378 const AbstractAttribute &QueryingAA,
379 bool &IsKnown);
380
381/// Return true if \p IRP is readnone. This will query respective AAs that
382/// deduce the information and introduce dependences for \p QueryingAA.
384 const AbstractAttribute &QueryingAA,
385 bool &IsKnown);
386
387/// Return true if \p ToI is potentially reachable from \p FromI without running
388/// into any instruction in \p ExclusionSet The two instructions do not need to
389/// be in the same function. \p GoBackwardsCB can be provided to convey domain
390/// knowledge about the "lifespan" the user is interested in. By default, the
391/// callers of \p FromI are checked as well to determine if \p ToI can be
392/// reached. If the query is not interested in callers beyond a certain point,
393/// e.g., a GPU kernel entry or the function containing an alloca, the
394/// \p GoBackwardsCB should return false.
396 Attributor &A, const Instruction &FromI, const Instruction &ToI,
397 const AbstractAttribute &QueryingAA,
398 const AA::InstExclusionSetTy *ExclusionSet = nullptr,
399 std::function<bool(const Function &F)> GoBackwardsCB = nullptr);
400
401/// Same as above but it is sufficient to reach any instruction in \p ToFn.
403 Attributor &A, const Instruction &FromI, const Function &ToFn,
404 const AbstractAttribute &QueryingAA,
405 const AA::InstExclusionSetTy *ExclusionSet = nullptr,
406 std::function<bool(const Function &F)> GoBackwardsCB = nullptr);
407
408/// Return true if \p Obj is assumed to be a thread local object.
410 const AbstractAttribute &QueryingAA);
411
412/// Return true if \p I is potentially affected by a barrier.
413LLVM_ABI bool
415 const AbstractAttribute &QueryingAA);
416LLVM_ABI bool
418 const AbstractAttribute &QueryingAA,
419 const Instruction *CtxI);
420} // namespace AA
421
422template <>
423struct DenseMapInfo<AA::ValueAndContext>
424 : public DenseMapInfo<AA::ValueAndContext::Base> {
426 static unsigned getHashValue(const AA::ValueAndContext &VAC) {
427 return Base::getHashValue(VAC);
428 }
429
430 static bool isEqual(const AA::ValueAndContext &LHS,
431 const AA::ValueAndContext &RHS) {
432 return Base::isEqual(LHS, RHS);
433 }
434};
435
436template <>
437struct DenseMapInfo<AA::ValueScope> : public DenseMapInfo<unsigned char> {
439 static unsigned getHashValue(const AA::ValueScope &S) {
440 return Base::getHashValue(S);
441 }
442
443 static bool isEqual(const AA::ValueScope &LHS, const AA::ValueScope &RHS) {
444 return Base::isEqual(LHS, RHS);
445 }
446};
447
448template <>
449struct DenseMapInfo<const AA::InstExclusionSetTy *>
450 : public DenseMapInfo<void *> {
451 static unsigned getHashValue(const AA::InstExclusionSetTy *BES) {
452 unsigned H = 0;
453 if (BES)
454 for (const auto *II : *BES)
455 H += DenseMapInfo<const Instruction *>::getHashValue(II);
456 return H;
457 }
458 static bool isEqual(const AA::InstExclusionSetTy *LHS,
460 if (LHS == RHS)
461 return true;
462 auto SizeLHS = LHS ? LHS->size() : 0;
463 auto SizeRHS = RHS ? RHS->size() : 0;
464 if (SizeLHS != SizeRHS)
465 return false;
466 if (SizeRHS == 0)
467 return true;
468 return llvm::set_is_subset(*LHS, *RHS);
469 }
470};
471
472/// The value passed to the line option that defines the maximal initialization
473/// chain length.
475
476///{
481
486
487enum class DepClassTy {
488 REQUIRED, ///< The target cannot be valid if the source is not.
489 OPTIONAL, ///< The target may be valid if the source is not.
490 NONE, ///< Do not track a dependence between source and target.
491};
492///}
493
494/// The data structure for the nodes of a dependency graph
496public:
497 virtual ~AADepGraphNode() = default;
500
501protected:
502 /// Set of dependency graph nodes which should be updated if this one
503 /// is updated. The bit encodes if it is optional.
505
506 static AADepGraphNode *DepGetVal(const DepTy &DT) { return DT.getPointer(); }
509 }
510
511 operator AbstractAttribute *() { return cast<AbstractAttribute>(this); }
512
513public:
517
518 aaiterator begin() { return aaiterator(Deps.begin(), &DepGetValAA); }
519 aaiterator end() { return aaiterator(Deps.end(), &DepGetValAA); }
520 iterator child_begin() { return iterator(Deps.begin(), &DepGetVal); }
521 iterator child_end() { return iterator(Deps.end(), &DepGetVal); }
522
523 void print(raw_ostream &OS) const { print(nullptr, OS); }
524 virtual void print(Attributor *, raw_ostream &OS) const {
525 OS << "AADepNode Impl\n";
526 }
527
528 friend struct Attributor;
529 friend struct AADepGraph;
530};
531
532/// The data structure for the dependency graph
533///
534/// Note that in this graph if there is an edge from A to B (A -> B),
535/// then it means that B depends on A, and when the state of A is
536/// updated, node B should also be updated
538 AADepGraph() = default;
539 ~AADepGraph() = default;
540
542 static AADepGraphNode *DepGetVal(const DepTy &DT) { return DT.getPointer(); }
543 using iterator =
545
546 /// There is no root node for the dependency graph. But the SCCIterator
547 /// requires a single entry point, so we maintain a fake("synthetic") root
548 /// node that depends on every node.
551
552 iterator begin() { return SyntheticRoot.child_begin(); }
553 iterator end() { return SyntheticRoot.child_end(); }
554
555 LLVM_ABI void viewGraph();
556
557 /// Dump graph to file
558 LLVM_ABI void dumpGraph();
559
560 /// Print dependency graph
561 LLVM_ABI void print();
562};
563
564/// Helper to describe and deal with positions in the LLVM-IR.
565///
566/// A position in the IR is described by an anchor value and an "offset" that
567/// could be the argument number, for call sites and arguments, or an indicator
568/// of the "position kind". The kinds, specified in the Kind enum below, include
569/// the locations in the attribute list, i.a., function scope and return value,
570/// as well as a distinction between call sites and functions. Finally, there
571/// are floating values that do not have a corresponding attribute list
572/// position.
574 // NOTE: In the future this definition can be changed to support recursive
575 // functions.
577
578 /// The positions we distinguish in the IR.
579 enum Kind : char {
580 IRP_INVALID, ///< An invalid position.
581 IRP_FLOAT, ///< A position that is not associated with a spot suitable
582 ///< for attributes. This could be any value or instruction.
583 IRP_RETURNED, ///< An attribute for the function return value.
584 IRP_CALL_SITE_RETURNED, ///< An attribute for a call site return value.
585 IRP_FUNCTION, ///< An attribute for a function (scope).
586 IRP_CALL_SITE, ///< An attribute for a call site (function scope).
587 IRP_ARGUMENT, ///< An attribute for a function argument.
588 IRP_CALL_SITE_ARGUMENT, ///< An attribute for a call site argument.
589 };
590
591 /// Default constructor available to create invalid positions implicitly. All
592 /// other positions need to be created explicitly through the appropriate
593 /// static member function.
594 IRPosition() : Enc(nullptr, ENC_VALUE) { verify(); }
595
596 /// Create a position describing the value of \p V.
597 static const IRPosition value(const Value &V,
598 const CallBaseContext *CBContext = nullptr) {
599 if (auto *Arg = dyn_cast<Argument>(&V))
600 return IRPosition::argument(*Arg, CBContext);
601 if (auto *CB = dyn_cast<CallBase>(&V))
603 return IRPosition(const_cast<Value &>(V), IRP_FLOAT, CBContext);
604 }
605
606 /// Create a position describing the instruction \p I. This is different from
607 /// the value version because call sites are treated as intrusctions rather
608 /// than their return value in this function.
609 static const IRPosition inst(const Instruction &I,
610 const CallBaseContext *CBContext = nullptr) {
611 return IRPosition(const_cast<Instruction &>(I), IRP_FLOAT, CBContext);
612 }
613
614 /// Create a position describing the function scope of \p F.
615 /// \p CBContext is used for call base specific analysis.
616 static const IRPosition function(const Function &F,
617 const CallBaseContext *CBContext = nullptr) {
618 return IRPosition(const_cast<Function &>(F), IRP_FUNCTION, CBContext);
619 }
620
621 /// Create a position describing the returned value of \p F.
622 /// \p CBContext is used for call base specific analysis.
623 static const IRPosition returned(const Function &F,
624 const CallBaseContext *CBContext = nullptr) {
625 return IRPosition(const_cast<Function &>(F), IRP_RETURNED, CBContext);
626 }
627
628 /// Create a position describing the argument \p Arg.
629 /// \p CBContext is used for call base specific analysis.
630 static const IRPosition argument(const Argument &Arg,
631 const CallBaseContext *CBContext = nullptr) {
632 return IRPosition(const_cast<Argument &>(Arg), IRP_ARGUMENT, CBContext);
633 }
634
635 /// Create a position describing the function scope of \p CB.
636 static const IRPosition callsite_function(const CallBase &CB) {
637 return IRPosition(const_cast<CallBase &>(CB), IRP_CALL_SITE);
638 }
639
640 /// Create a position describing the returned value of \p CB.
641 static const IRPosition callsite_returned(const CallBase &CB) {
642 return IRPosition(const_cast<CallBase &>(CB), IRP_CALL_SITE_RETURNED);
643 }
644
645 /// Create a position describing the argument of \p CB at position \p ArgNo.
646 static const IRPosition callsite_argument(const CallBase &CB,
647 unsigned ArgNo) {
648 return IRPosition(const_cast<Use &>(CB.getArgOperandUse(ArgNo)),
650 }
651
652 /// Create a position describing the argument of \p ACS at position \p ArgNo.
654 unsigned ArgNo) {
655 if (ACS.getNumArgOperands() <= ArgNo)
656 return IRPosition();
657 int CSArgNo = ACS.getCallArgOperandNo(ArgNo);
658 if (CSArgNo >= 0)
660 cast<CallBase>(*ACS.getInstruction()), CSArgNo);
661 return IRPosition();
662 }
663
664 /// Create a position with function scope matching the "context" of \p IRP.
665 /// If \p IRP is a call site (see isAnyCallSitePosition()) then the result
666 /// will be a call site position, otherwise the function position of the
667 /// associated function.
668 static const IRPosition
670 const CallBaseContext *CBContext = nullptr) {
671 if (IRP.isAnyCallSitePosition()) {
674 }
676 return IRPosition::function(*IRP.getAssociatedFunction(), CBContext);
677 }
678
679 bool operator==(const IRPosition &RHS) const {
680 return Enc == RHS.Enc && RHS.CBContext == CBContext;
681 }
682 bool operator!=(const IRPosition &RHS) const { return !(*this == RHS); }
683
684 /// Return the value this abstract attribute is anchored with.
685 ///
686 /// The anchor value might not be the associated value if the latter is not
687 /// sufficient to determine where arguments will be manifested. This is, so
688 /// far, only the case for call site arguments as the value is not sufficient
689 /// to pinpoint them. Instead, we can use the call site as an anchor.
691 switch (getEncodingBits()) {
692 case ENC_VALUE:
693 case ENC_RETURNED_VALUE:
694 case ENC_FLOATING_FUNCTION:
695 return *getAsValuePtr();
696 case ENC_CALL_SITE_ARGUMENT_USE:
697 return *(getAsUsePtr()->getUser());
698 default:
699 llvm_unreachable("Unkown encoding!");
700 };
701 }
702
703 /// Return the associated function, if any.
705 if (auto *CB = dyn_cast<CallBase>(&getAnchorValue())) {
706 // We reuse the logic that associates callback calles to arguments of a
707 // call site here to identify the callback callee as the associated
708 // function.
709 if (Argument *Arg = getAssociatedArgument())
710 return Arg->getParent();
712 CB->getCalledOperand()->stripPointerCasts());
713 }
714 return getAnchorScope();
715 }
716
717 /// Return the associated argument, if any.
719
720 /// Return true if the position refers to a function interface, that is the
721 /// function scope, the function return, or an argument.
722 bool isFnInterfaceKind() const {
723 switch (getPositionKind()) {
727 return true;
728 default:
729 return false;
730 }
731 }
732
733 /// Return true if this is a function or call site position.
734 bool isFunctionScope() const {
735 switch (getPositionKind()) {
738 return true;
739 default:
740 return false;
741 };
742 }
743
744 /// Return the Function surrounding the anchor value.
747 if (isa<Function>(V))
748 return &cast<Function>(V);
749 if (isa<Argument>(V))
750 return cast<Argument>(V).getParent();
751 if (isa<Instruction>(V))
752 return cast<Instruction>(V).getFunction();
753 return nullptr;
754 }
755
756 /// Return the context instruction, if any.
759 if (auto *I = dyn_cast<Instruction>(&V))
760 return I;
761 if (auto *Arg = dyn_cast<Argument>(&V))
762 if (!Arg->getParent()->isDeclaration())
763 return &Arg->getParent()->getEntryBlock().front();
764 if (auto *F = dyn_cast<Function>(&V))
765 if (!F->isDeclaration())
766 return &(F->getEntryBlock().front());
767 return nullptr;
768 }
769
770 /// Return the value this abstract attribute is associated with.
772 // A call site argument position is encoded by the argument operand use.
773 if (getEncodingBits() == ENC_CALL_SITE_ARGUMENT_USE)
774 return *getAsUsePtr()->get();
775 return getAnchorValue();
776 }
777
778 /// Return the type this abstract attribute is associated with.
784
785 /// Return the callee argument number of the associated value if it is an
786 /// argument or call site argument, otherwise a negative value. In contrast to
787 /// `getCallSiteArgNo` this method will always return the "argument number"
788 /// from the perspective of the callee. This may not the same as the call site
789 /// if this is a callback call.
790 int getCalleeArgNo() const {
791 return getArgNo(/* CallbackCalleeArgIfApplicable */ true);
792 }
793
794 /// Return the call site argument number of the associated value if it is an
795 /// argument or call site argument, otherwise a negative value. In contrast to
796 /// `getCalleArgNo` this method will always return the "operand number" from
797 /// the perspective of the call site. This may not the same as the callee
798 /// perspective if this is a callback call.
799 int getCallSiteArgNo() const {
800 return getArgNo(/* CallbackCalleeArgIfApplicable */ false);
801 }
802
803 /// Return the index in the attribute list for this position.
804 unsigned getAttrIdx() const {
805 switch (getPositionKind()) {
808 break;
811 return AttributeList::FunctionIndex;
814 return AttributeList::ReturnIndex;
816 return getCalleeArgNo() + AttributeList::FirstArgIndex;
818 return getCallSiteArgNo() + AttributeList::FirstArgIndex;
819 }
821 "There is no attribute index for a floating or invalid position!");
822 }
823
824 /// Return the value attributes are attached to.
826 if (auto *CB = dyn_cast<CallBase>(&getAnchorValue()))
827 return CB;
828 return getAssociatedFunction();
829 }
830
831 /// Return the attributes associated with this function or call site scope.
833 if (auto *CB = dyn_cast<CallBase>(&getAnchorValue()))
834 return CB->getAttributes();
836 }
837
838 /// Update the attributes associated with this function or call site scope.
839 void setAttrList(const AttributeList &AttrList) const {
840 if (auto *CB = dyn_cast<CallBase>(&getAnchorValue()))
841 return CB->setAttributes(AttrList);
842 return getAssociatedFunction()->setAttributes(AttrList);
843 }
844
845 /// Return the associated position kind.
847 char EncodingBits = getEncodingBits();
848 if (EncodingBits == ENC_CALL_SITE_ARGUMENT_USE)
850 if (EncodingBits == ENC_FLOATING_FUNCTION)
851 return IRP_FLOAT;
852
853 Value *V = getAsValuePtr();
854 if (!V)
855 return IRP_INVALID;
856 if (isa<Argument>(V))
857 return IRP_ARGUMENT;
858 if (isa<Function>(V))
859 return isReturnPosition(EncodingBits) ? IRP_RETURNED : IRP_FUNCTION;
860 if (isa<CallBase>(V))
861 return isReturnPosition(EncodingBits) ? IRP_CALL_SITE_RETURNED
863 return IRP_FLOAT;
864 }
865
867 switch (getPositionKind()) {
871 return true;
872 default:
873 return false;
874 }
875 }
876
877 /// Return true if the position is an argument or call site argument.
878 bool isArgumentPosition() const {
879 switch (getPositionKind()) {
882 return true;
883 default:
884 return false;
885 }
886 }
887
888 /// Return the same position without the call base context.
890 IRPosition Result = *this;
891 Result.CBContext = nullptr;
892 return Result;
893 }
894
895 /// Get the call base context from the position.
896 const CallBaseContext *getCallBaseContext() const { return CBContext; }
897
898 /// Check if the position has any call base context.
899 bool hasCallBaseContext() const { return CBContext != nullptr; }
900
901 /// Conversion into a void * to allow reuse of pointer hashing.
902 operator void *() const { return Enc.getOpaqueValue(); }
903
904private:
905 /// Private constructor for special values only!
906 explicit IRPosition(void *Ptr, const CallBaseContext *CBContext = nullptr)
907 : CBContext(CBContext) {
908 Enc.setFromOpaqueValue(Ptr);
909 }
910
911 /// IRPosition anchored at \p AnchorVal with kind/argument numbet \p PK.
912 explicit IRPosition(Value &AnchorVal, Kind PK,
913 const CallBaseContext *CBContext = nullptr)
914 : CBContext(CBContext) {
915 switch (PK) {
917 llvm_unreachable("Cannot create invalid IRP with an anchor value!");
918 break;
920 // Special case for floating functions.
921 if (isa<Function>(AnchorVal) || isa<CallBase>(AnchorVal))
922 Enc = {&AnchorVal, ENC_FLOATING_FUNCTION};
923 else
924 Enc = {&AnchorVal, ENC_VALUE};
925 break;
928 Enc = {&AnchorVal, ENC_VALUE};
929 break;
932 Enc = {&AnchorVal, ENC_RETURNED_VALUE};
933 break;
935 Enc = {&AnchorVal, ENC_VALUE};
936 break;
939 "Cannot create call site argument IRP with an anchor value!");
940 break;
941 }
942 verify();
943 }
944
945 /// Return the callee argument number of the associated value if it is an
946 /// argument or call site argument. See also `getCalleeArgNo` and
947 /// `getCallSiteArgNo`.
948 int getArgNo(bool CallbackCalleeArgIfApplicable) const {
949 switch (getPositionKind()) {
951 return cast<Argument>(getAsValuePtr())->getArgNo();
953 // Only call site arguments can be associated with a callback callee
954 // argument.
955 if (CallbackCalleeArgIfApplicable) {
956 if (Argument *Arg = getAssociatedArgument())
957 return Arg->getArgNo();
958 }
959 Use &U = *getAsUsePtr();
960 return cast<CallBase>(U.getUser())->getArgOperandNo(&U);
961 }
962 default:
963 return -1;
964 }
965 }
966
967 /// IRPosition for the use \p U. The position kind \p PK needs to be
968 /// IRP_CALL_SITE_ARGUMENT, the anchor value is the user, the associated value
969 /// the used value.
970 explicit IRPosition(Use &U, Kind PK) {
972 "Use constructor is for call site arguments only!");
973 Enc = {&U, ENC_CALL_SITE_ARGUMENT_USE};
974 verify();
975 }
976
977 /// Verify internal invariants.
978#ifdef EXPENSIVE_CHECKS
979 LLVM_ABI void verify();
980#else
981 void verify() {}
982#endif
983
984 /// Return the underlying pointer as Value *, valid for all positions but
985 /// IRP_CALL_SITE_ARGUMENT.
986 Value *getAsValuePtr() const {
987 assert(getEncodingBits() != ENC_CALL_SITE_ARGUMENT_USE &&
988 "Not a value pointer!");
989 return reinterpret_cast<Value *>(Enc.getPointer());
990 }
991
992 /// Return the underlying pointer as Use *, valid only for
993 /// IRP_CALL_SITE_ARGUMENT positions.
994 Use *getAsUsePtr() const {
995 assert(getEncodingBits() == ENC_CALL_SITE_ARGUMENT_USE &&
996 "Not a value pointer!");
997 return reinterpret_cast<Use *>(Enc.getPointer());
998 }
999
1000 /// Return true if \p EncodingBits describe a returned or call site returned
1001 /// position.
1002 static bool isReturnPosition(char EncodingBits) {
1003 return EncodingBits == ENC_RETURNED_VALUE;
1004 }
1005
1006 /// The encoding of the IRPosition is a combination of a pointer and two
1007 /// encoding bits. The values of the encoding bits are defined in the enum
1008 /// below. The pointer is either a Value* (for the first three encoding bit
1009 /// combinations) or Use* (for ENC_CALL_SITE_ARGUMENT_USE).
1010 ///
1011 ///{
1012 enum {
1013 ENC_VALUE = 0b00,
1014 ENC_RETURNED_VALUE = 0b01,
1015 ENC_FLOATING_FUNCTION = 0b10,
1016 ENC_CALL_SITE_ARGUMENT_USE = 0b11,
1017 };
1018
1019 // Reserve the maximal amount of bits so there is no need to mask out the
1020 // remaining ones. We will not encode anything else in the pointer anyway.
1021 static constexpr int NumEncodingBits =
1023 static_assert(NumEncodingBits >= 2, "At least two bits are required!");
1024
1025 /// The pointer with the encoding bits.
1026 PointerIntPair<void *, NumEncodingBits, char> Enc;
1027 ///}
1028
1029 /// Call base context. Used for callsite specific analysis.
1030 const CallBaseContext *CBContext = nullptr;
1031
1032 /// Return the encoding bits.
1033 char getEncodingBits() const { return Enc.getInt(); }
1034};
1035
1036/// Helper that allows IRPosition as a key in a DenseMap.
1037template <> struct DenseMapInfo<IRPosition> {
1038 static unsigned getHashValue(const IRPosition &IRP) {
1039 return (DenseMapInfo<void *>::getHashValue(IRP) << 4) ^
1041 }
1042
1043 static bool isEqual(const IRPosition &a, const IRPosition &b) {
1044 return a == b;
1045 }
1046};
1047
1048/// A visitor class for IR positions.
1049///
1050/// Given a position P, the SubsumingPositionIterator allows to visit "subsuming
1051/// positions" wrt. attributes/information. Thus, if a piece of information
1052/// holds for a subsuming position, it also holds for the position P.
1053///
1054/// The subsuming positions always include the initial position and then,
1055/// depending on the position kind, additionally the following ones:
1056/// - for IRP_RETURNED:
1057/// - the function (IRP_FUNCTION)
1058/// - for IRP_ARGUMENT:
1059/// - the function (IRP_FUNCTION)
1060/// - for IRP_CALL_SITE:
1061/// - the callee (IRP_FUNCTION), if known
1062/// - for IRP_CALL_SITE_RETURNED:
1063/// - the callee (IRP_RETURNED), if known
1064/// - the call site (IRP_FUNCTION)
1065/// - the callee (IRP_FUNCTION), if known
1066/// - for IRP_CALL_SITE_ARGUMENT:
1067/// - the argument of the callee (IRP_ARGUMENT), if known
1068/// - the callee (IRP_FUNCTION), if known
1069/// - the position the call site argument is associated with if it is not
1070/// anchored to the call site, e.g., if it is an argument then the argument
1071/// (IRP_ARGUMENT)
1073 SmallVector<IRPosition, 4> IRPositions;
1074 using iterator = decltype(IRPositions)::iterator;
1075
1076public:
1078 iterator begin() { return IRPositions.begin(); }
1079 iterator end() { return IRPositions.end(); }
1080};
1081
1082/// Wrapper for FunctionAnalysisManager.
1084 // The client may be running the old pass manager, in which case, we need to
1085 // map the requested Analysis to its equivalent wrapper in the old pass
1086 // manager. The scheme implemented here does not require every Analysis to be
1087 // updated. Only those new analyses that the client cares about in the old
1088 // pass manager need to expose a LegacyWrapper type, and that wrapper should
1089 // support a getResult() method that matches the new Analysis.
1090 //
1091 // We need SFINAE to check for the LegacyWrapper, but function templates don't
1092 // allow partial specialization, which is needed in this case. So instead, we
1093 // use a constexpr bool to perform the SFINAE, and then use this information
1094 // inside the function template.
1095 template <typename, typename = void>
1096 static constexpr bool HasLegacyWrapper = false;
1097
1098 template <typename Analysis>
1099 typename Analysis::Result *getAnalysis(const Function &F,
1100 bool RequestCachedOnly = false) {
1101 if (!LegacyPass && !FAM)
1102 return nullptr;
1103 if (FAM) {
1104 if (CachedOnly || RequestCachedOnly)
1105 return FAM->getCachedResult<Analysis>(const_cast<Function &>(F));
1106 return &FAM->getResult<Analysis>(const_cast<Function &>(F));
1107 }
1108 if constexpr (HasLegacyWrapper<Analysis>) {
1109 if (!CachedOnly && !RequestCachedOnly)
1110 return &LegacyPass
1111 ->getAnalysis<typename Analysis::LegacyWrapper>(
1112 const_cast<Function &>(F))
1113 .getResult();
1114 if (auto *P =
1115 LegacyPass
1116 ->getAnalysisIfAvailable<typename Analysis::LegacyWrapper>())
1117 return &P->getResult();
1118 }
1119 return nullptr;
1120 }
1121
1122 /// Invalidates the analyses. Valid only when using the new pass manager.
1124 assert(FAM && "Can only be used from the new PM!");
1125 FAM->clear();
1126 }
1127
1128 AnalysisGetter(FunctionAnalysisManager &FAM, bool CachedOnly = false)
1129 : FAM(&FAM), CachedOnly(CachedOnly) {}
1130 AnalysisGetter(Pass *P, bool CachedOnly = false)
1131 : LegacyPass(P), CachedOnly(CachedOnly) {}
1132 AnalysisGetter() = default;
1133
1134private:
1135 FunctionAnalysisManager *FAM = nullptr;
1136 Pass *LegacyPass = nullptr;
1137
1138 /// If \p CachedOnly is true, no pass is created, just existing results are
1139 /// used. Also available per request.
1140 bool CachedOnly = false;
1141};
1142
1143template <typename Analysis>
1145 Analysis, std::void_t<typename Analysis::LegacyWrapper>> = true;
1146
1147/// Data structure to hold cached (LLVM-IR) information.
1148///
1149/// All attributes are given an InformationCache object at creation time to
1150/// avoid inspection of the IR by all of them individually. This default
1151/// InformationCache will hold information required by 'default' attributes,
1152/// thus the ones deduced when Attributor::identifyDefaultAbstractAttributes(..)
1153/// is called.
1154///
1155/// If custom abstract attributes, registered manually through
1156/// Attributor::registerAA(...), need more information, especially if it is not
1157/// reusable, it is advised to inherit from the InformationCache and cast the
1158/// instance down in the abstract attributes.
1162 bool UseExplorer = true)
1163 : CGSCC(CGSCC), M(M), Allocator(Allocator), AG(AG) {
1164 if (UseExplorer)
1165 Explorer = new (Allocator) MustBeExecutedContextExplorer(
1166 /* ExploreInterBlock */
1167 true, /* ExploreCFGForward */ true,
1168 /* ExploreCFGBackward */ true,
1169 /* LIGetter */
1170 [&](const Function &F) { return AG.getAnalysis<LoopAnalysis>(F); },
1171 /* DTGetter */
1172 [&](const Function &F) {
1173 return AG.getAnalysis<DominatorTreeAnalysis>(F);
1174 },
1175 /* PDTGetter */
1176 [&](const Function &F) {
1177 return AG.getAnalysis<PostDominatorTreeAnalysis>(F);
1178 });
1179 }
1180
1182 // The FunctionInfo objects are allocated via a BumpPtrAllocator, we call
1183 // the destructor manually.
1184 for (auto &It : FuncInfoMap)
1185 It.getSecond()->~FunctionInfo();
1186 // Same is true for the instruction exclusions sets.
1188 for (auto *BES : BESets)
1189 BES->~InstExclusionSetTy();
1190 if (Explorer)
1191 Explorer->~MustBeExecutedContextExplorer();
1192 }
1193
1194 /// Apply \p CB to all uses of \p F. If \p LookThroughConstantExprUses is
1195 /// true, constant expression users are not given to \p CB but their uses are
1196 /// traversed transitively.
1197 template <typename CBTy>
1198 static void foreachUse(Function &F, CBTy CB,
1199 bool LookThroughConstantExprUses = true) {
1200 SmallVector<Use *, 8> Worklist(make_pointer_range(F.uses()));
1201
1202 for (unsigned Idx = 0; Idx < Worklist.size(); ++Idx) {
1203 Use &U = *Worklist[Idx];
1204
1205 // Allow use in constant bitcasts and simply look through them.
1206 if (LookThroughConstantExprUses && isa<ConstantExpr>(U.getUser())) {
1207 for (Use &CEU : cast<ConstantExpr>(U.getUser())->uses())
1208 Worklist.push_back(&CEU);
1209 continue;
1210 }
1211
1212 CB(U);
1213 }
1214 }
1215
1216 /// The CG-SCC the pass is run on, or nullptr if it is a module pass.
1217 const SetVector<Function *> *const CGSCC = nullptr;
1218
1219 /// A vector type to hold instructions.
1221
1222 /// A map type from opcodes to instructions with this opcode.
1224 std::array<InstructionVectorTy *, Instruction::OtherOpsEnd>;
1225
1226 /// Return the map that relates "interesting" opcodes with all instructions
1227 /// with that opcode in \p F.
1229 return getFunctionInfo(F).OpcodeInstMap;
1230 }
1231
1232 /// Return the instructions in \p F that may read or write memory.
1234 return getFunctionInfo(F).RWInsts;
1235 }
1236
1237 /// Return MustBeExecutedContextExplorer
1241
1242 /// Return TargetLibraryInfo for function \p F.
1246
1247 /// Return true if \p F has the "kernel" function attribute
1248 bool isKernel(const Function &F) {
1249 FunctionInfo &FI = getFunctionInfo(F);
1250 return FI.IsKernel;
1251 }
1252
1253 /// Return true if \p Arg is involved in a must-tail call, thus the argument
1254 /// of the caller or callee.
1256 FunctionInfo &FI = getFunctionInfo(*Arg.getParent());
1257 return FI.CalledViaMustTail || FI.ContainsMustTailCall;
1258 }
1259
1261 const Function &F = *I.getFunction();
1262 FunctionInfo &FI = getFunctionInfo(F);
1263 if (!FI.AssumeOnlyValuesCollected)
1264 collectAssumeOnlyValues(FI);
1265 return AssumeOnlyValues.contains(&I);
1266 }
1267
1268 /// Invalidates the cached analyses. Valid only when using the new pass
1269 /// manager.
1270 void invalidateAnalyses() { AG.invalidateAnalyses(); }
1271
1272 /// Return the analysis result from a pass \p AP for function \p F.
1273 template <typename AP>
1274 typename AP::Result *getAnalysisResultForFunction(const Function &F,
1275 bool CachedOnly = false) {
1276 return AG.getAnalysis<AP>(F, CachedOnly);
1277 }
1278
1279 const Module &getModule() const { return M; }
1280
1281 /// Return datalayout used in the module.
1282 const DataLayout &getDL() const { return M.getDataLayout(); }
1283
1284 /// Return the map conaining all the knowledge we have from `llvm.assume`s.
1285 const RetainedKnowledgeMap &getKnowledgeMap() const { return KnowledgeMap; }
1286
1287 /// Given \p BES, return a uniqued version.
1290 auto It = BESets.find(BES);
1291 if (It != BESets.end())
1292 return *It;
1293 auto *UniqueBES = new (Allocator) AA::InstExclusionSetTy(*BES);
1294 bool Success = BESets.insert(UniqueBES).second;
1295 (void)Success;
1296 assert(Success && "Expected only new entries to be added");
1297 return UniqueBES;
1298 }
1299
1300 /// Return true if the stack (llvm::Alloca) can be accessed by other threads.
1302
1303 /// Return true if the target is a GPU.
1304 bool IsTargetGPU() const { return M.getTargetTriple().isGPU(); }
1305
1306 /// Return all functions that might be called indirectly, only valid for
1307 /// closed world modules (see isClosedWorldModule).
1310
1311 /// Return true if \p F has an exact definition or is inlineable.
1312 ///
1313 /// This is computed once when the information of \p F is initialized. For
1314 /// functions that are not initialized yet, only the definition is checked,
1315 /// as InlineableFunctions is also only filled on initialization.
1316 bool isExactOrInlineable(const Function &F) const {
1317 if (const FunctionInfo *FI = FuncInfoMap.lookup(&F))
1318 return FI->IsExactOrInlineable;
1319 return F.hasExactDefinition();
1320 }
1321
1322 /// Return the flat address space if the associated target has.
1323 LLVM_ABI std::optional<unsigned> getFlatAddressSpace() const;
1324
1325 virtual unsigned getMaxAddrSpace() const { return ~0U; }
1326
1327private:
1328 struct FunctionInfo {
1329 LLVM_ABI ~FunctionInfo();
1330
1331 /// Whether the function has an exact definition or is inlineable.
1332 bool IsExactOrInlineable = false;
1333
1334 /// A nested map that remembers all instructions in a function with a
1335 /// certain instruction opcode (Instruction::getOpcode()).
1336 OpcodeInstMapTy OpcodeInstMap = {};
1337
1338 /// A map from functions to their instructions that may read or write
1339 /// memory.
1340 InstructionVectorTy RWInsts;
1341
1342 /// Function is called by a `musttail` call.
1343 bool CalledViaMustTail;
1344
1345 /// Function contains a `musttail` call.
1346 bool ContainsMustTailCall;
1347
1348 /// Function has the `"kernel"` attribute
1349 bool IsKernel;
1350
1351 /// The values only used by `llvm.assume`s in the function have been added
1352 /// to AssumeOnlyValues.
1353 bool AssumeOnlyValuesCollected = false;
1354 };
1355
1356 /// A map type from functions to informatio about it.
1357 DenseMap<const Function *, FunctionInfo *> FuncInfoMap;
1358
1359 /// Return information about the function \p F, potentially by creating it.
1360 FunctionInfo &getFunctionInfo(const Function &F) {
1361 auto [It, Inserted] = FuncInfoMap.try_emplace(&F);
1362 if (!Inserted)
1363 return *It->second;
1364
1365 // Initialization can grow the map, so don't keep a reference into it.
1366 FunctionInfo *FI = new (Allocator) FunctionInfo();
1367 It->second = FI;
1368 initializeInformationCache(F, *FI);
1369 return *FI;
1370 }
1371
1372 /// Vector of functions that might be callable indirectly, i.a., via a
1373 /// function pointer.
1374 SmallVector<Function *> IndirectlyCallableFunctions;
1375
1376 /// Add the values only used by `llvm.assume`s in the function of \p FI to
1377 /// AssumeOnlyValues. This is done on demand, as few users need them.
1378 LLVM_ABI void collectAssumeOnlyValues(FunctionInfo &FI);
1379
1380 /// Initialize the function information cache \p FI for the function \p F.
1381 ///
1382 /// This method needs to be called for all function that might be looked at
1383 /// through the information cache interface *prior* to looking at them.
1384 LLVM_ABI void initializeInformationCache(const Function &F, FunctionInfo &FI);
1385
1386 /// The module.
1387 const Module &M;
1388
1389 /// The allocator used to allocate memory, e.g. for `FunctionInfo`s.
1390 BumpPtrAllocator &Allocator;
1391
1392 /// MustBeExecutedContextExplorer
1393 MustBeExecutedContextExplorer *Explorer = nullptr;
1394
1395 /// A map with knowledge retained in `llvm.assume` instructions.
1396 RetainedKnowledgeMap KnowledgeMap;
1397
1398 /// A container for all instructions that are only used by `llvm.assume`.
1399 SetVector<const Instruction *> AssumeOnlyValues;
1400
1401 /// Cache for block sets to allow reuse.
1402 DenseSet<const AA::InstExclusionSetTy *> BESets;
1403
1404 /// Getters for analysis.
1405 AnalysisGetter &AG;
1406
1407 /// Set of inlineable functions
1408 SmallPtrSet<const Function *, 8> InlineableFunctions;
1409
1410 /// Give the Attributor access to the members so
1411 /// Attributor::identifyDefaultAbstractAttributes(...) can initialize them.
1412 friend struct Attributor;
1413};
1414
1415/// A set of kinds of abstract attributes, given by their IDs. The kinds
1416/// declared here are tested with a bit mask, others with a list of IDs.
1417class AAKindSet {
1418public:
1419 /// Return the set of the kinds with the IDs \p KindIDs.
1420 template <const char *...KindIDs> static constexpr AAKindSet get();
1421
1422 /// Return true if abstract attributes of type \p AAType are in the set.
1423 template <typename AAType> bool contains() const;
1424
1425private:
1426 constexpr AAKindSet(uint64_t Mask, ArrayRef<const char *> IDs)
1427 : Mask(Mask), IDs(IDs) {}
1428
1429 uint64_t Mask;
1431};
1432
1433/// Configuration for the Attributor.
1435
1437
1438 /// Is the user of the Attributor a module pass or not. This determines what
1439 /// IR we can look at and modify. If it is a module pass we might deduce facts
1440 /// outside the initial function set and modify functions outside that set,
1441 /// but only as part of the optimization of the functions in the initial
1442 /// function set. For CGSCC passes we can look at the IR of the module slice
1443 /// but never run any deduction, or perform any modification, outside the
1444 /// initial function set (which we assume is the SCC).
1445 bool IsModulePass = true;
1446
1447 /// Flag to determine if we can delete functions or keep dead ones around.
1448 bool DeleteFns = true;
1449
1450 /// Flag to determine if we rewrite function signatures.
1452
1453 /// Flag to determine if we want to initialize all default AAs for an internal
1454 /// function marked live. See also: InitializationCallback>
1456
1457 /// Flag to determine if we should skip all liveness checks early on.
1458 bool UseLiveness = true;
1459
1460 /// Flag to indicate if the entire world is contained in this module, that
1461 /// is, no outside functions exist.
1463
1464 /// Callback function to be invoked on internal functions marked live.
1465 std::function<void(Attributor &A, const Function &F)> InitializationCallback =
1466 nullptr;
1467
1468 /// Callback function to determine if an indirect call targets should be made
1469 /// direct call targets (with an if-cascade).
1470 std::function<bool(Attributor &A, const AbstractAttribute &AA, CallBase &CB,
1471 Function &AssumedCallee, unsigned NumAssumedCallees)>
1473
1474 /// Helper to update an underlying call graph and to delete functions.
1476
1477 /// If set, the only kinds of abstract attributes to create.
1478 std::optional<AAKindSet> Allowed;
1479
1480 /// Maximum number of iterations to run until fixpoint.
1481 std::optional<unsigned> MaxFixpointIterations;
1482
1483 /// A callback function that returns an ORE object from a Function pointer.
1484 ///{
1488 ///}
1489
1490 /// The name of the pass running the attributor, used to emit remarks.
1491 const char *PassName = nullptr;
1492
1493 using IPOAmendableCBTy = std::function<bool(const Function &F)>;
1495};
1496
1497/// Check the debug counter used to limit the number of AAs created. Returns
1498/// false if no further AA should be created.
1500
1501/// The fixpoint analysis framework that orchestrates the attribute deduction.
1502///
1503/// The Attributor provides a general abstract analysis framework (guided
1504/// fixpoint iteration) as well as helper functions for the deduction of
1505/// (LLVM-IR) attributes. However, also other code properties can be deduced,
1506/// propagated, and ultimately manifested through the Attributor framework. This
1507/// is particularly useful if these properties interact with attributes and a
1508/// co-scheduled deduction allows to improve the solution. Even if not, thus if
1509/// attributes/properties are completely isolated, they should use the
1510/// Attributor framework to reduce the number of fixpoint iteration frameworks
1511/// in the code base. Note that the Attributor design makes sure that isolated
1512/// attributes are not impacted, in any way, by others derived at the same time
1513/// if there is no cross-reasoning performed.
1514///
1515/// The public facing interface of the Attributor is kept simple and basically
1516/// allows abstract attributes to one thing, query abstract attributes
1517/// in-flight. There are two reasons to do this:
1518/// a) The optimistic state of one abstract attribute can justify an
1519/// optimistic state of another, allowing to framework to end up with an
1520/// optimistic (=best possible) fixpoint instead of one based solely on
1521/// information in the IR.
1522/// b) This avoids reimplementing various kinds of lookups, e.g., to check
1523/// for existing IR attributes, in favor of a single lookups interface
1524/// provided by an abstract attribute subclass.
1525///
1526/// NOTE: The mechanics of adding a new "concrete" abstract attribute are
1527/// described in the file comment.
1529
1530 /// Constructor
1531 ///
1532 /// \param Functions The set of functions we are deriving attributes for.
1533 /// \param InfoCache Cache to hold various information accessible for
1534 /// the abstract attributes.
1535 /// \param Configuration The Attributor configuration which determines what
1536 /// generic features to use.
1538 InformationCache &InfoCache,
1539 AttributorConfig Configuration);
1540
1542
1543 /// Run the analyses until a fixpoint is reached or enforced (timeout).
1544 ///
1545 /// The attributes registered with this Attributor can be used after as long
1546 /// as the Attributor is not destroyed (it owns the attributes now).
1547 ///
1548 /// \Returns CHANGED if the IR was changed, otherwise UNCHANGED.
1550
1551 /// Lookup an abstract attribute of type \p AAType at position \p IRP. While
1552 /// no abstract attribute is found equivalent positions are checked, see
1553 /// SubsumingPositionIterator. Thus, the returned abstract attribute
1554 /// might be anchored at a different position, e.g., the callee if \p IRP is a
1555 /// call base.
1556 ///
1557 /// This method is the only (supported) way an abstract attribute can retrieve
1558 /// information from another abstract attribute. As an example, take an
1559 /// abstract attribute that determines the memory access behavior for a
1560 /// argument (readnone, readonly, ...). It should use `getAAFor` to get the
1561 /// most optimistic information for other abstract attributes in-flight, e.g.
1562 /// the one reasoning about the "captured" state for the argument or the one
1563 /// reasoning on the memory access behavior of the function as a whole.
1564 ///
1565 /// If the DepClass enum is set to `DepClassTy::None` the dependence from
1566 /// \p QueryingAA to the return abstract attribute is not automatically
1567 /// recorded. This should only be used if the caller will record the
1568 /// dependence explicitly if necessary, thus if it the returned abstract
1569 /// attribute is used for reasoning. To record the dependences explicitly use
1570 /// the `Attributor::recordDependence` method.
1571 template <typename AAType>
1572 const AAType *getAAFor(const AbstractAttribute &QueryingAA,
1573 const IRPosition &IRP, DepClassTy DepClass) {
1574 return getOrCreateAAFor<AAType>(IRP, &QueryingAA, DepClass,
1575 /* ForceUpdate */ false);
1576 }
1577
1578 /// The version of getAAFor that allows to omit a querying abstract
1579 /// attribute. Using this after Attributor started running is restricted to
1580 /// only the Attributor itself. Initial seeding of AAs can be done via this
1581 /// function.
1582 /// NOTE: ForceUpdate is ignored in any stage other than the update stage.
1583 template <typename AAType>
1584 const AAType *getOrCreateAAFor(IRPosition IRP,
1585 const AbstractAttribute *QueryingAA,
1586 DepClassTy DepClass, bool ForceUpdate = false,
1587 bool UpdateAfterInit = true) {
1588 if (!shouldPropagateCallBaseContext(IRP))
1589 IRP = IRP.stripCallBaseContext();
1590
1591 if (AAType *AAPtr = lookupAAFor<AAType>(IRP, QueryingAA, DepClass,
1592 /* AllowInvalidState */ true)) {
1593 if (ForceUpdate && Phase == AttributorPhase::UPDATE)
1594 updateAA(*AAPtr);
1595 return AAPtr;
1596 }
1597
1598 bool ShouldUpdateAA;
1599 if (!shouldInitialize<AAType>(IRP, ShouldUpdateAA))
1600 return nullptr;
1601
1603 return nullptr;
1604
1605 // No matching attribute found, create one.
1606 // Use the static create method.
1607 auto &AA = AAType::createForPosition(IRP, *this);
1608
1609 // Always register a new attribute to make sure we clean up the allocated
1610 // memory properly.
1611 registerAA(AA);
1612
1613 // If we are currenty seeding attributes, enforce seeding rules.
1614 if (Phase == AttributorPhase::SEEDING && !shouldSeedAttribute(AA)) {
1615 AA.getState().indicatePessimisticFixpoint();
1616 return &AA;
1617 }
1618
1619 // Bootstrap the new attribute with an initial update to propagate
1620 // information, e.g., function -> call site.
1621 {
1622 std::optional<TimeTraceScope> TimeScope;
1623 if (TimeTraceEnabled) {
1624 TimeScope.emplace("initialize", [&]() {
1625 return AA.getName().str() +
1626 std::to_string(AA.getIRPosition().getPositionKind());
1627 });
1628 }
1629
1630 ++InitializationChainLength;
1631 AA.initialize(*this);
1632 --InitializationChainLength;
1633 }
1634
1635 if (!ShouldUpdateAA) {
1636 AA.getState().indicatePessimisticFixpoint();
1637 return &AA;
1638 }
1639
1640 // Allow seeded attributes to declare dependencies.
1641 // Remember the seeding state.
1642 if (UpdateAfterInit) {
1643 AttributorPhase OldPhase = Phase;
1644 Phase = AttributorPhase::UPDATE;
1645
1646 updateAA(AA);
1647
1648 Phase = OldPhase;
1649 }
1650
1651 if (QueryingAA && AA.getState().isValidState())
1652 recordDependence(AA, const_cast<AbstractAttribute &>(*QueryingAA),
1653 DepClass);
1654 return &AA;
1655 }
1656
1657 template <typename AAType>
1658 const AAType *getOrCreateAAFor(const IRPosition &IRP) {
1659 return getOrCreateAAFor<AAType>(IRP, /* QueryingAA */ nullptr,
1661 }
1662
1663 /// Return the attribute of \p AAType for \p IRP if existing and valid. This
1664 /// also allows non-AA users lookup.
1665 template <typename AAType>
1666 AAType *lookupAAFor(const IRPosition &IRP,
1667 const AbstractAttribute *QueryingAA = nullptr,
1669 bool AllowInvalidState = false) {
1670 static_assert(std::is_base_of<AbstractAttribute, AAType>::value,
1671 "Cannot query an attribute with a type not derived from "
1672 "'AbstractAttribute'!");
1673 // Lookup the abstract attribute of type AAType. If found, return it after
1674 // registering a dependence of QueryingAA on the one returned attribute.
1675 AbstractAttribute *AAPtr = AAMap.lookup({&AAType::ID, IRP});
1676 if (!AAPtr)
1677 return nullptr;
1678
1679 AAType *AA = static_cast<AAType *>(AAPtr);
1680
1681 // Do not register a dependence on an attribute with an invalid state.
1682 if (DepClass != DepClassTy::NONE && QueryingAA &&
1683 AA->getState().isValidState())
1684 recordDependence(*AA, const_cast<AbstractAttribute &>(*QueryingAA),
1685 DepClass);
1686
1687 // Return nullptr if this attribute has an invalid state.
1688 if (!AllowInvalidState && !AA->getState().isValidState())
1689 return nullptr;
1690 return AA;
1691 }
1692
1693 /// Allows a query AA to request an update if a new query was received.
1695
1696 /// Explicitly record a dependence from \p FromAA to \p ToAA, that is if
1697 /// \p FromAA changes \p ToAA should be updated as well.
1698 ///
1699 /// This method should be used in conjunction with the `getAAFor` method and
1700 /// with the DepClass enum passed to the method set to None. This can
1701 /// be beneficial to avoid false dependences but it requires the users of
1702 /// `getAAFor` to explicitly record true dependences through this method.
1703 /// The \p DepClass flag indicates if the dependence is striclty necessary.
1704 /// That means for required dependences, if \p FromAA changes to an invalid
1705 /// state, \p ToAA can be moved to a pessimistic fixpoint because it required
1706 /// information from \p FromAA but none are available anymore.
1707 LLVM_ABI void recordDependence(const AbstractAttribute &FromAA,
1708 const AbstractAttribute &ToAA,
1709 DepClassTy DepClass);
1710
1711 /// Introduce a new abstract attribute into the fixpoint analysis.
1712 ///
1713 /// Note that ownership of the attribute is given to the Attributor. It will
1714 /// invoke delete for the Attributor on destruction of the Attributor.
1715 ///
1716 /// Attributes are identified by their IR position (AAType::getIRPosition())
1717 /// and the address of their static member (see AAType::ID).
1718 template <typename AAType> AAType &registerAA(AAType &AA) {
1719 static_assert(std::is_base_of<AbstractAttribute, AAType>::value,
1720 "Cannot register an attribute with a type not derived from "
1721 "'AbstractAttribute'!");
1722 // Put the attribute in the lookup map structure and the container we use to
1723 // keep track of all attributes.
1724 const IRPosition &IRP = AA.getIRPosition();
1725 AbstractAttribute *&AAPtr = AAMap[{&AAType::ID, IRP}];
1726
1727 assert(!AAPtr && "Attribute already in map!");
1728 AAPtr = &AA;
1729
1730 // Register AA with the synthetic root only before the manifest stage.
1731 if (isDuringDeduction())
1732 DG.SyntheticRoot.Deps.insert(
1734
1735 return AA;
1736 }
1737
1738 /// Return the internal information cache.
1739 InformationCache &getInfoCache() { return InfoCache; }
1740
1741 /// Return the module.
1742 const Module &getModule() { return InfoCache.getModule(); }
1743
1744 /// Return true if this is a module pass, false otherwise.
1745 bool isModulePass() const { return Configuration.IsModulePass; }
1746
1747 /// Return true if we should specialize the call site \b CB for the potential
1748 /// callee \p Fn.
1750 CallBase &CB, Function &Callee,
1751 unsigned NumAssumedCallees) {
1752 return Configuration.IndirectCalleeSpecializationCallback
1753 ? Configuration.IndirectCalleeSpecializationCallback(
1754 *this, AA, CB, Callee, NumAssumedCallees)
1755 : true;
1756 }
1757
1758 /// Return true if the module contains the whole world, thus, no outside
1759 /// functions exist.
1760 LLVM_ABI bool isClosedWorldModule() const;
1761
1762 /// Return true if we derive attributes for \p Fn
1763 bool isRunOn(Function &Fn) const { return isRunOn(&Fn); }
1764 bool isRunOn(Function *Fn) const {
1765 return Functions.empty() || Functions.count(Fn);
1766 }
1767
1768 template <typename AAType> bool shouldUpdateAA(const IRPosition &IRP) {
1769 // If this is queried in the manifest stage, we force the AA to indicate
1770 // pessimistic fixpoint immediately.
1771 if (!isDuringDeduction())
1772 return false;
1773
1774 Function *AssociatedFn = IRP.getAssociatedFunction();
1775
1776 if (IRP.isAnyCallSitePosition()) {
1777 // Check if we require a callee but there is none.
1778 if (!AssociatedFn && AAType::requiresCalleeForCallBase())
1779 return false;
1780
1781 // Check if we require non-asm but it is inline asm.
1782 if (AAType::requiresNonAsmForCallBase() &&
1783 cast<CallBase>(IRP.getAnchorValue()).isInlineAsm())
1784 return false;
1785 }
1786
1787 // Check if we require a calles but we can't see all.
1788 if (AAType::requiresCallersForArgOrFunction())
1791 if (!AssociatedFn->hasLocalLinkage())
1792 return false;
1793
1794 if (!AAType::isValidIRPositionForUpdate(*this, IRP))
1795 return false;
1796
1797 // We update only AAs associated with functions in the Functions set or
1798 // call sites of them.
1799 return (!AssociatedFn || isModulePass() || isRunOn(AssociatedFn) ||
1800 isRunOn(IRP.getAnchorScope()));
1801 }
1802
1803 template <typename AAType>
1804 bool shouldInitialize(const IRPosition &IRP, bool &ShouldUpdateAA) {
1805 if (!AAType::isValidIRPositionForInit(*this, IRP))
1806 return false;
1807
1808 if (Configuration.Allowed && !Configuration.Allowed->contains<AAType>())
1809 return false;
1810
1811 // For now we skip anything in naked and optnone functions.
1812 const Function *AnchorFn = IRP.getAnchorScope();
1813 if (AnchorFn && (AnchorFn->hasFnAttribute(Attribute::Naked) ||
1814 AnchorFn->hasFnAttribute(Attribute::OptimizeNone)))
1815 return false;
1816
1817 // Avoid too many nested initializations to prevent a stack overflow.
1818 if (InitializationChainLength > MaxInitializationChainLength)
1819 return false;
1820
1821 ShouldUpdateAA = shouldUpdateAA<AAType>(IRP);
1822
1823 return !AAType::hasTrivialInitializer() || ShouldUpdateAA;
1824 }
1825
1826 /// Determine opportunities to derive 'default' attributes in \p F and create
1827 /// abstract attribute objects for them.
1828 ///
1829 /// \param F The function that is checked for attribute opportunities.
1830 ///
1831 /// Note that abstract attribute instances are generally created even if the
1832 /// IR already contains the information they would deduce. The most important
1833 /// reason for this is the single interface, the one of the abstract attribute
1834 /// instance, which can be queried without the need to look at the IR in
1835 /// various places.
1837
1838 /// Determine whether the function \p F is IPO amendable
1839 ///
1840 /// If a function is exactly defined or it has alwaysinline attribute
1841 /// and is viable to be inlined, we say it is IPO amendable
1843 return InfoCache.isExactOrInlineable(F) ||
1844 (Configuration.IPOAmendableCB && Configuration.IPOAmendableCB(F));
1845 }
1846
1847 /// Return whether attributes can participate in fixed-point deduction.
1848 bool isDuringDeduction() const {
1849 return Phase == AttributorPhase::SEEDING ||
1850 Phase == AttributorPhase::UPDATE;
1851 }
1852
1853 /// Mark the internal function \p F as live.
1854 ///
1855 /// This will trigger the identification and initialization of attributes for
1856 /// \p F.
1858 assert(F.hasLocalLinkage() &&
1859 "Only local linkage is assumed dead initially.");
1860
1861 if (Configuration.DefaultInitializeLiveInternals)
1863 if (Configuration.InitializationCallback)
1864 Configuration.InitializationCallback(*this, F);
1865 }
1866
1867 /// Record that \p U is to be replaces with \p NV after information was
1868 /// manifested. This also triggers deletion of trivially dead istructions.
1870 Value *&V = ToBeChangedUses[&U];
1871 if (V && (V->stripPointerCasts() == NV.stripPointerCasts() ||
1873 return false;
1874 assert((!V || V == &NV || isa<UndefValue>(NV)) &&
1875 "Use was registered twice for replacement with different values!");
1876 V = &NV;
1877 return true;
1878 }
1879
1880 /// Helper function to replace all uses associated with \p IRP with \p NV.
1881 /// Return true if there is any change. The flag \p ChangeDroppable indicates
1882 /// if dropppable uses should be changed too.
1884 bool ChangeDroppable = true) {
1886 auto *CB = cast<CallBase>(IRP.getCtxI());
1888 CB->getArgOperandUse(IRP.getCallSiteArgNo()), NV);
1889 }
1890 Value &V = IRP.getAssociatedValue();
1891 auto &Entry = ToBeChangedValues[&V];
1892 Value *CurNV = get<0>(Entry);
1893 if (CurNV && (CurNV->stripPointerCasts() == NV.stripPointerCasts() ||
1894 isa<UndefValue>(CurNV)))
1895 return false;
1896 assert((!CurNV || CurNV == &NV || isa<UndefValue>(NV)) &&
1897 "Value replacement was registered twice with different values!");
1898 Entry = {&NV, ChangeDroppable};
1899 return true;
1900 }
1901
1902 /// Record that \p I is to be replaced with `unreachable` after information
1903 /// was manifested.
1905 ToBeChangedToUnreachableInsts.insert(I);
1906 }
1907
1908 /// Record that \p II has at least one dead successor block. This information
1909 /// is used, e.g., to replace \p II with a call, after information was
1910 /// manifested.
1912 InvokeWithDeadSuccessor.insert(&II);
1913 }
1914
1915 /// Record that \p I is deleted after information was manifested. This also
1916 /// triggers deletion of trivially dead istructions.
1917 void deleteAfterManifest(Instruction &I) { ToBeDeletedInsts.insert(&I); }
1918
1919 /// Record that \p BB is deleted after information was manifested. This also
1920 /// triggers deletion of trivially dead istructions.
1921 void deleteAfterManifest(BasicBlock &BB) { ToBeDeletedBlocks.insert(&BB); }
1922
1923 // Record that \p BB is added during the manifest of an AA. Added basic blocks
1924 // are preserved in the IR.
1926 ManifestAddedBlocks.insert(&BB);
1927 }
1928
1929 /// Record that \p F is deleted after information was manifested.
1931 if (Configuration.DeleteFns)
1932 ToBeDeletedFunctions.insert(&F);
1933 }
1934
1935 /// Return the attributes of kind \p AK existing in the IR as operand bundles
1936 /// of an llvm.assume.
1937 LLVM_ABI bool getAttrsFromAssumes(const IRPosition &IRP,
1940
1941 /// Return true if any kind in \p AKs existing in the IR at a position that
1942 /// will affect this one. See also getAttrs(...).
1943 /// \param IgnoreSubsumingPositions Flag to determine if subsuming positions,
1944 /// e.g., the function position if this is an
1945 /// argument position, should be ignored.
1946 LLVM_ABI bool
1948 bool IgnoreSubsumingPositions = false,
1949 Attribute::AttrKind ImpliedAttributeKind = Attribute::None);
1950
1951 /// Return the attributes of any kind in \p AKs existing in the IR at a
1952 /// position that will affect this one. While each position can only have a
1953 /// single attribute of any kind in \p AKs, there are "subsuming" positions
1954 /// that could have an attribute as well. This method returns all attributes
1955 /// found in \p Attrs.
1956 /// \param IgnoreSubsumingPositions Flag to determine if subsuming positions,
1957 /// e.g., the function position if this is an
1958 /// argument position, should be ignored.
1959 LLVM_ABI void getAttrs(const IRPosition &IRP,
1962 bool IgnoreSubsumingPositions = false);
1963
1964 /// Remove all \p AttrKinds attached to \p IRP.
1968 ArrayRef<StringRef> Attrs);
1969
1970 /// Attach \p DeducedAttrs to \p IRP, if \p ForceReplace is set we do this
1971 /// even if the same attribute kind was already present. \p DeducedAttrs
1972 /// must be sorted like an attribute set, with at most one attribute of each
1973 /// kind.
1975 ArrayRef<Attribute> DeducedAttrs,
1976 bool ForceReplace = false);
1977
1978private:
1979 /// Helper to check \p Attrs for \p AK, if not found, check if \p
1980 /// AAType::isImpliedByIR is true, and if not, create AAType for \p IRP.
1981 /// If \p SkipHasAttrCheck is true, don't check whether the attribute is set
1982 /// first. This should be used if only some values of a complex IR attribute
1983 /// imply the AAType.
1984 template <Attribute::AttrKind AK, typename AAType>
1985 void checkAndQueryIRAttr(const IRPosition &IRP, AttributeSet Attrs,
1986 bool SkipHasAttrCheck = false);
1987
1988 /// Helper to apply \p CB on all attributes of type \p AttrDescs of \p IRP.
1989 template <typename DescTy>
1990 ChangeStatus updateAttrMap(const IRPosition &IRP, ArrayRef<DescTy> AttrDescs,
1991 function_ref<bool(const DescTy &, AttributeSet,
1992 AttributeMask &, AttrBuilder &)>
1993 CB);
1994
1995 /// Mapping from functions/call sites to their attributes.
1997
1998public:
1999 /// If \p IRP is assumed to be a constant, return it, if it is unclear yet,
2000 /// return std::nullopt, otherwise return `nullptr`.
2001 LLVM_ABI std::optional<Constant *>
2003 bool &UsedAssumedInformation);
2004 std::optional<Constant *> getAssumedConstant(const Value &V,
2005 const AbstractAttribute &AA,
2006 bool &UsedAssumedInformation) {
2007 return getAssumedConstant(IRPosition::value(V), AA, UsedAssumedInformation);
2008 }
2009
2010 /// If \p V is assumed simplified, return it, if it is unclear yet,
2011 /// return std::nullopt, otherwise return `nullptr`.
2012 std::optional<Value *> getAssumedSimplified(const IRPosition &IRP,
2013 const AbstractAttribute &AA,
2014 bool &UsedAssumedInformation,
2015 AA::ValueScope S) {
2016 return getAssumedSimplified(IRP, &AA, UsedAssumedInformation, S);
2017 }
2018 std::optional<Value *> getAssumedSimplified(const Value &V,
2019 const AbstractAttribute &AA,
2020 bool &UsedAssumedInformation,
2021 AA::ValueScope S) {
2023 UsedAssumedInformation, S);
2024 }
2025
2026 /// If \p V is assumed simplified, return it, if it is unclear yet,
2027 /// return std::nullopt, otherwise return `nullptr`. Same as the public
2028 /// version except that it can be used without recording dependences on any \p
2029 /// AA.
2030 LLVM_ABI std::optional<Value *>
2032 bool &UsedAssumedInformation, AA::ValueScope S);
2033
2034 /// Try to simplify \p IRP and in the scope \p S. If successful, true is
2035 /// returned and all potential values \p IRP can take are put into \p Values.
2036 /// If the result in \p Values contains select or PHI instructions it means
2037 /// those could not be simplified to a single value. Recursive calls with
2038 /// these instructions will yield their respective potential values. If false
2039 /// is returned no other information is valid.
2040 LLVM_ABI bool
2043 AA::ValueScope S, bool &UsedAssumedInformation,
2044 bool RecurseForSelectAndPHI = true);
2045
2046 /// Register \p CB as a simplification callback.
2047 /// `Attributor::getAssumedSimplified` will use these callbacks before
2048 /// we it will ask `AAValueSimplify`. It is important to ensure this
2049 /// is called before `identifyDefaultAbstractAttributes`, assuming the
2050 /// latter is called at all.
2051 using SimplifictionCallbackTy = std::function<std::optional<Value *>(
2052 const IRPosition &, const AbstractAttribute *, bool &)>;
2054 const SimplifictionCallbackTy &CB) {
2055 SimplificationCallbacks[IRP].emplace_back(CB);
2056 }
2057
2058 /// Return true if there is a simplification callback for \p IRP.
2060 return SimplificationCallbacks.count(IRP);
2061 }
2062
2063 /// Register \p CB as a simplification callback.
2064 /// Similar to \p registerSimplificationCallback, the call back will be called
2065 /// first when we simplify a global variable \p GV.
2067 std::function<std::optional<Constant *>(
2068 const GlobalVariable &, const AbstractAttribute *, bool &)>;
2070 const GlobalVariable &GV,
2072 GlobalVariableSimplificationCallbacks[&GV].emplace_back(CB);
2073 }
2074
2075 /// Return true if there is a simplification callback for \p GV.
2077 return GlobalVariableSimplificationCallbacks.count(&GV);
2078 }
2079
2080 /// Return \p std::nullopt if there is no call back registered for \p GV or
2081 /// the call back is still not sure if \p GV can be simplified. Return \p
2082 /// nullptr if \p GV can't be simplified.
2083 std::optional<Constant *>
2085 const AbstractAttribute *AA,
2086 bool &UsedAssumedInformation) {
2087 assert(GlobalVariableSimplificationCallbacks.contains(&GV));
2088 for (auto &CB : GlobalVariableSimplificationCallbacks.lookup(&GV)) {
2089 auto SimplifiedGV = CB(GV, AA, UsedAssumedInformation);
2090 // For now we assume the call back will not return a std::nullopt.
2091 assert(SimplifiedGV.has_value() && "SimplifiedGV has not value");
2092 return *SimplifiedGV;
2093 }
2094 llvm_unreachable("there must be a callback registered");
2095 }
2096
2098 std::function<bool(Attributor &, const AbstractAttribute *)>;
2100 const VirtualUseCallbackTy &CB) {
2101 VirtualUseCallbacks[&V].emplace_back(CB);
2102 }
2103
2104private:
2105 /// The vector with all simplification callbacks registered by outside AAs.
2107 SimplificationCallbacks;
2108
2109 /// The vector with all simplification callbacks for global variables
2110 /// registered by outside AAs.
2111 DenseMap<const GlobalVariable *,
2113 GlobalVariableSimplificationCallbacks;
2114
2116 VirtualUseCallbacks;
2117
2118public:
2119 /// Translate \p V from the callee context into the call site context.
2120 LLVM_ABI std::optional<Value *>
2121 translateArgumentToCallSiteContent(std::optional<Value *> V, CallBase &CB,
2122 const AbstractAttribute &AA,
2123 bool &UsedAssumedInformation);
2124
2125 /// Return true if \p AA (or its context instruction) is assumed dead.
2126 ///
2127 /// If \p LivenessAA is not provided it is queried.
2129 const AAIsDead *LivenessAA,
2130 bool &UsedAssumedInformation,
2131 bool CheckBBLivenessOnly = false,
2132 DepClassTy DepClass = DepClassTy::OPTIONAL);
2133
2134 /// Return true if \p I is assumed dead.
2135 ///
2136 /// If \p LivenessAA is not provided it is queried.
2137 LLVM_ABI bool isAssumedDead(const Instruction &I,
2138 const AbstractAttribute *QueryingAA,
2139 const AAIsDead *LivenessAA,
2140 bool &UsedAssumedInformation,
2141 bool CheckBBLivenessOnly = false,
2143 bool CheckForDeadStore = false);
2144
2145 /// Return true if \p U is assumed dead.
2146 ///
2147 /// If \p FnLivenessAA is not provided it is queried.
2148 LLVM_ABI bool isAssumedDead(const Use &U, const AbstractAttribute *QueryingAA,
2149 const AAIsDead *FnLivenessAA,
2150 bool &UsedAssumedInformation,
2151 bool CheckBBLivenessOnly = false,
2152 DepClassTy DepClass = DepClassTy::OPTIONAL);
2153
2154 /// Return true if \p IRP is assumed dead.
2155 ///
2156 /// If \p FnLivenessAA is not provided it is queried.
2157 LLVM_ABI bool isAssumedDead(const IRPosition &IRP,
2158 const AbstractAttribute *QueryingAA,
2159 const AAIsDead *FnLivenessAA,
2160 bool &UsedAssumedInformation,
2161 bool CheckBBLivenessOnly = false,
2162 DepClassTy DepClass = DepClassTy::OPTIONAL);
2163
2164 /// Return true if \p BB is assumed dead.
2165 ///
2166 /// If \p LivenessAA is not provided it is queried.
2167 LLVM_ABI bool isAssumedDead(const BasicBlock &BB,
2168 const AbstractAttribute *QueryingAA,
2169 const AAIsDead *FnLivenessAA,
2170 DepClassTy DepClass = DepClassTy::OPTIONAL);
2171
2172 /// Check \p Pred on all potential Callees of \p CB.
2173 ///
2174 /// This method will evaluate \p Pred with all potential callees of \p CB as
2175 /// input and return true if \p Pred does. If some callees might be unknown
2176 /// this function will return false.
2179 const AbstractAttribute &QueryingAA, const CallBase &CB);
2180
2181 /// Check \p Pred on all (transitive) uses of \p V.
2182 ///
2183 /// This method will evaluate \p Pred on all (transitive) uses of the
2184 /// associated value and return true if \p Pred holds every time.
2185 /// If uses are skipped in favor of equivalent ones, e.g., if we look through
2186 /// memory, the \p EquivalentUseCB will be used to give the caller an idea
2187 /// what original used was replaced by a new one (or new ones). The visit is
2188 /// cut short if \p EquivalentUseCB returns false and the function will return
2189 /// false as well.
2191 function_ref<bool(const Use &, bool &)> Pred,
2192 const AbstractAttribute &QueryingAA, const Value &V,
2193 bool CheckBBLivenessOnly = false,
2194 DepClassTy LivenessDepClass = DepClassTy::OPTIONAL,
2195 bool IgnoreDroppableUses = true,
2196 function_ref<bool(const Use &OldU, const Use &NewU)> EquivalentUseCB =
2197 nullptr);
2198
2199 /// Emit a remark generically.
2200 ///
2201 /// This template function can be used to generically emit a remark. The
2202 /// RemarkKind should be one of the following:
2203 /// - OptimizationRemark to indicate a successful optimization attempt
2204 /// - OptimizationRemarkMissed to report a failed optimization attempt
2205 /// - OptimizationRemarkAnalysis to provide additional information about an
2206 /// optimization attempt
2207 ///
2208 /// The remark is built using a callback function \p RemarkCB that takes a
2209 /// RemarkKind as input and returns a RemarkKind.
2210 template <typename RemarkKind, typename RemarkCallBack>
2212 RemarkCallBack &&RemarkCB) const {
2213 if (!Configuration.OREGetter)
2214 return;
2215
2216 Function *F = I->getFunction();
2217 auto &ORE = Configuration.OREGetter(F);
2218
2219 if (RemarkName.starts_with("OMP"))
2220 ORE.emit([&]() {
2221 return RemarkCB(RemarkKind(Configuration.PassName, RemarkName, I))
2222 << " [" << RemarkName << "]";
2223 });
2224 else
2225 ORE.emit([&]() {
2226 return RemarkCB(RemarkKind(Configuration.PassName, RemarkName, I));
2227 });
2228 }
2229
2230 /// Emit a remark on a function.
2231 template <typename RemarkKind, typename RemarkCallBack>
2232 void emitRemark(Function *F, StringRef RemarkName,
2233 RemarkCallBack &&RemarkCB) const {
2234 if (!Configuration.OREGetter)
2235 return;
2236
2237 auto &ORE = Configuration.OREGetter(F);
2238
2239 if (RemarkName.starts_with("OMP"))
2240 ORE.emit([&]() {
2241 return RemarkCB(RemarkKind(Configuration.PassName, RemarkName, F))
2242 << " [" << RemarkName << "]";
2243 });
2244 else
2245 ORE.emit([&]() {
2246 return RemarkCB(RemarkKind(Configuration.PassName, RemarkName, F));
2247 });
2248 }
2249
2250 /// Helper struct used in the communication between an abstract attribute (AA)
2251 /// that wants to change the signature of a function and the Attributor which
2252 /// applies the changes. The struct is partially initialized with the
2253 /// information from the AA (see the constructor). All other members are
2254 /// provided by the Attributor prior to invoking any callbacks.
2255 struct ArgumentReplacementInfo {
2256 /// Callee repair callback type
2257 ///
2258 /// The function repair callback is invoked once to rewire the replacement
2259 /// arguments in the body of the new function. The argument replacement info
2260 /// is passed, as build from the registerFunctionSignatureRewrite call, as
2261 /// well as the replacement function and an iteratore to the first
2262 /// replacement argument.
2263 using CalleeRepairCBTy = std::function<void(
2264 const ArgumentReplacementInfo &, Function &, Function::arg_iterator)>;
2265
2266 /// Abstract call site (ACS) repair callback type
2267 ///
2268 /// The abstract call site repair callback is invoked once on every abstract
2269 /// call site of the replaced function (\see ReplacedFn). The callback needs
2270 /// to provide the operands for the call to the new replacement function.
2271 /// The number and type of the operands appended to the provided vector
2272 /// (second argument) is defined by the number and types determined through
2273 /// the replacement type vector (\see ReplacementTypes). The first argument
2274 /// is the ArgumentReplacementInfo object registered with the Attributor
2275 /// through the registerFunctionSignatureRewrite call.
2277 std::function<void(const ArgumentReplacementInfo &, AbstractCallSite,
2279
2280 /// Simple getters, see the corresponding members for details.
2281 ///{
2282
2283 Attributor &getAttributor() const { return A; }
2284 const Function &getReplacedFn() const { return ReplacedFn; }
2285 const Argument &getReplacedArg() const { return ReplacedArg; }
2286 unsigned getNumReplacementArgs() const { return ReplacementTypes.size(); }
2287
2288 ///}
2289
2290 private:
2291 /// Constructor that takes the argument to be replaced, the types of
2292 /// the replacement arguments, as well as callbacks to repair the call sites
2293 /// and new function after the replacement happened.
2295 ArrayRef<Type *> ReplacementTypes,
2296 CalleeRepairCBTy &&CalleeRepairCB,
2297 ACSRepairCBTy &&ACSRepairCB)
2298 : A(A), ReplacedFn(*Arg.getParent()), ReplacedArg(Arg),
2299 ReplacementTypes(ReplacementTypes),
2300 CalleeRepairCB(std::move(CalleeRepairCB)),
2301 ACSRepairCB(std::move(ACSRepairCB)) {}
2302
2303 /// Reference to the attributor to allow access from the callbacks.
2304 Attributor &A;
2305
2306 /// The "old" function replaced by ReplacementFn.
2307 const Function &ReplacedFn;
2308
2309 /// The "old" argument replaced by new ones defined via ReplacementTypes.
2310 const Argument &ReplacedArg;
2311
2312 /// The types of the arguments replacing ReplacedArg.
2313 const SmallVector<Type *, 8> ReplacementTypes;
2314
2315 /// Callee repair callback, see CalleeRepairCBTy.
2316 const CalleeRepairCBTy CalleeRepairCB;
2317
2318 /// Abstract call site (ACS) repair callback, see ACSRepairCBTy.
2319 const ACSRepairCBTy ACSRepairCB;
2320
2321 /// Allow access to the private members from the Attributor.
2322 friend struct Attributor;
2323 };
2324
2325 /// Check if we can rewrite a function signature.
2326 ///
2327 /// The argument \p Arg is replaced with new ones defined by the number,
2328 /// order, and types in \p ReplacementTypes.
2329 ///
2330 /// \returns True, if the replacement can be registered, via
2331 /// registerFunctionSignatureRewrite, false otherwise.
2332 LLVM_ABI bool
2334 ArrayRef<Type *> ReplacementTypes);
2335
2336 /// Register a rewrite for a function signature.
2337 ///
2338 /// The argument \p Arg is replaced with new ones defined by the number,
2339 /// order, and types in \p ReplacementTypes. The rewiring at the call sites is
2340 /// done through \p ACSRepairCB and at the callee site through
2341 /// \p CalleeRepairCB.
2342 ///
2343 /// \returns True, if the replacement was registered, false otherwise.
2345 Argument &Arg, ArrayRef<Type *> ReplacementTypes,
2348
2349 /// Check \p Pred on all function call sites.
2350 ///
2351 /// This method will evaluate \p Pred on call sites and return
2352 /// true if \p Pred holds in every call sites. However, this is only possible
2353 /// all call sites are known, hence the function has internal linkage.
2354 /// If true is returned, \p UsedAssumedInformation is set if assumed
2355 /// information was used to skip or simplify potential call sites.
2357 const AbstractAttribute &QueryingAA,
2358 bool RequireAllCallSites,
2359 bool &UsedAssumedInformation);
2360
2361 /// Check \p Pred on all call sites of \p Fn.
2362 ///
2363 /// This method will evaluate \p Pred on call sites and return
2364 /// true if \p Pred holds in every call sites. However, this is only possible
2365 /// all call sites are known, hence the function has internal linkage.
2366 /// If true is returned, \p UsedAssumedInformation is set if assumed
2367 /// information was used to skip or simplify potential call sites.
2369 const Function &Fn,
2370 bool RequireAllCallSites,
2371 const AbstractAttribute *QueryingAA,
2372 bool &UsedAssumedInformation,
2373 bool CheckPotentiallyDead = false);
2374
2375 /// Check \p Pred on all values potentially returned by the function
2376 /// associated with \p QueryingAA.
2377 ///
2378 /// This is the context insensitive version of the method above.
2379 LLVM_ABI bool
2381 const AbstractAttribute &QueryingAA,
2383 bool RecurseForSelectAndPHI = true);
2384
2385 /// Check \p Pred on all instructions in \p Fn with an opcode present in
2386 /// \p Opcodes.
2387 ///
2388 /// This method will evaluate \p Pred on all instructions with an opcode
2389 /// present in \p Opcode and return true if \p Pred holds on all of them.
2391 const Function *Fn,
2392 const AbstractAttribute *QueryingAA,
2393 ArrayRef<unsigned> Opcodes,
2394 bool &UsedAssumedInformation,
2395 bool CheckBBLivenessOnly = false,
2396 bool CheckPotentiallyDead = false);
2397
2398 /// Check \p Pred on all instructions with an opcode present in \p Opcodes.
2399 ///
2400 /// This method will evaluate \p Pred on all instructions with an opcode
2401 /// present in \p Opcode and return true if \p Pred holds on all of them.
2403 const AbstractAttribute &QueryingAA,
2404 ArrayRef<unsigned> Opcodes,
2405 bool &UsedAssumedInformation,
2406 bool CheckBBLivenessOnly = false,
2407 bool CheckPotentiallyDead = false);
2408
2409 /// Check \p Pred on all call-like instructions (=CallBased derived).
2410 ///
2411 /// See checkForAllCallLikeInstructions(...) for more information.
2413 const AbstractAttribute &QueryingAA,
2414 bool &UsedAssumedInformation,
2415 bool CheckBBLivenessOnly = false,
2416 bool CheckPotentiallyDead = false) {
2418 Pred, QueryingAA,
2419 {(unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,
2420 (unsigned)Instruction::Call},
2421 UsedAssumedInformation, CheckBBLivenessOnly, CheckPotentiallyDead);
2422 }
2423
2424 /// Check \p Pred on all Read/Write instructions.
2425 ///
2426 /// This method will evaluate \p Pred on all instructions that read or write
2427 /// to memory present in the information cache and return true if \p Pred
2428 /// holds on all of them.
2429 LLVM_ABI bool
2431 AbstractAttribute &QueryingAA,
2432 bool &UsedAssumedInformation);
2433
2434 /// Create a shallow wrapper for \p F such that \p F has internal linkage
2435 /// afterwards. It also sets the original \p F 's name to anonymous
2436 ///
2437 /// A wrapper is a function with the same type (and attributes) as \p F
2438 /// that will only call \p F and return the result, if any.
2439 ///
2440 /// Assuming the declaration of looks like:
2441 /// rty F(aty0 arg0, ..., atyN argN);
2442 ///
2443 /// The wrapper will then look as follows:
2444 /// rty wrapper(aty0 arg0, ..., atyN argN) {
2445 /// return F(arg0, ..., argN);
2446 /// }
2447 ///
2449
2450 /// Returns true if the function \p F can be internalized. i.e. it has a
2451 /// compatible linkage.
2452 LLVM_ABI static bool isInternalizable(Function &F);
2453
2454 /// Make another copy of the function \p F such that the copied version has
2455 /// internal linkage afterwards and can be analysed. Then we replace all uses
2456 /// of the original function to the copied one
2457 ///
2458 /// Only non-locally linked functions that have `linkonce_odr` or `weak_odr`
2459 /// linkage can be internalized because these linkages guarantee that other
2460 /// definitions with the same name have the same semantics as this one.
2461 ///
2462 /// This will only be run if the `attributor-allow-deep-wrappers` option is
2463 /// set, or if the function is called with \p Force set to true.
2464 ///
2465 /// If the function \p F failed to be internalized the return value will be a
2466 /// null pointer.
2468 bool Force = false);
2469
2470 /// Make copies of each function in the set \p FnSet such that the copied
2471 /// version has internal linkage afterwards and can be analysed. Then we
2472 /// replace all uses of the original function to the copied one. The map
2473 /// \p FnMap contains a mapping of functions to their internalized versions.
2474 ///
2475 /// Only non-locally linked functions that have `linkonce_odr` or `weak_odr`
2476 /// linkage can be internalized because these linkages guarantee that other
2477 /// definitions with the same name have the same semantics as this one.
2478 ///
2479 /// This version will internalize all the functions in the set \p FnSet at
2480 /// once and then replace the uses. This prevents internalized functions being
2481 /// called by external functions when there is an internalized version in the
2482 /// module.
2483 LLVM_ABI static bool
2486
2487 /// Return the data layout associated with the anchor scope.
2488 const DataLayout &getDataLayout() const { return InfoCache.getDL(); }
2489
2490 /// The allocator used to allocate memory, e.g. for `AbstractAttribute`s.
2492
2494 return CGModifiedFunctions;
2495 }
2496
2497 /// Return the functions whose attributes, or whose call site attributes,
2498 /// were changed.
2500 return AttrModifiedFunctions;
2501 }
2502
2503private:
2504 /// This method will do fixpoint iteration until fixpoint or the
2505 /// maximum iteration count is reached.
2506 ///
2507 /// If the maximum iteration count is reached, This method will
2508 /// indicate pessimistic fixpoint on attributes that transitively depend
2509 /// on attributes that were scheduled for an update.
2510 void runTillFixpoint();
2511
2512 /// Gets called after scheduling, manifests attributes to the LLVM IR.
2513 ChangeStatus manifestAttributes();
2514
2515 /// Gets called after attributes have been manifested, cleans up the IR.
2516 /// Deletes dead functions, blocks and instructions.
2517 /// Rewrites function signitures and updates the call graph.
2518 ChangeStatus cleanupIR();
2519
2520 /// Identify internal functions that are effectively dead, thus not reachable
2521 /// from a live entry point. The functions are added to ToBeDeletedFunctions.
2522 void identifyDeadInternalFunctions();
2523
2524 /// Run `::update` on \p AA and track the dependences queried while doing so.
2525 /// Also adjust the state if we know further updates are not necessary.
2527
2528 /// Remember the dependences on the top of the dependence stack such that they
2529 /// may trigger further updates. (\see DependenceStack)
2530 void rememberDependences();
2531
2532 /// Determine if CallBase context in \p IRP should be propagated.
2533 LLVM_ABI bool shouldPropagateCallBaseContext(const IRPosition &IRP);
2534
2535 /// Apply all requested function signature rewrites
2536 /// (\see registerFunctionSignatureRewrite) and return Changed if the module
2537 /// was altered.
2539 rewriteFunctionSignatures(SmallSetVector<Function *, 8> &ModifiedFns);
2540
2541 /// Check if the Attribute \p AA should be seeded.
2542 /// See getOrCreateAAFor.
2543 LLVM_ABI bool shouldSeedAttribute(AbstractAttribute &AA);
2544
2545 /// A nested map to lookup abstract attributes based on the argument position
2546 /// on the outer level, and the addresses of the static member (AAType::ID) on
2547 /// the inner level.
2548 ///{
2549 using AAMapKeyTy = std::pair<const char *, IRPosition>;
2550 /// The IDs are adjacent bytes and the positions of a value differ only in
2551 /// the low bits, both of which the default hash functions mostly ignore.
2552 struct AAMapKeyInfo : DenseMapInfo<AAMapKeyTy> {
2553 static unsigned getHashValue(const AAMapKeyTy &Key) {
2554 const IRPosition &IRP = Key.second;
2555 auto ID = reinterpret_cast<uintptr_t>(Key.first);
2556 auto Pos = reinterpret_cast<uintptr_t>(static_cast<void *>(IRP));
2557 auto Ctx = reinterpret_cast<uintptr_t>(IRP.getCallBaseContext());
2558 return detail::combineHashValue(unsigned(ID), unsigned(Pos ^ Ctx));
2559 }
2560 };
2561 DenseMap<AAMapKeyTy, AbstractAttribute *, AAMapKeyInfo> AAMap;
2562 ///}
2563
2564 /// Map to remember all requested signature changes (= argument replacements).
2565 /// A MapVector so the functions are rewritten in a deterministic order.
2566 MapVector<Function *,
2568 ArgumentReplacementMap;
2569
2570 /// The set of functions we are deriving attributes for.
2571 SetVector<Function *> &Functions;
2572
2573 /// The information cache that holds pre-processed (LLVM-IR) information.
2574 InformationCache &InfoCache;
2575
2576 /// Abstract Attribute dependency graph
2577 AADepGraph DG;
2578
2579 /// Set of functions for which we modified the content such that it might
2580 /// impact the call graph.
2581 SmallSetVector<Function *, 8> CGModifiedFunctions;
2582
2583 /// Set of functions whose attributes, or whose call site attributes, were
2584 /// changed during manifest.
2585 SmallSetVector<Function *, 8> AttrModifiedFunctions;
2586
2587 /// Information about a dependence. If FromAA is changed ToAA needs to be
2588 /// updated as well.
2589 struct DepInfo {
2590 const AbstractAttribute *FromAA;
2591 const AbstractAttribute *ToAA;
2592 DepClassTy DepClass;
2593 };
2594
2595 /// The dependence stack is used to track dependences during an
2596 /// `AbstractAttribute::update` call. As `AbstractAttribute::update` can be
2597 /// recursive we might have multiple vectors of dependences in here. The stack
2598 /// size, should be adjusted according to the expected recursion depth and the
2599 /// inner dependence vector size to the expected number of dependences per
2600 /// abstract attribute. Since the inner vectors are actually allocated on the
2601 /// stack we can be generous with their size.
2602 using DependenceVector = SmallVector<DepInfo, 8>;
2604
2605 /// A set to remember the functions we already assume to be live and visited.
2606 DenseSet<const Function *> VisitedFunctions;
2607
2608 /// Uses we replace with a new value after manifest is done. We will remove
2609 /// then trivially dead instructions as well.
2610 SmallMapVector<Use *, Value *, 32> ToBeChangedUses;
2611
2612 /// Values we replace with a new value after manifest is done. We will remove
2613 /// then trivially dead instructions as well.
2614 SmallMapVector<Value *, PointerIntPair<Value *, 1, bool>, 32>
2615 ToBeChangedValues;
2616
2617 /// Instructions we replace with `unreachable` insts after manifest is done.
2618 SmallSetVector<WeakVH, 16> ToBeChangedToUnreachableInsts;
2619
2620 /// Invoke instructions with at least a single dead successor block.
2621 SmallSetVector<WeakVH, 16> InvokeWithDeadSuccessor;
2622
2623 /// A flag that indicates which stage of the process we are in. Initially, the
2624 /// phase is SEEDING. Phase is changed in `Attributor::run()`
2625 enum class AttributorPhase {
2626 SEEDING,
2627 UPDATE,
2628 MANIFEST,
2629 CLEANUP,
2630 } Phase = AttributorPhase::SEEDING;
2631
2632 /// The current initialization chain length. Tracked to avoid stack overflows.
2633 unsigned InitializationChainLength = 0;
2634
2635 /// Whether time trace scopes are recorded for every initialization and
2636 /// update.
2637 const bool TimeTraceEnabled = timeTraceProfilerEnabled();
2638
2639 /// Functions, blocks, and instructions we delete after manifest is done.
2640 ///
2641 ///{
2642 SmallPtrSet<BasicBlock *, 8> ManifestAddedBlocks;
2643 SmallSetVector<Function *, 8> ToBeDeletedFunctions;
2644 SmallSetVector<BasicBlock *, 8> ToBeDeletedBlocks;
2645 SmallSetVector<WeakVH, 8> ToBeDeletedInsts;
2646 ///}
2647
2648 /// Container with all the query AAs that requested an update via
2649 /// registerForUpdate.
2650 SmallSetVector<AbstractAttribute *, 16> QueryAAsAwaitingUpdate;
2651
2652 /// User provided configuration for this Attributor instance.
2653 const AttributorConfig Configuration;
2654
2655 friend AADepGraph;
2656 friend AttributorCallGraph;
2657};
2658
2659/// An interface to query the internal state of an abstract attribute.
2660///
2661/// The abstract state is a minimal interface that allows the Attributor to
2662/// communicate with the abstract attributes about their internal state without
2663/// enforcing or exposing implementation details, e.g., the (existence of an)
2664/// underlying lattice.
2665///
2666/// It is sufficient to be able to query if a state is (1) valid or invalid, (2)
2667/// at a fixpoint, and to indicate to the state that (3) an optimistic fixpoint
2668/// was reached or (4) a pessimistic fixpoint was enforced.
2669///
2670/// All methods need to be implemented by the subclass. For the common use case,
2671/// a single boolean state or a bit-encoded state, the BooleanState and
2672/// {Inc,Dec,Bit}IntegerState classes are already provided. An abstract
2673/// attribute can inherit from them to get the abstract state interface and
2674/// additional methods to directly modify the state based if needed. See the
2675/// class comments for help.
2677 virtual ~AbstractState() = default;
2678
2679 /// Return if this abstract state is in a valid state. If false, no
2680 /// information provided should be used.
2681 virtual bool isValidState() const = 0;
2682
2683 /// Return if this abstract state is fixed, thus does not need to be updated
2684 /// if information changes as it cannot change itself.
2685 virtual bool isAtFixpoint() const = 0;
2686
2687 /// Indicate that the abstract state should converge to the optimistic state.
2688 ///
2689 /// This will usually make the optimistically assumed state the known to be
2690 /// true state.
2691 ///
2692 /// \returns ChangeStatus::UNCHANGED as the assumed value should not change.
2694
2695 /// Indicate that the abstract state should converge to the pessimistic state.
2696 ///
2697 /// This will usually revert the optimistically assumed state to the known to
2698 /// be true state.
2699 ///
2700 /// \returns ChangeStatus::CHANGED as the assumed value may change.
2702};
2703
2704/// Simple state with integers encoding.
2705///
2706/// The interface ensures that the assumed bits are always a subset of the known
2707/// bits. Users can only add known bits and, except through adding known bits,
2708/// they can only remove assumed bits. This should guarantee monotonicity and
2709/// thereby the existence of a fixpoint (if used correctly). The fixpoint is
2710/// reached when the assumed and known state/bits are equal. Users can
2711/// force/inidicate a fixpoint. If an optimistic one is indicated, the known
2712/// state will catch up with the assumed one, for a pessimistic fixpoint it is
2713/// the other way around.
2714template <typename base_ty, base_ty BestState, base_ty WorstState>
2716 using base_t = base_ty;
2717
2718 IntegerStateBase() = default;
2720
2721 /// Return the best possible representable state.
2722 static constexpr base_t getBestState() { return BestState; }
2723 static constexpr base_t getBestState(const IntegerStateBase &) {
2724 return getBestState();
2725 }
2726
2727 /// Return the worst possible representable state.
2728 static constexpr base_t getWorstState() { return WorstState; }
2729 static constexpr base_t getWorstState(const IntegerStateBase &) {
2730 return getWorstState();
2731 }
2732
2733 /// NOTE: For now we simply pretend that the worst possible state is invalid.
2734 bool isValidState() const override { return Assumed != getWorstState(); }
2735
2736 bool isAtFixpoint() const override { return Assumed == Known; }
2737
2742
2747
2748 /// Return the known state encoding
2749 base_t getKnown() const { return Known; }
2750
2751 /// Return the assumed state encoding.
2752 base_t getAssumed() const { return Assumed; }
2753
2754 /// Equality for IntegerStateBase.
2755 bool
2757 return this->getAssumed() == R.getAssumed() &&
2758 this->getKnown() == R.getKnown();
2759 }
2760
2761 /// Inequality for IntegerStateBase.
2762 bool
2764 return !(*this == R);
2765 }
2766
2767 /// "Clamp" this state with \p R. The result is subtype dependent but it is
2768 /// intended that only information assumed in both states will be assumed in
2769 /// this one afterwards.
2773
2774 /// "Clamp" this state with \p R. The result is subtype dependent but it is
2775 /// intended that information known in either state will be known in
2776 /// this one afterwards.
2780
2782 joinOR(R.getAssumed(), R.getKnown());
2783 }
2784
2786 joinAND(R.getAssumed(), R.getKnown());
2787 }
2788
2789protected:
2790 /// Handle a new assumed value \p Value. Subtype dependent.
2792
2793 /// Handle a new known value \p Value. Subtype dependent.
2795
2796 /// Handle a value \p Value. Subtype dependent.
2797 virtual void joinOR(base_t AssumedValue, base_t KnownValue) = 0;
2798
2799 /// Handle a new assumed value \p Value. Subtype dependent.
2800 virtual void joinAND(base_t AssumedValue, base_t KnownValue) = 0;
2801
2802 /// The known state encoding in an integer of type base_t.
2804
2805 /// The assumed state encoding in an integer of type base_t.
2807};
2808
2809/// Specialization of the integer state for a bit-wise encoding.
2810template <typename base_ty = uint32_t, base_ty BestState = ~base_ty(0),
2811 base_ty WorstState = 0>
2813 : public IntegerStateBase<base_ty, BestState, WorstState> {
2815 using base_t = base_ty;
2816 BitIntegerState() = default;
2818
2819 /// Return true if the bits set in \p BitsEncoding are "known bits".
2820 bool isKnown(base_t BitsEncoding = BestState) const {
2821 return (this->Known & BitsEncoding) == BitsEncoding;
2822 }
2823
2824 /// Return true if the bits set in \p BitsEncoding are "assumed bits".
2825 bool isAssumed(base_t BitsEncoding = BestState) const {
2826 return (this->Assumed & BitsEncoding) == BitsEncoding;
2827 }
2828
2829 /// Add the bits in \p BitsEncoding to the "known bits".
2831 // Make sure we never miss any "known bits".
2832 this->Assumed |= Bits;
2833 this->Known |= Bits;
2834 return *this;
2835 }
2836
2837 /// Remove the bits in \p BitsEncoding from the "assumed bits" if not known.
2839 return intersectAssumedBits(~BitsEncoding);
2840 }
2841
2842 /// Remove the bits in \p BitsEncoding from the "known bits".
2844 this->Known = (this->Known & ~BitsEncoding);
2845 return *this;
2846 }
2847
2848 /// Keep only "assumed bits" also set in \p BitsEncoding but all known ones.
2850 // Make sure we never lose any "known bits".
2851 this->Assumed = (this->Assumed & BitsEncoding) | this->Known;
2852 return *this;
2853 }
2854
2855private:
2856 void handleNewAssumedValue(base_t Value) override {
2858 }
2859 void handleNewKnownValue(base_t Value) override { addKnownBits(Value); }
2860 void joinOR(base_t AssumedValue, base_t KnownValue) override {
2861 this->Known |= KnownValue;
2862 this->Assumed |= AssumedValue;
2863 }
2864 void joinAND(base_t AssumedValue, base_t KnownValue) override {
2865 this->Known &= KnownValue;
2866 this->Assumed &= AssumedValue;
2867 }
2868};
2869
2870/// Specialization of the integer state for an increasing value, hence ~0u is
2871/// the best state and 0 the worst.
2872template <typename base_ty = uint32_t, base_ty BestState = ~base_ty(0),
2873 base_ty WorstState = 0>
2875 : public IntegerStateBase<base_ty, BestState, WorstState> {
2877 using base_t = base_ty;
2878
2881
2882 /// Return the best possible representable state.
2883 static constexpr base_t getBestState() { return BestState; }
2884 static constexpr base_t
2888
2889 /// Take minimum of assumed and \p Value.
2891 // Make sure we never lose "known value".
2892 this->Assumed = std::max(std::min(this->Assumed, Value), this->Known);
2893 return *this;
2894 }
2895
2896 /// Take maximum of known and \p Value.
2898 // Make sure we never lose "known value".
2899 this->Assumed = std::max(Value, this->Assumed);
2900 this->Known = std::max(Value, this->Known);
2901 return *this;
2902 }
2903
2904private:
2905 void handleNewAssumedValue(base_t Value) override {
2907 }
2908 void handleNewKnownValue(base_t Value) override { takeKnownMaximum(Value); }
2909 void joinOR(base_t AssumedValue, base_t KnownValue) override {
2910 this->Known = std::max(this->Known, KnownValue);
2911 this->Assumed = std::max(this->Assumed, AssumedValue);
2912 }
2913 void joinAND(base_t AssumedValue, base_t KnownValue) override {
2914 this->Known = std::min(this->Known, KnownValue);
2915 this->Assumed = std::min(this->Assumed, AssumedValue);
2916 }
2917};
2918
2919/// Specialization of the integer state for a decreasing value, hence 0 is the
2920/// best state and ~0u the worst.
2921template <typename base_ty = uint32_t>
2922struct DecIntegerState : public IntegerStateBase<base_ty, 0, ~base_ty(0)> {
2923 using base_t = base_ty;
2924
2925 /// Take maximum of assumed and \p Value.
2927 // Make sure we never lose "known value".
2928 this->Assumed = std::min(std::max(this->Assumed, Value), this->Known);
2929 return *this;
2930 }
2931
2932 /// Take minimum of known and \p Value.
2934 // Make sure we never lose "known value".
2935 this->Assumed = std::min(Value, this->Assumed);
2936 this->Known = std::min(Value, this->Known);
2937 return *this;
2938 }
2939
2940private:
2941 void handleNewAssumedValue(base_t Value) override {
2943 }
2944 void handleNewKnownValue(base_t Value) override { takeKnownMinimum(Value); }
2945 void joinOR(base_t AssumedValue, base_t KnownValue) override {
2946 this->Assumed = std::min(this->Assumed, KnownValue);
2947 this->Assumed = std::min(this->Assumed, AssumedValue);
2948 }
2949 void joinAND(base_t AssumedValue, base_t KnownValue) override {
2950 this->Assumed = std::max(this->Assumed, KnownValue);
2951 this->Assumed = std::max(this->Assumed, AssumedValue);
2952 }
2953};
2954
2955/// Simple wrapper for a single bit (boolean) state.
2956struct BooleanState : public IntegerStateBase<bool, true, false> {
2959
2960 BooleanState() = default;
2962
2963 /// Set the known and asssumed value to \p Value.
2964 void setKnown(bool Value) {
2965 Known |= Value;
2966 Assumed |= Value;
2967 }
2968
2969 /// Return true if the state is assumed to hold.
2970 bool isAssumed() const { return getAssumed(); }
2971
2972 /// Return true if the state is known to hold.
2973 bool isKnown() const { return getKnown(); }
2974
2975private:
2976 void handleNewAssumedValue(base_t Value) override {
2977 if (!Value)
2978 Assumed = Known;
2979 }
2980 void handleNewKnownValue(base_t Value) override {
2981 if (Value)
2982 Known = (Assumed = Value);
2983 }
2984 void joinOR(base_t AssumedValue, base_t KnownValue) override {
2985 Known |= KnownValue;
2986 Assumed |= AssumedValue;
2987 }
2988 void joinAND(base_t AssumedValue, base_t KnownValue) override {
2989 Known &= KnownValue;
2990 Assumed &= AssumedValue;
2991 }
2992};
2993
2994/// State for an integer range.
2996
2997 /// Bitwidth of the associated value.
2999
3000 /// State representing assumed range, initially set to empty.
3002
3003 /// State representing known range, initially set to [-inf, inf].
3005
3009
3013
3014 /// Return the worst possible representable state.
3016 return ConstantRange::getFull(BitWidth);
3017 }
3018
3019 /// Return the best possible representable state.
3021 return ConstantRange::getEmpty(BitWidth);
3022 }
3024 return getBestState(IRS.getBitWidth());
3025 }
3026
3027 /// Return associated values' bit width.
3028 uint32_t getBitWidth() const { return BitWidth; }
3029
3030 bool isValidState() const override {
3031 return BitWidth > 0 && !Assumed.isFullSet();
3032 }
3033
3034 bool isAtFixpoint() const override { return Assumed == Known; }
3035
3040
3045
3046 /// Return the known state encoding
3047 ConstantRange getKnown() const { return Known; }
3048
3049 /// Return the assumed state encoding.
3051
3052 /// Unite assumed range with the passed state.
3054 // Don't lose a known range.
3055 Assumed = Assumed.unionWith(R).intersectWith(Known);
3056 }
3057
3058 /// See IntegerRangeState::unionAssumed(..).
3060 unionAssumed(R.getAssumed());
3061 }
3062
3063 /// Intersect known range with the passed state.
3065 Assumed = Assumed.intersectWith(R);
3066 Known = Known.intersectWith(R);
3067 }
3068
3069 /// See IntegerRangeState::intersectKnown(..).
3071 intersectKnown(R.getKnown());
3072 }
3073
3074 /// Equality for IntegerRangeState.
3075 bool operator==(const IntegerRangeState &R) const {
3076 return getAssumed() == R.getAssumed() && getKnown() == R.getKnown();
3077 }
3078
3079 /// "Clamp" this state with \p R. The result is subtype dependent but it is
3080 /// intended that only information assumed in both states will be assumed in
3081 /// this one afterwards.
3083 // NOTE: `^=` operator seems like `intersect` but in this case, we need to
3084 // take `union`.
3085 unionAssumed(R);
3086 return *this;
3087 }
3088
3090 // NOTE: `&=` operator seems like `intersect` but in this case, we need to
3091 // take `union`.
3092 Known = Known.unionWith(R.getKnown());
3093 Assumed = Assumed.unionWith(R.getAssumed());
3094 return *this;
3095 }
3096};
3097
3098/// Simple state for a set.
3099///
3100/// This represents a state containing a set of values. The interface supports
3101/// modelling sets that contain all possible elements. The state's internal
3102/// value is modified using union or intersection operations.
3103template <typename BaseTy> struct SetState : public AbstractState {
3104 /// A wrapper around a set that has semantics for handling unions and
3105 /// intersections with a "universal" set that contains all elements.
3107 /// Creates a universal set with no concrete elements or an empty set.
3108 SetContents(bool Universal) : Universal(Universal) {}
3109
3110 /// Creates a non-universal set with concrete values.
3111 SetContents(const DenseSet<BaseTy> &Assumptions)
3112 : Universal(false), Set(Assumptions) {}
3113
3114 SetContents(bool Universal, const DenseSet<BaseTy> &Assumptions)
3115 : Universal(Universal), Set(Assumptions) {}
3116
3117 const DenseSet<BaseTy> &getSet() const { return Set; }
3118
3119 bool isUniversal() const { return Universal; }
3120
3121 bool empty() const { return Set.empty() && !Universal; }
3122
3123 /// Finds A := A ^ B where A or B could be the "Universal" set which
3124 /// contains every possible attribute. Returns true if changes were made.
3126 bool IsUniversal = Universal;
3127 unsigned Size = Set.size();
3128
3129 // A := A ^ U = A
3130 if (RHS.isUniversal())
3131 return false;
3132
3133 // A := U ^ B = B
3134 if (Universal)
3135 Set = RHS.getSet();
3136 else
3137 set_intersect(Set, RHS.getSet());
3138
3139 Universal &= RHS.isUniversal();
3140 return IsUniversal != Universal || Size != Set.size();
3141 }
3142
3143 /// Finds A := A u B where A or B could be the "Universal" set which
3144 /// contains every possible attribute. returns true if changes were made.
3145 bool getUnion(const SetContents &RHS) {
3146 bool IsUniversal = Universal;
3147 unsigned Size = Set.size();
3148
3149 // A := A u U = U = U u B
3150 if (!RHS.isUniversal() && !Universal)
3151 set_union(Set, RHS.getSet());
3152
3153 Universal |= RHS.isUniversal();
3154 return IsUniversal != Universal || Size != Set.size();
3155 }
3156
3157 private:
3158 /// Indicates if this set is "universal", containing every possible element.
3159 bool Universal;
3160
3161 /// The set of currently active assumptions.
3162 DenseSet<BaseTy> Set;
3163 };
3164
3165 SetState() : Known(false), Assumed(true), IsAtFixedpoint(false) {}
3166
3167 /// Initializes the known state with an initial set and initializes the
3168 /// assumed state as universal.
3170 : Known(Known), Assumed(true), IsAtFixedpoint(false) {}
3171
3172 bool isValidState() const override { return !Assumed.empty(); }
3173
3174 bool isAtFixpoint() const override { return IsAtFixedpoint; }
3175
3177 IsAtFixedpoint = true;
3178 Known = Assumed;
3180 }
3181
3183 IsAtFixedpoint = true;
3184 Assumed = Known;
3185 return ChangeStatus::CHANGED;
3186 }
3187
3188 /// Return the known state encoding.
3189 const SetContents &getKnown() const { return Known; }
3190
3191 /// Return the assumed state encoding.
3192 const SetContents &getAssumed() const { return Assumed; }
3193
3194 /// Returns if the set state contains the element.
3195 bool setContains(const BaseTy &Elem) const {
3196 return Assumed.getSet().contains(Elem) || Known.getSet().contains(Elem);
3197 }
3198
3199 /// Performs the set intersection between this set and \p RHS. Returns true if
3200 /// changes were made.
3202 bool IsUniversal = Assumed.isUniversal();
3203 unsigned SizeBefore = Assumed.getSet().size();
3204
3205 // Get intersection and make sure that the known set is still a proper
3206 // subset of the assumed set. A := K u (A ^ R).
3207 Assumed.getIntersection(RHS);
3208 Assumed.getUnion(Known);
3209
3210 return SizeBefore != Assumed.getSet().size() ||
3211 IsUniversal != Assumed.isUniversal();
3212 }
3213
3214 /// Performs the set union between this set and \p RHS. Returns true if
3215 /// changes were made.
3216 bool getUnion(const SetContents &RHS) { return Assumed.getUnion(RHS); }
3217
3218private:
3219 /// The set of values known for this state.
3220 SetContents Known;
3221
3222 /// The set of assumed values for this state.
3223 SetContents Assumed;
3224
3225 bool IsAtFixedpoint;
3226};
3227
3228/// Helper to tie a abstract state implementation to an abstract attribute.
3229template <typename StateTy, typename BaseType, class... Ts>
3230struct StateWrapper : public BaseType, public StateTy {
3231 /// Provide static access to the type of the state.
3233
3234 StateWrapper(const IRPosition &IRP, Ts... Args)
3235 : BaseType(IRP), StateTy(Args...) {}
3236
3237 StateType &getState() override { return *this; }
3238
3239 const StateType &getState() const override { return *this; }
3240
3241 bool isAtFixpoint() const final { return StateTy::isAtFixpoint(); }
3242
3243 bool isStateAtFixpoint() const final { return StateTy::isAtFixpoint(); }
3244};
3245
3246/// Helper class that provides common functionality to manifest IR attributes.
3247template <Attribute::AttrKind AK, typename BaseType, typename AAType>
3248struct IRAttribute : public BaseType {
3249 IRAttribute(const IRPosition &IRP) : BaseType(IRP) {}
3250
3251 /// Most boolean IRAttribute AAs don't do anything non-trivial
3252 /// in their initializers while non-boolean ones often do. Subclasses can
3253 /// change this.
3255
3256 /// Compile time access to the IR attribute kind.
3258
3259 /// Return true if the IR attribute(s) associated with this AA are implied for
3260 /// an undef value.
3261 static bool isImpliedByUndef() { return true; }
3262
3263 /// Return true if the IR attribute(s) associated with this AA are implied for
3264 /// an poison value.
3265 static bool isImpliedByPoison() { return true; }
3266
3267 static bool isImpliedByIR(Attributor &A, const IRPosition &IRP,
3268 Attribute::AttrKind ImpliedAttributeKind = AK,
3269 bool IgnoreSubsumingPositions = false) {
3270 if (AAType::isImpliedByUndef() && isa<UndefValue>(IRP.getAssociatedValue()))
3271 return true;
3272 if (AAType::isImpliedByPoison() &&
3274 return true;
3275 return A.hasAttr(IRP, {ImpliedAttributeKind}, IgnoreSubsumingPositions,
3276 ImpliedAttributeKind);
3277 }
3278
3280 if (isa<UndefValue>(this->getIRPosition().getAssociatedValue()))
3282 SmallVector<Attribute, 4> DeducedAttrs;
3283 getDeducedAttributes(A, this->getAnchorValue().getContext(), DeducedAttrs);
3284 if (DeducedAttrs.empty())
3286 return A.manifestAttrs(this->getIRPosition(), DeducedAttrs);
3287 }
3288
3289 /// Return the kind that identifies the abstract attribute implementation.
3290 Attribute::AttrKind getAttrKind() const { return AK; }
3291
3292 /// Return the deduced attributes in \p Attrs.
3294 SmallVectorImpl<Attribute> &Attrs) const {
3295 Attrs.emplace_back(Attribute::get(Ctx, getAttrKind()));
3296 }
3297};
3298
3299/// Base struct for all "concrete attribute" deductions.
3300///
3301/// The abstract attribute is a minimal interface that allows the Attributor to
3302/// orchestrate the abstract/fixpoint analysis. The design allows to hide away
3303/// implementation choices made for the subclasses but also to structure their
3304/// implementation and simplify the use of other abstract attributes in-flight.
3305///
3306/// To allow easy creation of new attributes, most methods have default
3307/// implementations. The ones that do not are generally straight forward, except
3308/// `AbstractAttribute::updateImpl` which is the location of most reasoning
3309/// associated with the abstract attribute. The update is invoked by the
3310/// Attributor in case the situation used to justify the current optimistic
3311/// state might have changed. The Attributor determines this automatically
3312/// by monitoring the `Attributor::getAAFor` calls made by abstract attributes.
3313///
3314/// The `updateImpl` method should inspect the IR and other abstract attributes
3315/// in-flight to justify the best possible (=optimistic) state. The actual
3316/// implementation is, similar to the underlying abstract state encoding, not
3317/// exposed. In the most common case, the `updateImpl` will go through a list of
3318/// reasons why its optimistic state is valid given the current information. If
3319/// any combination of them holds and is sufficient to justify the current
3320/// optimistic state, the method shall return UNCHAGED. If not, the optimistic
3321/// state is adjusted to the situation and the method shall return CHANGED.
3322///
3323/// If the manifestation of the "concrete attribute" deduced by the subclass
3324/// differs from the "default" behavior, which is a (set of) LLVM-IR
3325/// attribute(s) for an argument, call site argument, function return value, or
3326/// function, the `AbstractAttribute::manifest` method should be overloaded.
3327///
3328/// NOTE: If the state obtained via getState() is INVALID, thus if
3329/// AbstractAttribute::getState().isValidState() returns false, no
3330/// information provided by the methods of this class should be used.
3331/// NOTE: The Attributor currently has certain limitations to what we can do.
3332/// As a general rule of thumb, "concrete" abstract attributes should *for
3333/// now* only perform "backward" information propagation. That means
3334/// optimistic information obtained through abstract attributes should
3335/// only be used at positions that precede the origin of the information
3336/// with regards to the program flow. More practically, information can
3337/// *now* be propagated from instructions to their enclosing function, but
3338/// *not* from call sites to the called function. The mechanisms to allow
3339/// both directions will be added in the future.
3340/// NOTE: The mechanics of adding a new "concrete" abstract attribute are
3341/// described in the file comment.
3344
3346
3347 /// Virtual destructor.
3348 ~AbstractAttribute() override = default;
3349
3350 /// Compile time access to the IR attribute kind.
3352
3353 /// This function is used to identify if an \p DGN is of type
3354 /// AbstractAttribute so that the dyn_cast and cast can use such information
3355 /// to cast an AADepGraphNode to an AbstractAttribute.
3356 ///
3357 /// We eagerly return true here because all AADepGraphNodes except for the
3358 /// Synthethis Node are of type AbstractAttribute
3359 static bool classof(const AADepGraphNode *DGN) { return true; }
3360
3361 /// Return false if this AA does anything non-trivial (hence not done by
3362 /// default) in its initializer.
3363 static bool hasTrivialInitializer() { return false; }
3364
3365 /// Return true if this AA requires a "callee" (or an associted function) for
3366 /// a call site positon. Default is optimistic to minimize AAs.
3367 static bool requiresCalleeForCallBase() { return false; }
3368
3369 /// Return true if this AA requires non-asm "callee" for a call site positon.
3370 static bool requiresNonAsmForCallBase() { return true; }
3371
3372 /// Return true if this AA requires all callees for an argument or function
3373 /// positon.
3374 static bool requiresCallersForArgOrFunction() { return false; }
3375
3376 /// Return false if an AA should not be created for \p IRP.
3378 return true;
3379 }
3380
3381 /// Return false if an AA should not be updated for \p IRP.
3383 if (!IRP.isFnInterfaceKind())
3384 return true;
3385 Function *AssociatedFn = IRP.getAssociatedFunction();
3386 assert(AssociatedFn && "Function interface without a function?");
3387
3388 // TODO: Not all attributes require an exact definition. Find a way to
3389 // enable deduction for some but not all attributes in case the
3390 // definition might be changed at runtime, see also
3391 // http://lists.llvm.org/pipermail/llvm-dev/2018-February/121275.html.
3392 // TODO: We could always determine abstract attributes and if sufficient
3393 // information was found we could duplicate the functions that do not
3394 // have an exact definition.
3395 return A.isFunctionIPOAmendable(*AssociatedFn);
3396 }
3397
3398 /// Initialize the state with the information in the Attributor \p A.
3399 ///
3400 /// This function is called by the Attributor once all abstract attributes
3401 /// have been identified. It can and shall be used for task like:
3402 /// - identify existing knowledge in the IR and use it for the "known state"
3403 /// - perform any work that is not going to change over time, e.g., determine
3404 /// a subset of the IR, or attributes in-flight, that have to be looked at
3405 /// in the `updateImpl` method.
3406 virtual void initialize(Attributor &A) {}
3407
3408 /// A query AA is always scheduled as long as we do updates because it does
3409 /// lazy computation that cannot be determined to be done from the outside.
3410 /// However, while query AAs will not be fixed if they do not have outstanding
3411 /// dependences, we will only schedule them like other AAs. If a query AA that
3412 /// received a new query it needs to request an update via
3413 /// `Attributor::requestUpdateForAA`.
3414 virtual bool isQueryAA() const { return false; }
3415
3416 /// Return the internal abstract state for inspection.
3417 virtual StateType &getState() = 0;
3418 virtual const StateType &getState() const = 0;
3419
3420 /// Return true if the state is at a fixpoint, like
3421 /// getState().isAtFixpoint() but with a single virtual call.
3422 virtual bool isStateAtFixpoint() const { return getState().isAtFixpoint(); }
3423
3424 /// Return an IR position, see struct IRPosition.
3425 const IRPosition &getIRPosition() const { return *this; };
3426 IRPosition &getIRPosition() { return *this; };
3427
3428 /// Helper functions, for debug purposes only.
3429 ///{
3430 void print(raw_ostream &OS) const { print(nullptr, OS); }
3431 void print(Attributor *, raw_ostream &OS) const override;
3432 virtual void printWithDeps(raw_ostream &OS) const;
3433 void dump() const { this->print(dbgs()); }
3434
3435 /// This function should return the "summarized" assumed state as string.
3436 virtual const std::string getAsStr(Attributor *A) const = 0;
3437
3438 /// This function should return the name of the AbstractAttribute
3439 virtual StringRef getName() const = 0;
3440
3441 /// This function should return the address of the ID of the AbstractAttribute
3442 virtual const char *getIdAddr() const = 0;
3443 ///}
3444
3445 /// Allow the Attributor access to the protected methods.
3446 friend struct Attributor;
3447
3448protected:
3449 /// Hook for the Attributor to trigger an update of the internal state.
3450 ///
3451 /// If this attribute is already fixed, this method will return UNCHANGED,
3452 /// otherwise it delegates to `AbstractAttribute::updateImpl`.
3453 ///
3454 /// \Return CHANGED if the internal state changed, otherwise UNCHANGED.
3456
3457 /// Hook for the Attributor to trigger the manifestation of the information
3458 /// represented by the abstract attribute in the LLVM-IR.
3459 ///
3460 /// \Return CHANGED if the IR was altered, otherwise UNCHANGED.
3464
3465 /// Hook to enable custom statistic tracking, called after manifest that
3466 /// resulted in a change if statistics are enabled.
3467 ///
3468 /// We require subclasses to provide an implementation so we remember to
3469 /// add statistics for them.
3470 virtual void trackStatistics() const = 0;
3471
3472 /// The actual update/transfer function which has to be implemented by the
3473 /// derived classes.
3474 ///
3475 /// If it is called, the environment has changed and we have to determine if
3476 /// the current information is still valid or adjust it otherwise.
3477 ///
3478 /// \Return CHANGED if the internal state changed, otherwise UNCHANGED.
3480};
3481
3482/// Forward declarations of output streams for debug purposes.
3483///
3484///{
3490template <typename base_ty, base_ty BestState, base_ty WorstState>
3494 return OS << "(" << S.getKnown() << "-" << S.getAssumed() << ")"
3495 << static_cast<const AbstractState &>(S);
3496}
3497LLVM_ABI raw_ostream &operator<<(raw_ostream &OS,
3498 const IntegerRangeState &State);
3499///}
3500
3509
3510/// A more lightweight version of the Attributor which only runs attribute
3511/// inference but no simplifications.
3512struct AttributorLightPass : public OptionalPassInfoMixin<AttributorLightPass> {
3514};
3515
3516/// A more lightweight version of the Attributor which only runs attribute
3517/// inference but no simplifications.
3519 : public OptionalPassInfoMixin<AttributorLightCGSCCPass> {
3522 CGSCCUpdateResult &UR);
3523};
3524
3525/// Helper function to clamp a state \p S of type \p StateType with the
3526/// information in \p R and indicate/return if \p S did change (as-in update is
3527/// required to be run again).
3528template <typename StateType>
3529ChangeStatus clampStateAndIndicateChange(StateType &S, const StateType &R) {
3530 auto Assumed = S.getAssumed();
3531 S ^= R;
3532 return Assumed == S.getAssumed() ? ChangeStatus::UNCHANGED
3534}
3535
3536/// ----------------------------------------------------------------------------
3537/// Abstract Attribute Classes
3538/// ----------------------------------------------------------------------------
3539
3541 : public IRAttribute<Attribute::NoUnwind,
3542 StateWrapper<BooleanState, AbstractAttribute>,
3543 AANoUnwind> {
3545
3546 /// Returns true if nounwind is assumed.
3547 bool isAssumedNoUnwind() const { return getAssumed(); }
3548
3549 /// Returns true if nounwind is known.
3550 bool isKnownNoUnwind() const { return getKnown(); }
3551
3552 /// Create an abstract attribute view for the position \p IRP.
3554 Attributor &A);
3555
3556 StringRef getName() const override { return "AANoUnwind"; }
3557
3558 const char *getIdAddr() const override { return &ID; }
3559
3560 /// This function should return true if the type of the \p AA is AANoUnwind
3561 static bool classof(const AbstractAttribute *AA) {
3562 return (AA->getIdAddr() == &ID);
3563 }
3564
3565 /// Unique ID (due to the unique address)
3566 LLVM_ABI static const char ID;
3567};
3568
3570 : public IRAttribute<Attribute::NoSync,
3571 StateWrapper<BooleanState, AbstractAttribute>,
3572 AANoSync> {
3574
3575 static bool isImpliedByIR(Attributor &A, const IRPosition &IRP,
3576 Attribute::AttrKind ImpliedAttributeKind,
3577 bool IgnoreSubsumingPositions = false) {
3578 // Note: This is also run for non-IPO amendable functions.
3579 assert(ImpliedAttributeKind == Attribute::NoSync);
3580 if (A.hasAttr(IRP, {Attribute::NoSync}, IgnoreSubsumingPositions,
3581 Attribute::NoSync))
3582 return true;
3583
3584 // Check for readonly + non-convergent.
3585 // TODO: We should be able to use hasAttr for Attributes, not only
3586 // AttrKinds.
3588 if (!F || F->isConvergent())
3589 return false;
3590
3592 A.getAttrs(IRP, {Attribute::Memory}, Attrs, IgnoreSubsumingPositions);
3593
3595 for (const Attribute &Attr : Attrs)
3596 ME &= Attr.getMemoryEffects();
3597
3598 if (!ME.onlyReadsMemory())
3599 return false;
3600
3601 A.manifestAttrs(IRP, Attribute::get(F->getContext(), Attribute::NoSync));
3602 return true;
3603 }
3604
3606 if (!IRP.isFunctionScope() &&
3608 return false;
3609 return IRAttribute::isValidIRPositionForInit(A, IRP);
3610 }
3611
3612 /// Returns true if "nosync" is assumed.
3613 bool isAssumedNoSync() const { return getAssumed(); }
3614
3615 /// Returns true if "nosync" is known.
3616 bool isKnownNoSync() const { return getKnown(); }
3617
3618 /// Helper function used to determine whether an instruction is non-relaxed
3619 /// atomic. In other words, if an atomic instruction does not have unordered
3620 /// or monotonic ordering
3621 LLVM_ABI static bool isNonRelaxedAtomic(const Instruction *I);
3622
3623 /// Helper function to determine if \p CB is an aligned (GPU) barrier. Aligned
3624 /// barriers have to be executed by all threads. The flag \p ExecutedAligned
3625 /// indicates if the call is executed by all threads in a (thread) block in an
3626 /// aligned way. If that is the case, non-aligned barriers are effectively
3627 /// aligned barriers.
3628 LLVM_ABI static bool isAlignedBarrier(const CallBase &CB,
3629 bool ExecutedAligned);
3630
3631 /// Create an abstract attribute view for the position \p IRP.
3633 Attributor &A);
3634
3635 StringRef getName() const override { return "AANoSync"; }
3636
3637 const char *getIdAddr() const override { return &ID; }
3638
3639 /// This function should return true if the type of the \p AA is AANoSync
3640 static bool classof(const AbstractAttribute *AA) {
3641 return (AA->getIdAddr() == &ID);
3642 }
3643
3644 /// Unique ID (due to the unique address)
3645 LLVM_ABI static const char ID;
3646};
3647
3648/// An abstract interface for all nonnull attributes.
3650 : public IRAttribute<Attribute::MustProgress,
3651 StateWrapper<BooleanState, AbstractAttribute>,
3652 AAMustProgress> {
3654
3655 static bool isImpliedByIR(Attributor &A, const IRPosition &IRP,
3656 Attribute::AttrKind ImpliedAttributeKind,
3657 bool IgnoreSubsumingPositions = false) {
3658 // Note: This is also run for non-IPO amendable functions.
3659 assert(ImpliedAttributeKind == Attribute::MustProgress);
3660 return A.hasAttr(IRP, {Attribute::MustProgress, Attribute::WillReturn},
3661 IgnoreSubsumingPositions, Attribute::MustProgress);
3662 }
3663
3664 /// Return true if we assume that the underlying value is nonnull.
3665 bool isAssumedMustProgress() const { return getAssumed(); }
3666
3667 /// Return true if we know that underlying value is nonnull.
3668 bool isKnownMustProgress() const { return getKnown(); }
3669
3670 /// Create an abstract attribute view for the position \p IRP.
3672 Attributor &A);
3673
3674 StringRef getName() const override { return "AAMustProgress"; }
3675
3676 const char *getIdAddr() const override { return &ID; }
3677
3678 /// This function should return true if the type of the \p AA is
3679 /// AAMustProgress
3680 static bool classof(const AbstractAttribute *AA) {
3681 return (AA->getIdAddr() == &ID);
3682 }
3683
3684 /// Unique ID (due to the unique address)
3685 LLVM_ABI static const char ID;
3686};
3687
3688/// An abstract interface for all nonnull attributes.
3690 : public IRAttribute<Attribute::NonNull,
3691 StateWrapper<BooleanState, AbstractAttribute>,
3692 AANonNull> {
3694
3695 static bool hasTrivialInitializer() { return false; }
3696
3697 /// Undef is not necessarily nonnull as nonnull + noundef would cause poison.
3698 /// Poison implies nonnull though.
3699 static bool isImpliedByUndef() { return false; }
3700
3703 return false;
3704 return IRAttribute::isValidIRPositionForInit(A, IRP);
3705 }
3706
3707 LLVM_ABI static bool isImpliedByIR(Attributor &A, const IRPosition &IRP,
3708 Attribute::AttrKind ImpliedAttributeKind,
3709 bool IgnoreSubsumingPositions = false);
3710
3711 /// Return true if we assume that the underlying value is nonnull.
3712 bool isAssumedNonNull() const { return getAssumed(); }
3713
3714 /// Return true if we know that underlying value is nonnull.
3715 bool isKnownNonNull() const { return getKnown(); }
3716
3717 /// Create an abstract attribute view for the position \p IRP.
3719 Attributor &A);
3720
3721 StringRef getName() const override { return "AANonNull"; }
3722
3723 const char *getIdAddr() const override { return &ID; }
3724
3725 /// This function should return true if the type of the \p AA is AANonNull
3726 static bool classof(const AbstractAttribute *AA) {
3727 return (AA->getIdAddr() == &ID);
3728 }
3729
3730 /// Unique ID (due to the unique address)
3731 LLVM_ABI static const char ID;
3732};
3733
3734/// An abstract attribute for norecurse.
3736 : public IRAttribute<Attribute::NoRecurse,
3737 StateWrapper<BooleanState, AbstractAttribute>,
3738 AANoRecurse> {
3740
3741 /// Return true if "norecurse" is assumed.
3742 bool isAssumedNoRecurse() const { return getAssumed(); }
3743
3744 /// Return true if "norecurse" is known.
3745 bool isKnownNoRecurse() const { return getKnown(); }
3746
3747 /// Create an abstract attribute view for the position \p IRP.
3749 Attributor &A);
3750
3751 StringRef getName() const override { return "AANoRecurse"; }
3752
3753 const char *getIdAddr() const override { return &ID; }
3754
3755 /// This function should return true if the type of the \p AA is AANoRecurse
3756 static bool classof(const AbstractAttribute *AA) {
3757 return (AA->getIdAddr() == &ID);
3758 }
3759
3760 /// Unique ID (due to the unique address)
3761 LLVM_ABI static const char ID;
3762};
3763
3764/// An abstract attribute for willreturn.
3766 : public IRAttribute<Attribute::WillReturn,
3767 StateWrapper<BooleanState, AbstractAttribute>,
3768 AAWillReturn> {
3770
3771 static bool isImpliedByIR(Attributor &A, const IRPosition &IRP,
3772 Attribute::AttrKind ImpliedAttributeKind,
3773 bool IgnoreSubsumingPositions = false) {
3774 // Note: This is also run for non-IPO amendable functions.
3775 assert(ImpliedAttributeKind == Attribute::WillReturn);
3776 if (IRAttribute::isImpliedByIR(A, IRP, ImpliedAttributeKind,
3777 IgnoreSubsumingPositions))
3778 return true;
3780 return false;
3781 A.manifestAttrs(IRP, Attribute::get(IRP.getAnchorValue().getContext(),
3782 Attribute::WillReturn));
3783 return true;
3784 }
3785
3786 /// Check for `mustprogress` and `readonly` as they imply `willreturn`.
3788 const IRPosition &IRP) {
3789 // Check for `mustprogress` in the scope and the associated function which
3790 // might be different if this is a call site.
3791 if (!A.hasAttr(IRP, {Attribute::MustProgress}))
3792 return false;
3793
3795 A.getAttrs(IRP, {Attribute::Memory}, Attrs,
3796 /* IgnoreSubsumingPositions */ false);
3797
3799 for (const Attribute &Attr : Attrs)
3800 ME &= Attr.getMemoryEffects();
3801 return ME.onlyReadsMemory();
3802 }
3803
3804 /// Return true if "willreturn" is assumed.
3805 bool isAssumedWillReturn() const { return getAssumed(); }
3806
3807 /// Return true if "willreturn" is known.
3808 bool isKnownWillReturn() const { return getKnown(); }
3809
3810 /// Create an abstract attribute view for the position \p IRP.
3812 Attributor &A);
3813
3814 StringRef getName() const override { return "AAWillReturn"; }
3815
3816 const char *getIdAddr() const override { return &ID; }
3817
3818 /// This function should return true if the type of the \p AA is AAWillReturn
3819 static bool classof(const AbstractAttribute *AA) {
3820 return (AA->getIdAddr() == &ID);
3821 }
3822
3823 /// Unique ID (due to the unique address)
3824 LLVM_ABI static const char ID;
3825};
3826
3827/// An abstract attribute for undefined behavior.
3829 : public StateWrapper<BooleanState, AbstractAttribute> {
3832
3833 /// Return true if "undefined behavior" is assumed for a specific instruction.
3834 virtual bool isAssumedToCauseUB(Instruction *I) const = 0;
3835
3836 /// Return true if "undefined behavior" is known for a specific instruction.
3837 virtual bool isKnownToCauseUB(Instruction *I) const = 0;
3838
3839 /// Create an abstract attribute view for the position \p IRP.
3841 Attributor &A);
3842
3843 StringRef getName() const override { return "AAUndefinedBehavior"; }
3844
3845 const char *getIdAddr() const override { return &ID; }
3846
3847 /// This function should return true if the type of the \p AA is
3848 /// AAUndefineBehavior
3849 static bool classof(const AbstractAttribute *AA) {
3850 return (AA->getIdAddr() == &ID);
3851 }
3852
3853 /// Unique ID (due to the unique address)
3854 LLVM_ABI static const char ID;
3855};
3856
3857/// An abstract interface to determine reachability of point A to B.
3859 : public StateWrapper<BooleanState, AbstractAttribute> {
3862
3863 /// Returns true if 'From' instruction is assumed to reach, 'To' instruction.
3864 /// Users should provide two positions they are interested in, and the class
3865 /// determines (and caches) reachability.
3867 Attributor &A, const Instruction &From, const Instruction &To,
3868 const AA::InstExclusionSetTy *ExclusionSet = nullptr) const = 0;
3869
3870 /// Create an abstract attribute view for the position \p IRP.
3873
3874 StringRef getName() const override { return "AAIntraFnReachability"; }
3875
3876 const char *getIdAddr() const override { return &ID; }
3877
3878 /// This function should return true if the type of the \p AA is
3879 /// AAIntraFnReachability
3880 static bool classof(const AbstractAttribute *AA) {
3881 return (AA->getIdAddr() == &ID);
3882 }
3883
3884 /// Unique ID (due to the unique address)
3885 LLVM_ABI static const char ID;
3886};
3887
3888/// An abstract interface for all noalias attributes.
3890 : public IRAttribute<Attribute::NoAlias,
3891 StateWrapper<BooleanState, AbstractAttribute>,
3892 AANoAlias> {
3894
3896 if (!IRP.getAssociatedType()->isPointerTy())
3897 return false;
3898 return IRAttribute::isValidIRPositionForInit(A, IRP);
3899 }
3900
3901 LLVM_ABI static bool isImpliedByIR(Attributor &A, const IRPosition &IRP,
3902 Attribute::AttrKind ImpliedAttributeKind,
3903 bool IgnoreSubsumingPositions = false);
3904
3905 static bool requiresCallersForArgOrFunction() { return true; }
3906
3907 /// Return true if we assume that the underlying value is alias.
3908 bool isAssumedNoAlias() const { return getAssumed(); }
3909
3910 /// Return true if we know that underlying value is noalias.
3911 bool isKnownNoAlias() const { return getKnown(); }
3912
3913 /// Create an abstract attribute view for the position \p IRP.
3915 Attributor &A);
3916
3917 StringRef getName() const override { return "AANoAlias"; }
3918
3919 const char *getIdAddr() const override { return &ID; }
3920
3921 /// This function should return true if the type of the \p AA is AANoAlias
3922 static bool classof(const AbstractAttribute *AA) {
3923 return (AA->getIdAddr() == &ID);
3924 }
3925
3926 /// Unique ID (due to the unique address)
3927 LLVM_ABI static const char ID;
3928};
3929
3930/// An AbstractAttribute for nofree.
3932 : public IRAttribute<Attribute::NoFree,
3933 StateWrapper<BooleanState, AbstractAttribute>,
3934 AANoFree> {
3936
3937 static bool isImpliedByIR(Attributor &A, const IRPosition &IRP,
3938 Attribute::AttrKind ImpliedAttributeKind,
3939 bool IgnoreSubsumingPositions = false) {
3940 // Note: This is also run for non-IPO amendable functions.
3941 assert(ImpliedAttributeKind == Attribute::NoFree);
3942 return A.hasAttr(
3943 IRP, {Attribute::ReadNone, Attribute::ReadOnly, Attribute::NoFree},
3944 IgnoreSubsumingPositions, Attribute::NoFree);
3945 }
3946
3948 if (!IRP.isFunctionScope() &&
3950 return false;
3951 return IRAttribute::isValidIRPositionForInit(A, IRP);
3952 }
3953
3954 /// Return true if "nofree" is assumed.
3955 bool isAssumedNoFree() const { return getAssumed(); }
3956
3957 /// Return true if "nofree" is known.
3958 bool isKnownNoFree() const { return getKnown(); }
3959
3960 /// Create an abstract attribute view for the position \p IRP.
3962 Attributor &A);
3963
3964 StringRef getName() const override { return "AANoFree"; }
3965
3966 const char *getIdAddr() const override { return &ID; }
3967
3968 /// This function should return true if the type of the \p AA is AANoFree
3969 static bool classof(const AbstractAttribute *AA) {
3970 return (AA->getIdAddr() == &ID);
3971 }
3972
3973 /// Unique ID (due to the unique address)
3974 LLVM_ABI static const char ID;
3975};
3976
3977/// An AbstractAttribute for noreturn.
3979 : public IRAttribute<Attribute::NoReturn,
3980 StateWrapper<BooleanState, AbstractAttribute>,
3981 AANoReturn> {
3983
3984 /// Return true if the underlying object is assumed to never return.
3985 bool isAssumedNoReturn() const { return getAssumed(); }
3986
3987 /// Return true if the underlying object is known to never return.
3988 bool isKnownNoReturn() const { return getKnown(); }
3989
3990 /// Create an abstract attribute view for the position \p IRP.
3992 Attributor &A);
3993
3994 StringRef getName() const override { return "AANoReturn"; }
3995
3996 const char *getIdAddr() const override { return &ID; }
3997
3998 /// This function should return true if the type of the \p AA is AANoReturn
3999 static bool classof(const AbstractAttribute *AA) {
4000 return (AA->getIdAddr() == &ID);
4001 }
4002
4003 /// Unique ID (due to the unique address)
4004 LLVM_ABI static const char ID;
4005};
4006
4007/// An abstract interface for liveness abstract attribute.
4009 : public StateWrapper<BitIntegerState<uint8_t, 3, 0>, AbstractAttribute> {
4011 AAIsDead(const IRPosition &IRP, Attributor &A) : Base(IRP) {}
4012
4015 return isa<Function>(IRP.getAnchorValue()) &&
4016 !cast<Function>(IRP.getAnchorValue()).isDeclaration();
4017 return true;
4018 }
4019
4020 /// State encoding bits. A set bit in the state means the property holds.
4021 enum {
4024
4026 };
4027 static_assert(IS_DEAD == getBestState(), "Unexpected BEST_STATE value");
4028
4029protected:
4030 /// The query functions are protected such that other attributes need to go
4031 /// through the Attributor interfaces: `Attributor::isAssumedDead(...)`
4032
4033 /// Returns true if the underlying value is assumed dead.
4034 virtual bool isAssumedDead() const = 0;
4035
4036 /// Returns true if the underlying value is known dead.
4037 virtual bool isKnownDead() const = 0;
4038
4039 /// Returns true if \p BB is known dead.
4040 virtual bool isKnownDead(const BasicBlock *BB) const = 0;
4041
4042 /// Returns true if \p I is assumed dead.
4043 virtual bool isAssumedDead(const Instruction *I) const = 0;
4044
4045 /// Returns true if \p I is known dead.
4046 virtual bool isKnownDead(const Instruction *I) const = 0;
4047
4048 /// Return true if the underlying value is a store that is known to be
4049 /// removable. This is different from dead stores as the removable store
4050 /// can have an effect on live values, especially loads, but that effect
4051 /// is propagated which allows us to remove the store in turn.
4052 virtual bool isRemovableStore() const { return false; }
4053
4054public:
4055 /// Create an abstract attribute view for the position \p IRP.
4057 Attributor &A);
4058
4059 /// Determine if \p F might catch asynchronous exceptions.
4061 return F.hasPersonalityFn() && !canSimplifyInvokeNoUnwind(&F);
4062 }
4063
4064 /// Returns true if \p BB is assumed dead.
4065 virtual bool isAssumedDead(const BasicBlock *BB) const = 0;
4066
4067 /// Return if the edge from \p From BB to \p To BB is assumed dead.
4068 /// This is specifically useful in AAReachability.
4069 virtual bool isEdgeDead(const BasicBlock *From, const BasicBlock *To) const {
4070 return false;
4071 }
4072
4073 StringRef getName() const override { return "AAIsDead"; }
4074
4075 const char *getIdAddr() const override { return &ID; }
4076
4077 /// This function should return true if the type of the \p AA is AAIsDead
4078 static bool classof(const AbstractAttribute *AA) {
4079 return (AA->getIdAddr() == &ID);
4080 }
4081
4082 /// Unique ID (due to the unique address)
4083 LLVM_ABI static const char ID;
4084
4085 friend struct Attributor;
4086};
4087
4088/// State for dereferenceable attribute
4090
4091 static DerefState getBestState() { return DerefState(); }
4092 static DerefState getBestState(const DerefState &) { return getBestState(); }
4093
4094 /// Return the worst possible representable state.
4096 DerefState DS;
4097 DS.indicatePessimisticFixpoint();
4098 return DS;
4099 }
4101 return getWorstState();
4102 }
4103
4104 /// State representing for dereferenceable bytes.
4106
4107 /// Map representing for accessed memory offsets and sizes.
4108 /// A key is Offset and a value is size.
4109 /// If there is a load/store instruction something like,
4110 /// p[offset] = v;
4111 /// (offset, sizeof(v)) will be inserted to this map.
4112 /// std::map is used because we want to iterate keys in ascending order.
4113 std::map<int64_t, uint64_t> AccessedBytesMap;
4114
4115 /// Helper function to calculate dereferenceable bytes from current known
4116 /// bytes and accessed bytes.
4117 ///
4118 /// int f(int *A){
4119 /// *A = 0;
4120 /// *(A+2) = 2;
4121 /// *(A+1) = 1;
4122 /// *(A+10) = 10;
4123 /// }
4124 /// ```
4125 /// In that case, AccessedBytesMap is `{0:4, 4:4, 8:4, 40:4}`.
4126 /// AccessedBytesMap is std::map so it is iterated in accending order on
4127 /// key(Offset). So KnownBytes will be updated like this:
4128 ///
4129 /// |Access | KnownBytes
4130 /// |(0, 4)| 0 -> 4
4131 /// |(4, 4)| 4 -> 8
4132 /// |(8, 4)| 8 -> 12
4133 /// |(40, 4) | 12 (break)
4134 void computeKnownDerefBytesFromAccessedMap() {
4135 int64_t KnownBytes = DerefBytesState.getKnown();
4136 for (auto &Access : AccessedBytesMap) {
4137 if (KnownBytes < Access.first)
4138 break;
4139 KnownBytes = std::max(KnownBytes, Access.first + (int64_t)Access.second);
4140 }
4141
4142 DerefBytesState.takeKnownMaximum(KnownBytes);
4143 }
4144
4145 /// State representing that whether the value is globaly dereferenceable.
4146 BooleanState GlobalState;
4147
4148 bool isValidState() const override { return DerefBytesState.isValidState(); }
4149
4150 bool isAtFixpoint() const override {
4151 return !isValidState() ||
4152 (DerefBytesState.isAtFixpoint() && GlobalState.isAtFixpoint());
4153 }
4154
4156 DerefBytesState.indicateOptimisticFixpoint();
4157 GlobalState.indicateOptimisticFixpoint();
4159 }
4160
4162 DerefBytesState.indicatePessimisticFixpoint();
4163 GlobalState.indicatePessimisticFixpoint();
4164 return ChangeStatus::CHANGED;
4165 }
4166
4167 /// Update known dereferenceable bytes.
4168 void takeKnownDerefBytesMaximum(uint64_t Bytes) {
4169 DerefBytesState.takeKnownMaximum(Bytes);
4170
4171 // Known bytes might increase.
4172 computeKnownDerefBytesFromAccessedMap();
4173 }
4174
4175 /// Update assumed dereferenceable bytes.
4176 void takeAssumedDerefBytesMinimum(uint64_t Bytes) {
4177 DerefBytesState.takeAssumedMinimum(Bytes);
4178 }
4179
4180 /// Add accessed bytes to the map.
4181 void addAccessedBytes(int64_t Offset, uint64_t Size) {
4182 uint64_t &AccessedBytes = AccessedBytesMap[Offset];
4183 AccessedBytes = std::max(AccessedBytes, Size);
4184
4185 // Known bytes might increase.
4186 computeKnownDerefBytesFromAccessedMap();
4187 }
4188
4189 /// Equality for DerefState.
4190 bool operator==(const DerefState &R) const {
4191 return this->DerefBytesState == R.DerefBytesState &&
4192 this->GlobalState == R.GlobalState;
4193 }
4194
4195 /// Inequality for DerefState.
4196 bool operator!=(const DerefState &R) const { return !(*this == R); }
4197
4198 /// See IntegerStateBase::operator^=
4199 DerefState operator^=(const DerefState &R) {
4200 DerefBytesState ^= R.DerefBytesState;
4201 GlobalState ^= R.GlobalState;
4202 return *this;
4203 }
4204
4205 /// See IntegerStateBase::operator+=
4206 DerefState operator+=(const DerefState &R) {
4207 DerefBytesState += R.DerefBytesState;
4208 GlobalState += R.GlobalState;
4209 return *this;
4210 }
4211
4212 /// See IntegerStateBase::operator&=
4213 DerefState operator&=(const DerefState &R) {
4214 DerefBytesState &= R.DerefBytesState;
4215 GlobalState &= R.GlobalState;
4216 return *this;
4217 }
4218
4219 /// See IntegerStateBase::operator|=
4220 DerefState operator|=(const DerefState &R) {
4221 DerefBytesState |= R.DerefBytesState;
4222 GlobalState |= R.GlobalState;
4223 return *this;
4224 }
4225};
4226
4227/// An abstract interface for all dereferenceable attribute.
4229 : public IRAttribute<Attribute::Dereferenceable,
4230 StateWrapper<DerefState, AbstractAttribute>,
4231 AADereferenceable> {
4233
4235 if (!IRP.getAssociatedType()->isPointerTy())
4236 return false;
4237 return IRAttribute::isValidIRPositionForInit(A, IRP);
4238 }
4239
4240 /// Return true if we assume that underlying value is
4241 /// dereferenceable(_or_null) globally.
4242 bool isAssumedGlobal() const { return GlobalState.getAssumed(); }
4243
4244 /// Return true if we know that underlying value is
4245 /// dereferenceable(_or_null) globally.
4246 bool isKnownGlobal() const { return GlobalState.getKnown(); }
4247
4248 /// Return assumed dereferenceable bytes.
4250 return DerefBytesState.getAssumed();
4251 }
4252
4253 /// Return known dereferenceable bytes.
4255 return DerefBytesState.getKnown();
4256 }
4257
4258 /// Create an abstract attribute view for the position \p IRP.
4260 Attributor &A);
4261
4262 StringRef getName() const override { return "AADereferenceable"; }
4263
4264 const char *getIdAddr() const override { return &ID; }
4265
4266 /// This function should return true if the type of the \p AA is
4267 /// AADereferenceable
4268 static bool classof(const AbstractAttribute *AA) {
4269 return (AA->getIdAddr() == &ID);
4270 }
4271
4272 /// Unique ID (due to the unique address)
4273 LLVM_ABI static const char ID;
4274};
4275
4278/// An abstract interface for all align attributes.
4280 : public IRAttribute<Attribute::Alignment,
4281 StateWrapper<AAAlignmentStateType, AbstractAttribute>,
4282 AAAlign> {
4284
4287 return false;
4288 return IRAttribute::isValidIRPositionForInit(A, IRP);
4289 }
4290
4291 /// Return assumed alignment.
4292 Align getAssumedAlign() const { return Align(getAssumed()); }
4293
4294 /// Return known alignment.
4295 Align getKnownAlign() const { return Align(getKnown()); }
4296
4297 StringRef getName() const override { return "AAAlign"; }
4298
4299 const char *getIdAddr() const override { return &ID; }
4300
4301 /// This function should return true if the type of the \p AA is AAAlign
4302 static bool classof(const AbstractAttribute *AA) {
4303 return (AA->getIdAddr() == &ID);
4304 }
4305
4306 /// Create an abstract attribute view for the position \p IRP.
4308 Attributor &A);
4309
4310 /// Unique ID (due to the unique address)
4311 LLVM_ABI static const char ID;
4312};
4313
4314/// An abstract interface to track if a value leaves it's defining function
4315/// instance.
4316/// TODO: We should make it a ternary AA tracking uniqueness, and uniqueness
4317/// wrt. the Attributor analysis separately.
4318struct AAInstanceInfo : public StateWrapper<BooleanState, AbstractAttribute> {
4321
4322 /// Return true if we assume that the underlying value is unique in its scope
4323 /// wrt. the Attributor analysis. That means it might not be unique but we can
4324 /// still use pointer equality without risking to represent two instances with
4325 /// one `llvm::Value`.
4326 bool isAssumedUniqueForAnalysis() const { return isAssumed(); }
4327
4328 /// Create an abstract attribute view for the position \p IRP.
4330 Attributor &A);
4331
4332 StringRef getName() const override { return "AAInstanceInfo"; }
4333
4334 const char *getIdAddr() const override { return &ID; }
4335
4336 /// This function should return true if the type of the \p AA is
4337 /// AAInstanceInfo
4338 static bool classof(const AbstractAttribute *AA) {
4339 return (AA->getIdAddr() == &ID);
4340 }
4341
4342 /// Unique ID (due to the unique address)
4343 LLVM_ABI static const char ID;
4344};
4345
4346/// An abstract interface for all nocapture attributes.
4348 : public IRAttribute<
4349 Attribute::Captures,
4350 StateWrapper<BitIntegerState<uint16_t, 7, 0>, AbstractAttribute>,
4351 AANoCapture> {
4353
4354 LLVM_ABI static bool isImpliedByIR(Attributor &A, const IRPosition &IRP,
4355 Attribute::AttrKind ImpliedAttributeKind,
4356 bool IgnoreSubsumingPositions = false);
4357
4358 /// Update \p State according to the capture capabilities of \p F for position
4359 /// \p IRP.
4360 LLVM_ABI static void
4362 BitIntegerState &State);
4363
4365 if (!IRP.getAssociatedType()->isPointerTy())
4366 return false;
4367 return IRAttribute::isValidIRPositionForInit(A, IRP);
4368 }
4369
4370 /// State encoding bits. A set bit in the state means the property holds.
4371 /// NO_CAPTURE is the best possible state, 0 the worst possible state.
4372 enum {
4376
4377 /// If we do not capture the value in memory or through integers we can only
4378 /// communicate it back as a derived pointer.
4380
4381 /// If we do not capture the value in memory, through integers, or as a
4382 /// derived pointer we know it is not captured.
4385 };
4386
4387 /// Return true if we know that the underlying value is not captured in its
4388 /// respective scope.
4389 bool isKnownNoCapture() const { return isKnown(NO_CAPTURE); }
4390
4391 /// Return true if we assume that the underlying value is not captured in its
4392 /// respective scope.
4393 bool isAssumedNoCapture() const { return isAssumed(NO_CAPTURE); }
4394
4395 /// Return true if we know that the underlying value is not captured in its
4396 /// respective scope but we allow it to escape through a "return".
4400
4401 /// Return true if we assume that the underlying value is not captured in its
4402 /// respective scope but we allow it to escape through a "return".
4406
4407 /// Create an abstract attribute view for the position \p IRP.
4409 Attributor &A);
4410
4411 StringRef getName() const override { return "AANoCapture"; }
4412
4413 const char *getIdAddr() const override { return &ID; }
4414
4415 /// This function should return true if the type of the \p AA is AANoCapture
4416 static bool classof(const AbstractAttribute *AA) {
4417 return (AA->getIdAddr() == &ID);
4418 }
4419
4420 /// Unique ID (due to the unique address)
4421 LLVM_ABI static const char ID;
4422};
4423
4425
4427
4432 return getBestState(VS.Ty);
4433 }
4434
4435 /// Return the worst possible representable state.
4438 DS.indicatePessimisticFixpoint();
4439 return DS;
4440 }
4443 return getWorstState(VS.Ty);
4444 }
4445
4446 bool isValidState() const override { return BS.isValidState(); }
4447
4448 bool isAtFixpoint() const override { return BS.isAtFixpoint(); }
4449
4450 /// Return the assumed state encoding.
4452 const ValueSimplifyStateType &getAssumed() const { return *this; }
4453
4455 return BS.indicatePessimisticFixpoint();
4456 }
4457
4459 return BS.indicateOptimisticFixpoint();
4460 }
4461
4462 /// "Clamp" this state with \p PVS.
4464 BS ^= VS.BS;
4465 unionAssumed(VS.SimplifiedAssociatedValue);
4466 return *this;
4467 }
4468
4470 if (isValidState() != RHS.isValidState())
4471 return false;
4472 if (!isValidState() && !RHS.isValidState())
4473 return true;
4474 return SimplifiedAssociatedValue == RHS.SimplifiedAssociatedValue;
4475 }
4476
4477protected:
4478 /// The type of the original value.
4480
4481 /// Merge \p Other into the currently assumed simplified value
4482 LLVM_ABI bool unionAssumed(std::optional<Value *> Other);
4483
4484 /// Helper to track validity and fixpoint
4486
4487 /// An assumed simplified value. Initially, it is set to std::nullopt, which
4488 /// means that the value is not clear under current assumption. If in the
4489 /// pessimistic state, getAssumedSimplifiedValue doesn't return this value but
4490 /// returns orignal associated value.
4491 std::optional<Value *> SimplifiedAssociatedValue;
4492};
4493
4494/// An abstract interface for value simplify abstract attribute.
4496 : public StateWrapper<ValueSimplifyStateType, AbstractAttribute, Type *> {
4499 : Base(IRP, IRP.getAssociatedType()) {}
4500
4501 /// Create an abstract attribute view for the position \p IRP.
4503 Attributor &A);
4504
4505 StringRef getName() const override { return "AAValueSimplify"; }
4506
4507 const char *getIdAddr() const override { return &ID; }
4508
4509 /// This function should return true if the type of the \p AA is
4510 /// AAValueSimplify
4511 static bool classof(const AbstractAttribute *AA) {
4512 return (AA->getIdAddr() == &ID);
4513 }
4514
4515 /// Unique ID (due to the unique address)
4516 LLVM_ABI static const char ID;
4517
4518private:
4519 /// Return an assumed simplified value if a single candidate is found. If
4520 /// there cannot be one, return original value. If it is not clear yet, return
4521 /// std::nullopt.
4522 ///
4523 /// Use `Attributor::getAssumedSimplified` for value simplification.
4524 virtual std::optional<Value *>
4525 getAssumedSimplifiedValue(Attributor &A) const = 0;
4526
4527 friend struct Attributor;
4528};
4529
4530struct AAHeapToStack : public StateWrapper<BooleanState, AbstractAttribute> {
4532 AAHeapToStack(const IRPosition &IRP, Attributor &A) : Base(IRP) {}
4533
4534 /// Returns true if HeapToStack conversion is assumed to be possible.
4535 virtual bool isAssumedHeapToStack(const CallBase &CB) const = 0;
4536
4537 /// Returns true if HeapToStack conversion is assumed and the CB is a
4538 /// callsite to a free operation to be removed.
4539 virtual bool isAssumedHeapToStackRemovedFree(CallBase &CB) const = 0;
4540
4541 /// Create an abstract attribute view for the position \p IRP.
4543 Attributor &A);
4544
4545 StringRef getName() const override { return "AAHeapToStack"; }
4546
4547 const char *getIdAddr() const override { return &ID; }
4548
4549 /// This function should return true if the type of the \p AA is AAHeapToStack
4550 static bool classof(const AbstractAttribute *AA) {
4551 return (AA->getIdAddr() == &ID);
4552 }
4553
4554 /// Unique ID (due to the unique address)
4555 LLVM_ABI static const char ID;
4556};
4557
4558/// An abstract interface for privatizability.
4559///
4560/// A pointer is privatizable if it can be replaced by a new, private one.
4561/// Privatizing pointer reduces the use count, interaction between unrelated
4562/// code parts.
4563///
4564/// In order for a pointer to be privatizable its value cannot be observed
4565/// (=nocapture), it is (for now) not written (=readonly & noalias), we know
4566/// what values are necessary to make the private copy look like the original
4567/// one, and the values we need can be loaded (=dereferenceable).
4569 : public StateWrapper<BooleanState, AbstractAttribute> {
4572
4575 return false;
4577 }
4578
4579 /// Returns true if pointer privatization is assumed to be possible.
4580 bool isAssumedPrivatizablePtr() const { return getAssumed(); }
4581
4582 static bool requiresCallersForArgOrFunction() { return true; }
4583
4584 /// Return the type we can choose for a private copy of the underlying
4585 /// value. std::nullopt means it is not clear yet, nullptr means there is
4586 /// none.
4587 virtual std::optional<Type *> getPrivatizableType() const = 0;
4588
4589 /// Create an abstract attribute view for the position \p IRP.
4591 Attributor &A);
4592
4593 StringRef getName() const override { return "AAPrivatizablePtr"; }
4594
4595 const char *getIdAddr() const override { return &ID; }
4596
4597 /// This function should return true if the type of the \p AA is
4598 /// AAPricatizablePtr
4599 static bool classof(const AbstractAttribute *AA) {
4600 return (AA->getIdAddr() == &ID);
4601 }
4602
4603 /// Unique ID (due to the unique address)
4604 LLVM_ABI static const char ID;
4605};
4606
4607/// An abstract interface for memory access kind related attributes
4608/// (readnone/readonly/writeonly).
4610 : public IRAttribute<
4611 Attribute::None,
4612 StateWrapper<BitIntegerState<uint8_t, 3>, AbstractAttribute>,
4613 AAMemoryBehavior> {
4615
4616 static bool hasTrivialInitializer() { return false; }
4617
4619 if (!IRP.isFunctionScope() && !IRP.getAssociatedType()->isPointerTy())
4620 return false;
4621 return IRAttribute::isValidIRPositionForInit(A, IRP);
4622 }
4623
4624 /// State encoding bits. A set bit in the state means the property holds.
4625 /// BEST_STATE is the best possible state, 0 the worst possible state.
4626 enum {
4627 NO_READS = 1 << 0,
4628 NO_WRITES = 1 << 1,
4630
4632 };
4633 static_assert(BEST_STATE == getBestState(), "Unexpected BEST_STATE value");
4634
4635 /// Return true if we know that the underlying value is not read or accessed
4636 /// in its respective scope.
4637 bool isKnownReadNone() const { return isKnown(NO_ACCESSES); }
4638
4639 /// Return true if we assume that the underlying value is not read or accessed
4640 /// in its respective scope.
4641 bool isAssumedReadNone() const { return isAssumed(NO_ACCESSES); }
4642
4643 /// Return true if we know that the underlying value is not accessed
4644 /// (=written) in its respective scope.
4645 bool isKnownReadOnly() const { return isKnown(NO_WRITES); }
4646
4647 /// Return true if we assume that the underlying value is not accessed
4648 /// (=written) in its respective scope.
4649 bool isAssumedReadOnly() const { return isAssumed(NO_WRITES); }
4650
4651 /// Return true if we know that the underlying value is not read in its
4652 /// respective scope.
4653 bool isKnownWriteOnly() const { return isKnown(NO_READS); }
4654
4655 /// Return true if we assume that the underlying value is not read in its
4656 /// respective scope.
4657 bool isAssumedWriteOnly() const { return isAssumed(NO_READS); }
4658
4659 /// Create an abstract attribute view for the position \p IRP.
4661 Attributor &A);
4662
4663 StringRef getName() const override { return "AAMemoryBehavior"; }
4664
4665 const char *getIdAddr() const override { return &ID; }
4666
4667 /// This function should return true if the type of the \p AA is
4668 /// AAMemoryBehavior
4669 static bool classof(const AbstractAttribute *AA) {
4670 return (AA->getIdAddr() == &ID);
4671 }
4672
4673 /// Unique ID (due to the unique address)
4674 LLVM_ABI static const char ID;
4675};
4676
4677/// An abstract interface for all memory location attributes
4678/// (readnone/argmemonly/inaccessiblememonly/inaccessibleorargmemonly).
4680 : public IRAttribute<
4681 Attribute::None,
4682 StateWrapper<BitIntegerState<uint32_t, 511>, AbstractAttribute>,
4683 AAMemoryLocation> {
4684 using MemoryLocationsKind = StateType::base_t;
4685
4687
4688 static bool requiresCalleeForCallBase() { return true; }
4689
4690 static bool hasTrivialInitializer() { return false; }
4691
4693 if (!IRP.isFunctionScope() &&
4695 return false;
4696 return IRAttribute::isValidIRPositionForInit(A, IRP);
4697 }
4698
4699 /// Encoding of different locations that could be accessed by a memory
4700 /// access.
4701 enum {
4715
4716 // Helper bit to track if we gave up or not.
4718
4720 };
4721 static_assert(BEST_STATE == getBestState(), "Unexpected BEST_STATE value");
4722
4723 /// Return true if we know that the associated functions has no observable
4724 /// accesses.
4725 bool isKnownReadNone() const { return isKnown(NO_LOCATIONS); }
4726
4727 /// Return true if we assume that the associated functions has no observable
4728 /// accesses.
4729 bool isAssumedReadNone() const {
4731 }
4732
4733 /// Return true if we know that the associated functions has at most
4734 /// local/stack accesses.
4735 bool isKnowStackOnly() const {
4736 return isKnown(inverseLocation(NO_LOCAL_MEM, true, true));
4737 }
4738
4739 /// Return true if we assume that the associated functions has at most
4740 /// local/stack accesses.
4741 bool isAssumedStackOnly() const {
4742 return isAssumed(inverseLocation(NO_LOCAL_MEM, true, true));
4743 }
4744
4745 /// Return true if we know that the underlying value will only access
4746 /// inaccesible memory only (see Attribute::InaccessibleMemOnly).
4748 return isKnown(inverseLocation(NO_INACCESSIBLE_MEM, true, true));
4749 }
4750
4751 /// Return true if we assume that the underlying value will only access
4752 /// inaccesible memory only (see Attribute::InaccessibleMemOnly).
4754 return isAssumed(inverseLocation(NO_INACCESSIBLE_MEM, true, true));
4755 }
4756
4757 /// Return true if we know that the underlying value will only access
4758 /// argument pointees (see Attribute::ArgMemOnly).
4759 bool isKnownArgMemOnly() const {
4760 return isKnown(inverseLocation(NO_ARGUMENT_MEM, true, true));
4761 }
4762
4763 /// Return true if we assume that the underlying value will only access
4764 /// argument pointees (see Attribute::ArgMemOnly).
4765 bool isAssumedArgMemOnly() const {
4766 return isAssumed(inverseLocation(NO_ARGUMENT_MEM, true, true));
4767 }
4768
4769 /// Return true if we know that the underlying value will only access
4770 /// inaccesible memory or argument pointees (see
4771 /// Attribute::InaccessibleOrArgMemOnly).
4773 return isKnown(
4775 }
4776
4777 /// Return true if we assume that the underlying value will only access
4778 /// inaccesible memory or argument pointees (see
4779 /// Attribute::InaccessibleOrArgMemOnly).
4784
4785 /// Return true if the underlying value may access memory through arguement
4786 /// pointers of the associated function, if any.
4787 bool mayAccessArgMem() const { return !isAssumed(NO_ARGUMENT_MEM); }
4788
4789 /// Return true if only the memory locations specififed by \p MLK are assumed
4790 /// to be accessed by the associated function.
4792 return isAssumed(MLK);
4793 }
4794
4795 /// Return the locations that are assumed to be not accessed by the associated
4796 /// function, if any.
4800
4801 /// Return the inverse of location \p Loc, thus for NO_XXX the return
4802 /// describes ONLY_XXX. The flags \p AndLocalMem and \p AndConstMem determine
4803 /// if local (=stack) and constant memory are allowed as well. Most of the
4804 /// time we do want them to be included, e.g., argmemonly allows accesses via
4805 /// argument pointers or local or constant memory accesses.
4806 static MemoryLocationsKind
4807 inverseLocation(MemoryLocationsKind Loc, bool AndLocalMem, bool AndConstMem) {
4808 return NO_LOCATIONS & ~(Loc | (AndLocalMem ? NO_LOCAL_MEM : 0) |
4809 (AndConstMem ? NO_CONST_MEM : 0));
4810 };
4811
4812 /// Return the locations encoded by \p MLK as a readable string.
4814
4815 /// Simple enum to distinguish read/write/read-write accesses.
4817 NONE = 0,
4818 READ = 1 << 0,
4819 WRITE = 1 << 1,
4821 };
4822
4823 /// Check \p Pred on all accesses to the memory kinds specified by \p MLK.
4824 ///
4825 /// This method will evaluate \p Pred on all accesses (access instruction +
4826 /// underlying accessed memory pointer) and it will return true if \p Pred
4827 /// holds every time.
4829 function_ref<bool(const Instruction *, const Value *, AccessKind,
4831 Pred,
4832 MemoryLocationsKind MLK) const = 0;
4833
4834 /// Create an abstract attribute view for the position \p IRP.
4836 Attributor &A);
4837
4838 const std::string getAsStr(Attributor *A) const override {
4840 }
4841
4842 StringRef getName() const override { return "AAMemoryLocation"; }
4843
4844 const char *getIdAddr() const override { return &ID; }
4845
4846 /// This function should return true if the type of the \p AA is
4847 /// AAMemoryLocation
4848 static bool classof(const AbstractAttribute *AA) {
4849 return (AA->getIdAddr() == &ID);
4850 }
4851
4852 /// Unique ID (due to the unique address)
4853 LLVM_ABI static const char ID;
4854};
4855
4856/// An abstract interface for range value analysis.
4858 : public StateWrapper<IntegerRangeState, AbstractAttribute, uint32_t> {
4861 : Base(IRP, IRP.getAssociatedType()->getIntegerBitWidth()) {}
4862
4864 if (!IRP.getAssociatedType()->isIntegerTy())
4865 return false;
4867 }
4868
4869 static bool requiresCallersForArgOrFunction() { return true; }
4870
4871 IntegerRangeState &getState() override { return *this; }
4872 const IntegerRangeState &getState() const override { return *this; }
4873
4874 /// Create an abstract attribute view for the position \p IRP.
4876 Attributor &A);
4877
4878 /// Return an assumed range for the associated value a program point \p CtxI.
4879 /// If \p I is nullptr, simply return an assumed range.
4880 virtual ConstantRange
4882 const Instruction *CtxI = nullptr) const = 0;
4883
4884 /// Return an assumed constant for the associated value a program point \p
4885 /// CtxI.
4886 std::optional<Constant *>
4887 getAssumedConstant(Attributor &A, const Instruction *CtxI = nullptr) const {
4888 ConstantRange RangeV = getAssumedConstantRange(A, CtxI);
4889 if (auto *C = RangeV.getSingleElement()) {
4892 AA::getWithType(*ConstantInt::get(Ty->getContext(), *C), *Ty));
4893 }
4894 if (RangeV.isEmptySet())
4895 return std::nullopt;
4896 return nullptr;
4897 }
4898
4899 StringRef getName() const override { return "AAValueConstantRange"; }
4900
4901 const char *getIdAddr() const override { return &ID; }
4902
4903 /// This function should return true if the type of the \p AA is
4904 /// AAValueConstantRange
4905 static bool classof(const AbstractAttribute *AA) {
4906 return (AA->getIdAddr() == &ID);
4907 }
4908
4909 /// Unique ID (due to the unique address)
4910 LLVM_ABI static const char ID;
4911};
4912
4913/// A class for a set state.
4914/// The assumed boolean state indicates whether the corresponding set is full
4915/// set or not. If the assumed state is false, this is the worst state. The
4916/// worst state (invalid state) of set of potential values is when the set
4917/// contains every possible value (i.e. we cannot in any way limit the value
4918/// that the target position can take). That never happens naturally, we only
4919/// force it. As for the conditions under which we force it, see
4920/// AAPotentialConstantValues.
4921template <typename MemberTy> struct PotentialValuesState : AbstractState {
4923
4924 PotentialValuesState() : IsValidState(true), UndefIsContained(false) {}
4925
4927 : IsValidState(IsValid), UndefIsContained(false) {}
4928
4929 bool isValidState() const override { return IsValidState.isValidState(); }
4930
4931 bool isAtFixpoint() const override { return IsValidState.isAtFixpoint(); }
4932
4934 return IsValidState.indicatePessimisticFixpoint();
4935 }
4936
4938 return IsValidState.indicateOptimisticFixpoint();
4939 }
4940
4941 /// Return the assumed state
4943 const PotentialValuesState &getAssumed() const { return *this; }
4944
4945 /// Return this set. We should check whether this set is valid or not by
4946 /// isValidState() before calling this function.
4947 const SetTy &getAssumedSet() const {
4948 assert(isValidState() && "This set shoud not be used when it is invalid!");
4949 return Set;
4950 }
4951
4952 /// Returns whether this state contains an undef value or not.
4953 bool undefIsContained() const {
4954 assert(isValidState() && "This flag shoud not be used when it is invalid!");
4955 return UndefIsContained;
4956 }
4957
4959 if (isValidState() != RHS.isValidState())
4960 return false;
4961 if (!isValidState() && !RHS.isValidState())
4962 return true;
4963 if (undefIsContained() != RHS.undefIsContained())
4964 return false;
4965 return Set == RHS.getAssumedSet();
4966 }
4967
4968 /// Maximum number of potential values to be tracked.
4969 /// This is set by -attributor-max-potential-values command line option
4970 static unsigned MaxPotentialValues;
4971
4972 /// Return empty set as the best state of potential values.
4974 return PotentialValuesState(true);
4975 }
4976
4978 return getBestState();
4979 }
4980
4981 /// Return full set as the worst state of potential values.
4983 return PotentialValuesState(false);
4984 }
4985
4986 /// Union assumed set with the passed value.
4987 void unionAssumed(const MemberTy &C) { insert(C); }
4988
4989 /// Union assumed set with assumed set of the passed state \p PVS.
4990 void unionAssumed(const PotentialValuesState &PVS) { unionWith(PVS); }
4991
4992 /// Union assumed set with an undef value.
4993 void unionAssumedWithUndef() { unionWithUndef(); }
4994
4995 /// "Clamp" this state with \p PVS.
4997 IsValidState ^= PVS.IsValidState;
4998 unionAssumed(PVS);
4999 return *this;
5000 }
5001
5003 IsValidState &= PVS.IsValidState;
5004 unionAssumed(PVS);
5005 return *this;
5006 }
5007
5008protected:
5010 assert(isValidState() && "This set shoud not be used when it is invalid!");
5011 return Set;
5012 }
5013
5014private:
5015 /// Check the size of this set, and invalidate when the size is no
5016 /// less than \p MaxPotentialValues threshold.
5017 void checkAndInvalidate() {
5018 if (Set.size() >= MaxPotentialValues)
5020 else
5021 reduceUndefValue();
5022 }
5023
5024 /// If this state contains both undef and not undef, we can reduce
5025 /// undef to the not undef value.
5026 void reduceUndefValue() { UndefIsContained = UndefIsContained & Set.empty(); }
5027
5028 /// Insert an element into this set.
5029 void insert(const MemberTy &C) {
5030 if (!isValidState())
5031 return;
5032 Set.insert(C);
5033 checkAndInvalidate();
5034 }
5035
5036 /// Take union with R.
5037 void unionWith(const PotentialValuesState &R) {
5038 /// If this is a full set, do nothing.
5039 if (!isValidState())
5040 return;
5041 /// If R is full set, change L to a full set.
5042 if (!R.isValidState()) {
5044 return;
5045 }
5046 Set.insert_range(R.Set);
5047 UndefIsContained |= R.undefIsContained();
5048 checkAndInvalidate();
5049 }
5050
5051 /// Take union with an undef value.
5052 void unionWithUndef() {
5053 UndefIsContained = true;
5054 reduceUndefValue();
5055 }
5056
5057 /// A helper state which indicate whether this state is valid or not.
5058 BooleanState IsValidState;
5059
5060 /// Container for potential values
5061 SetTy Set;
5062
5063 /// Flag for undef value
5064 bool UndefIsContained;
5065};
5066
5071
5072 bool operator==(const DenormalState Other) const {
5073 return Mode == Other.Mode && ModeF32 == Other.ModeF32;
5074 }
5075
5076 bool operator!=(const DenormalState Other) const {
5077 return Mode != Other.Mode || ModeF32 != Other.ModeF32;
5078 }
5079
5080 bool isValid() const { return Mode.isValid() && ModeF32.isValid(); }
5081
5085 if (Caller == Callee)
5086 return Caller;
5087 if (Callee == DenormalMode::Dynamic)
5088 return Caller;
5089 if (Caller == DenormalMode::Dynamic)
5090 return Callee;
5091 return DenormalMode::Invalid;
5092 }
5093
5095 return DenormalMode{unionDenormalKind(Callee.Output, Caller.Output),
5096 unionDenormalKind(Callee.Input, Caller.Input)};
5097 }
5098
5100 DenormalState Callee(*this);
5101 Callee.Mode = unionAssumed(Callee.Mode, Caller.Mode);
5102 Callee.ModeF32 = unionAssumed(Callee.ModeF32, Caller.ModeF32);
5103 return Callee;
5104 }
5105 };
5106
5108
5109 /// Explicitly track whether we've hit a fixed point.
5110 bool IsAtFixedpoint = false;
5111
5113
5114 DenormalState getKnown() const { return Known; }
5115
5116 // There's only really known or unknown, there's no speculatively assumable
5117 // state.
5118 DenormalState getAssumed() const { return Known; }
5119
5120 bool isValidState() const override { return Known.isValid(); }
5121
5122 /// Return true if there are no dynamic components to the denormal mode worth
5123 /// specializing.
5124 bool isModeFixed() const {
5125 return Known.Mode.Input != DenormalMode::Dynamic &&
5126 Known.Mode.Output != DenormalMode::Dynamic &&
5127 Known.ModeF32.Input != DenormalMode::Dynamic &&
5128 Known.ModeF32.Output != DenormalMode::Dynamic;
5129 }
5130
5131 bool isAtFixpoint() const override { return IsAtFixedpoint; }
5132
5138
5142
5146
5148 Known = Known.unionWith(Caller.getKnown());
5149 return *this;
5150 }
5151};
5152
5156
5160 const PotentialLLVMValuesState &R);
5161
5162/// An abstract interface for potential values analysis.
5163///
5164/// This AA collects potential values for each IR position.
5165/// An assumed set of potential values is initialized with the empty set (the
5166/// best state) and it will grow monotonically as we find more potential values
5167/// for this position.
5168/// The set might be forced to the worst state, that is, to contain every
5169/// possible value for this position in 2 cases.
5170/// 1. We surpassed the \p MaxPotentialValues threshold. This includes the
5171/// case that this position is affected (e.g. because of an operation) by a
5172/// Value that is in the worst state.
5173/// 2. We tried to initialize on a Value that we cannot handle (e.g. an
5174/// operator we do not currently handle).
5175///
5176/// For non constant integers see AAPotentialValues.
5178 : public StateWrapper<PotentialConstantIntValuesState, AbstractAttribute> {
5181
5183 if (!IRP.getAssociatedType()->isIntegerTy())
5184 return false;
5186 }
5187
5188 static bool requiresCallersForArgOrFunction() { return true; }
5189
5190 PotentialConstantIntValuesState &getState() override { return *this; }
5192 return *this;
5193 }
5194
5195 /// Create an abstract attribute view for the position \p IRP.
5198
5199 /// Return assumed constant for the associated value
5200 std::optional<Constant *>
5201 getAssumedConstant(Attributor &A, const Instruction *CtxI = nullptr) const {
5202 if (!isValidState())
5203 return nullptr;
5204 if (getAssumedSet().size() == 1) {
5207 *ConstantInt::get(Ty->getContext(), *(getAssumedSet().begin())),
5208 *Ty));
5209 }
5210 if (getAssumedSet().size() == 0) {
5211 if (undefIsContained())
5213 return std::nullopt;
5214 }
5215
5216 return nullptr;
5217 }
5218
5219 /// Return the minimum trailing zeros of potential constants
5221 if (!isValidState() || getAssumedSet().empty())
5222 return 0;
5223 unsigned TrailingZeros = getAssumedSet().begin()->getBitWidth() + 1;
5224 for (const APInt &It : getAssumedSet()) {
5225 if (It.countTrailingZeros() < TrailingZeros)
5226 TrailingZeros = It.countTrailingZeros();
5227 }
5228 if (TrailingZeros > getAssumedSet().begin()->getBitWidth())
5229 return 0;
5230 return TrailingZeros;
5231 }
5232 StringRef getName() const override { return "AAPotentialConstantValues"; }
5233
5234 const char *getIdAddr() const override { return &ID; }
5235
5236 /// This function should return true if the type of the \p AA is
5237 /// AAPotentialConstantValues
5238 static bool classof(const AbstractAttribute *AA) {
5239 return (AA->getIdAddr() == &ID);
5240 }
5241
5242 /// Unique ID (due to the unique address)
5243 LLVM_ABI static const char ID;
5244};
5245
5247 : public StateWrapper<PotentialLLVMValuesState, AbstractAttribute> {
5250
5251 static bool requiresCallersForArgOrFunction() { return true; }
5252
5253 PotentialLLVMValuesState &getState() override { return *this; }
5254 const PotentialLLVMValuesState &getState() const override { return *this; }
5255
5256 /// Create an abstract attribute view for the position \p IRP.
5258 Attributor &A);
5259
5260 /// Extract the single value in \p Values if any.
5261 LLVM_ABI static Value *
5263 const IRPosition &IRP,
5265
5266 StringRef getName() const override { return "AAPotentialValues"; }
5267
5268 const char *getIdAddr() const override { return &ID; }
5269
5270 /// This function should return true if the type of the \p AA is
5271 /// AAPotentialValues
5272 static bool classof(const AbstractAttribute *AA) {
5273 return (AA->getIdAddr() == &ID);
5274 }
5275
5276 /// Unique ID (due to the unique address)
5277 LLVM_ABI static const char ID;
5278
5279private:
5280 virtual bool getAssumedSimplifiedValues(
5282 AA::ValueScope, bool RecurseForSelectAndPHI = false) const = 0;
5283
5284 friend struct Attributor;
5285};
5286
5287/// An abstract interface for all noundef attributes.
5289 : public IRAttribute<Attribute::NoUndef,
5290 StateWrapper<BooleanState, AbstractAttribute>,
5291 AANoUndef> {
5293
5294 static bool isImpliedByUndef() { return false; }
5295
5296 static bool isImpliedByPoison() { return false; }
5297
5298 LLVM_ABI static bool isImpliedByIR(Attributor &A, const IRPosition &IRP,
5299 Attribute::AttrKind ImpliedAttributeKind,
5300 bool IgnoreSubsumingPositions = false);
5301
5302 /// Return true if we assume that the underlying value is noundef.
5303 bool isAssumedNoUndef() const { return getAssumed(); }
5304
5305 /// Return true if we know that underlying value is noundef.
5306 bool isKnownNoUndef() const { return getKnown(); }
5307
5308 /// Create an abstract attribute view for the position \p IRP.
5310 Attributor &A);
5311
5312 StringRef getName() const override { return "AANoUndef"; }
5313
5314 const char *getIdAddr() const override { return &ID; }
5315
5316 /// This function should return true if the type of the \p AA is AANoUndef
5317 static bool classof(const AbstractAttribute *AA) {
5318 return (AA->getIdAddr() == &ID);
5319 }
5320
5321 /// Unique ID (due to the unique address)
5322 LLVM_ABI static const char ID;
5323};
5324
5326 : public IRAttribute<
5327 Attribute::NoFPClass,
5328 StateWrapper<BitIntegerState<uint32_t, fcAllFlags, fcNone>,
5329 AbstractAttribute>,
5330 AANoFPClass> {
5333
5335
5337 return AttributeFuncs::isNoFPClassCompatibleType(IRP.getAssociatedType());
5338 }
5339
5340 /// Return the underlying assumed nofpclass.
5342 return static_cast<FPClassTest>(getAssumed());
5343 }
5344 /// Return the underlying known nofpclass.
5346 return static_cast<FPClassTest>(getKnown());
5347 }
5348
5349 /// Create an abstract attribute view for the position \p IRP.
5351 Attributor &A);
5352
5353 StringRef getName() const override { return "AANoFPClass"; }
5354
5355 const char *getIdAddr() const override { return &ID; }
5356
5357 /// This function should return true if the type of the \p AA is AANoFPClass
5358 static bool classof(const AbstractAttribute *AA) {
5359 return (AA->getIdAddr() == &ID);
5360 }
5361
5362 /// Unique ID (due to the unique address)
5363 LLVM_ABI static const char ID;
5364};
5365
5366struct AACallGraphNode;
5367struct AACallEdges;
5368
5369/// An Iterator for call edges, creates AACallEdges attributes in a lazy way.
5370/// This iterator becomes invalid if the underlying edge list changes.
5371/// So This shouldn't outlive a iteration of Attributor.
5372class AACallEdgeIterator
5373 : public iterator_adaptor_base<AACallEdgeIterator,
5374 SetVector<Function *>::iterator> {
5375 AACallEdgeIterator(Attributor &A, SetVector<Function *>::iterator Begin)
5376 : iterator_adaptor_base(Begin), A(A) {}
5377
5378public:
5380
5381private:
5382 Attributor &A;
5383 friend AACallEdges;
5384 friend AttributorCallGraph;
5385};
5386
5389 virtual ~AACallGraphNode() = default;
5390
5393
5394 /// Iterator range for exploring the call graph.
5399
5400protected:
5401 /// Reference to Attributor needed for GraphTraits implementation.
5403};
5404
5405/// An abstract state for querying live call edges.
5406/// This interface uses the Attributor's optimistic liveness
5407/// information to compute the edges that are alive.
5408struct AACallEdges : public StateWrapper<BooleanState, AbstractAttribute>,
5411
5413 : Base(IRP), AACallGraphNode(A) {}
5414
5415 static bool requiresNonAsmForCallBase() { return false; }
5416
5417 /// Get the optimistic edges.
5418 virtual const SetVector<Function *> &getOptimisticEdges() const = 0;
5419
5420 /// Is there any call with a unknown callee.
5421 virtual bool hasUnknownCallee() const = 0;
5422
5423 /// Is there any call with a unknown callee, excluding any inline asm.
5424 virtual bool hasNonAsmUnknownCallee() const = 0;
5425
5426 /// Iterator for exploring the call graph.
5430
5431 /// Iterator for exploring the call graph.
5435
5436 /// Create an abstract attribute view for the position \p IRP.
5438 Attributor &A);
5439
5440 StringRef getName() const override { return "AACallEdges"; }
5441
5442 const char *getIdAddr() const override { return &ID; }
5443
5444 /// This function should return true if the type of the \p AA is AACallEdges.
5445 static bool classof(const AbstractAttribute *AA) {
5446 return (AA->getIdAddr() == &ID);
5447 }
5448
5449 /// Unique ID (due to the unique address)
5450 LLVM_ABI static const char ID;
5451};
5452
5453// Synthetic root node for the Attributor's internal call graph.
5456 ~AttributorCallGraph() override = default;
5457
5459 return AACallEdgeIterator(A, A.Functions.begin());
5460 }
5461
5463 return AACallEdgeIterator(A, A.Functions.end());
5464 }
5465
5466 /// Force populate the entire call graph.
5467 void populateAll() const {
5468 for (const AACallGraphNode *AA : optimisticEdgesRange()) {
5469 // Nothing else to do here.
5470 (void)AA;
5471 }
5472 }
5473
5474 LLVM_ABI void print();
5475};
5476
5477template <> struct GraphTraits<AACallGraphNode *> {
5480
5482 return Node->optimisticEdgesBegin();
5483 }
5484
5486 return Node->optimisticEdgesEnd();
5487 }
5488};
5489
5490template <>
5494
5496 return static_cast<AACallGraphNode *>(G);
5497 }
5498
5500 return G->optimisticEdgesBegin();
5501 }
5502
5504 return G->optimisticEdgesEnd();
5505 }
5506};
5507
5508template <>
5511
5513 const AttributorCallGraph *Graph) {
5514 const AACallEdges *AACE = static_cast<const AACallEdges *>(Node);
5515 return AACE->getAssociatedFunction()->getName().str();
5516 }
5517
5519 const AttributorCallGraph *Graph) {
5520 // Hide the synth root.
5521 return static_cast<const AACallGraphNode *>(Graph) == Node;
5522 }
5523};
5524
5526 : public StateWrapper<BooleanState, AbstractAttribute> {
5529
5530 /// Summary about the execution domain of a block or instruction.
5555
5556 /// Create an abstract attribute view for the position \p IRP.
5558 Attributor &A);
5559
5560 StringRef getName() const override { return "AAExecutionDomain"; }
5561
5562 const char *getIdAddr() const override { return &ID; }
5563
5564 /// Check if an instruction is executed only by the initial thread.
5566 return isExecutedByInitialThreadOnly(*I.getParent());
5567 }
5568
5569 /// Check if a basic block is executed only by the initial thread.
5570 virtual bool isExecutedByInitialThreadOnly(const BasicBlock &) const = 0;
5571
5572 /// Check if the instruction \p I is executed in an aligned region, that is,
5573 /// the synchronizing effects before and after \p I are both aligned barriers.
5574 /// This effectively means all threads execute \p I together.
5576 const Instruction &I) const = 0;
5577
5579 /// Return the execution domain with which the call \p CB is entered and the
5580 /// one with which it is left.
5581 virtual std::pair<ExecutionDomainTy, ExecutionDomainTy>
5582 getExecutionDomain(const CallBase &CB) const = 0;
5584
5585 /// Helper function to determine if \p FI is a no-op given the information
5586 /// about its execution from \p ExecDomainAA.
5587 virtual bool isNoOpFence(const FenceInst &FI) const = 0;
5588
5589 /// This function should return true if the type of the \p AA is
5590 /// AAExecutionDomain.
5591 static bool classof(const AbstractAttribute *AA) {
5592 return (AA->getIdAddr() == &ID);
5593 }
5594
5595 /// Unique ID (due to the unique address)
5596 LLVM_ABI static const char ID;
5597};
5598
5599/// An abstract Attribute for computing reachability between functions.
5601 : public StateWrapper<BooleanState, AbstractAttribute> {
5603
5605
5606 /// If the function represented by this possition can reach \p Fn.
5607 bool canReach(Attributor &A, const Function &Fn) const {
5608 Function *Scope = getAnchorScope();
5609 if (!Scope || Scope->isDeclaration())
5610 return true;
5611 return instructionCanReach(A, Scope->getEntryBlock().front(), Fn);
5612 }
5613
5614 /// Can \p Inst reach \p Fn.
5615 /// See also AA::isPotentiallyReachable.
5617 Attributor &A, const Instruction &Inst, const Function &Fn,
5618 const AA::InstExclusionSetTy *ExclusionSet = nullptr) const = 0;
5619
5620 /// Create an abstract attribute view for the position \p IRP.
5623
5624 StringRef getName() const override { return "AAInterFnReachability"; }
5625
5626 const char *getIdAddr() const override { return &ID; }
5627
5628 /// This function should return true if the type of the \p AA is AACallEdges.
5629 static bool classof(const AbstractAttribute *AA) {
5630 return (AA->getIdAddr() == &ID);
5631 }
5632
5633 /// Unique ID (due to the unique address)
5634 LLVM_ABI static const char ID;
5635};
5636
5637/// An abstract Attribute for determining the necessity of the convergent
5638/// attribute.
5639struct AANonConvergent : public StateWrapper<BooleanState, AbstractAttribute> {
5641
5643
5644 /// Create an abstract attribute view for the position \p IRP.
5646 Attributor &A);
5647
5648 /// Return true if "non-convergent" is assumed.
5649 bool isAssumedNotConvergent() const { return getAssumed(); }
5650
5651 /// Return true if "non-convergent" is known.
5652 bool isKnownNotConvergent() const { return getKnown(); }
5653
5654 StringRef getName() const override { return "AANonConvergent"; }
5655
5656 const char *getIdAddr() const override { return &ID; }
5657
5658 /// This function should return true if the type of the \p AA is
5659 /// AANonConvergent.
5660 static bool classof(const AbstractAttribute *AA) {
5661 return (AA->getIdAddr() == &ID);
5662 }
5663
5664 /// Unique ID (due to the unique address)
5665 LLVM_ABI static const char ID;
5666};
5667
5668/// An abstract interface for struct information.
5671
5674 return false;
5676 }
5677
5679 // First two bits to distinguish may and must accesses.
5680 AK_MUST = 1 << 0,
5681 AK_MAY = 1 << 1,
5682
5683 // Then two bits for read and write. These are not exclusive.
5684 AK_R = 1 << 2,
5685 AK_W = 1 << 3,
5687
5688 // One special case for assumptions about memory content. These
5689 // are neither reads nor writes. They are however always modeled
5690 // as read to avoid using them for write removal.
5692
5693 // Helper for easy access.
5700 };
5701
5702 /// A helper containing a list of offsets computed for a Use. Ideally this
5703 /// list should be strictly ascending, but we ensure that only when we
5704 /// actually translate the list of offsets to a RangeList.
5705 struct OffsetInfo {
5709
5710 const_iterator begin() const { return Offsets.begin(); }
5711 const_iterator end() const { return Offsets.end(); }
5712
5713 bool operator==(const OffsetInfo &RHS) const {
5714 return Offsets == RHS.Offsets;
5715 }
5716
5717 bool operator!=(const OffsetInfo &RHS) const { return !(*this == RHS); }
5718
5719 bool insert(int64_t Offset) { return Offsets.insert(Offset).second; }
5720 bool isUnassigned() const { return Offsets.size() == 0; }
5721
5722 bool isUnknown() const {
5723 if (isUnassigned())
5724 return false;
5725 if (Offsets.size() == 1)
5726 return *Offsets.begin() == AA::RangeTy::Unknown;
5727 return false;
5728 }
5729
5730 void setUnknown() {
5731 Offsets.clear();
5733 }
5734
5735 void addToAll(int64_t Inc) {
5736 VecTy NewOffsets;
5737 for (auto &Offset : Offsets)
5738 NewOffsets.insert(Offset + Inc);
5739 Offsets = std::move(NewOffsets);
5740 }
5741
5742 /// Copy offsets from \p R into the current list.
5743 ///
5744 /// Ideally all lists should be strictly ascending, but we defer that to the
5745 /// actual use of the list. So we just blindly append here.
5746 bool merge(const OffsetInfo &R) { return set_union(Offsets, R.Offsets); }
5747 };
5748
5749 /// A container for a list of ranges.
5750 struct RangeList {
5751 // The set of ranges rarely contains more than one element, and is unlikely
5752 // to contain more than say four elements. So we find the middle-ground with
5753 // a sorted vector. This avoids hard-coding a rarely used number like "four"
5754 // into every instance of a SmallSet.
5760
5761 RangeList(const RangeTy &R) { Ranges.push_back(R); }
5763 Ranges.reserve(Offsets.size());
5764 for (unsigned i = 0, e = Offsets.size(); i != e; ++i) {
5765 assert(((i + 1 == e) || Offsets[i] < Offsets[i + 1]) &&
5766 "Expected strictly ascending offsets.");
5767 Ranges.emplace_back(Offsets[i], Size);
5768 }
5769 }
5770 RangeList() = default;
5771
5772 iterator begin() { return Ranges.begin(); }
5773 iterator end() { return Ranges.end(); }
5774 const_iterator begin() const { return Ranges.begin(); }
5775 const_iterator end() const { return Ranges.end(); }
5776
5777 // Helpers required for std::set_difference
5779 void push_back(const RangeTy &R) {
5780 assert((Ranges.empty() || RangeTy::LessThan(Ranges.back(), R)) &&
5781 "Ensure the last element is the greatest.");
5782 Ranges.push_back(R);
5783 }
5784
5785 /// Copy ranges from \p L that are not in \p R, into \p D.
5786 static void set_difference(const RangeList &L, const RangeList &R,
5787 RangeList &D) {
5788 std::set_difference(L.begin(), L.end(), R.begin(), R.end(),
5789 std::back_inserter(D), RangeTy::LessThan);
5790 }
5791
5792 unsigned size() const { return Ranges.size(); }
5793
5794 bool operator==(const RangeList &OI) const { return Ranges == OI.Ranges; }
5795
5796 /// Merge the ranges in \p RHS into the current ranges.
5797 /// - Merging a list of unknown ranges makes the current list unknown.
5798 /// - Ranges with the same offset are merged according to RangeTy::operator&
5799 /// \return true if the current RangeList changed.
5800 bool merge(const RangeList &RHS) {
5801 if (isUnknown())
5802 return false;
5803 if (RHS.isUnknown()) {
5804 setUnknown();
5805 return true;
5806 }
5807
5808 if (Ranges.empty()) {
5809 Ranges = RHS.Ranges;
5810 return true;
5811 }
5812
5813 bool Changed = false;
5814 auto LPos = Ranges.begin();
5815 for (auto &R : RHS.Ranges) {
5816 auto Result = insert(LPos, R);
5817 if (isUnknown())
5818 return true;
5819 LPos = Result.first;
5820 Changed |= Result.second;
5821 }
5822 return Changed;
5823 }
5824
5825 /// Insert \p R at the given iterator \p Pos, and merge if necessary.
5826 ///
5827 /// This assumes that all ranges before \p Pos are LessThan \p R, and
5828 /// then maintains the sorted order for the suffix list.
5829 ///
5830 /// \return The place of insertion and true iff anything changed.
5831 std::pair<iterator, bool> insert(iterator Pos, const RangeTy &R) {
5832 if (isUnknown())
5833 return std::make_pair(Ranges.begin(), false);
5834 if (R.offsetOrSizeAreUnknown()) {
5835 return std::make_pair(setUnknown(), true);
5836 }
5837
5838 // Maintain this as a sorted vector of unique entries.
5839 auto LB = std::lower_bound(Pos, Ranges.end(), R, RangeTy::LessThan);
5840 if (LB == Ranges.end() || LB->Offset != R.Offset)
5841 return std::make_pair(Ranges.insert(LB, R), true);
5842 bool Changed = *LB != R;
5843 *LB &= R;
5844 if (LB->offsetOrSizeAreUnknown())
5845 return std::make_pair(setUnknown(), true);
5846 return std::make_pair(LB, Changed);
5847 }
5848
5849 /// Add the increment \p Inc to the offset of every range.
5850 void addToAllOffsets(int64_t Inc) {
5851 assert(!isUnassigned() &&
5852 "Cannot increment if the offset is not yet computed!");
5853 if (isUnknown())
5854 return;
5855 for (auto &R : Ranges) {
5856 R.Offset += Inc;
5857 }
5858 }
5859
5860 /// Return true iff the list contains an unknown range.
5861 bool isUnknown() const {
5862 if (isUnassigned())
5863 return false;
5864 if (Ranges.front().offsetOrSizeAreUnknown()) {
5865 assert(Ranges.size() == 1 && "Unknown is a singleton range.");
5866 return true;
5867 }
5868 return false;
5869 }
5870
5871 /// Discard all ranges and insert a single unknown range.
5873 Ranges.clear();
5874 Ranges.push_back(RangeTy::getUnknown());
5875 return Ranges.begin();
5876 }
5877
5878 /// Return true if no ranges have been inserted.
5879 bool isUnassigned() const { return Ranges.size() == 0; }
5880 };
5881
5882 /// An access description.
5883 struct Access {
5884 Access(Instruction *I, int64_t Offset, int64_t Size,
5885 std::optional<Value *> Content, AccessKind Kind, Type *Ty)
5886 : LocalI(I), RemoteI(I), Content(Content), Ranges(Offset, Size),
5887 Kind(Kind), Ty(Ty) {
5888 verify();
5889 }
5890 Access(Instruction *LocalI, Instruction *RemoteI, const RangeList &Ranges,
5891 std::optional<Value *> Content, AccessKind K, Type *Ty)
5892 : LocalI(LocalI), RemoteI(RemoteI), Content(Content), Ranges(Ranges),
5893 Kind(K), Ty(Ty) {
5894 if (Ranges.size() > 1) {
5895 Kind = AccessKind(Kind | AK_MAY);
5896 Kind = AccessKind(Kind & ~AK_MUST);
5897 }
5898 verify();
5899 }
5900 Access(Instruction *LocalI, Instruction *RemoteI, int64_t Offset,
5901 int64_t Size, std::optional<Value *> Content, AccessKind Kind,
5902 Type *Ty)
5903 : LocalI(LocalI), RemoteI(RemoteI), Content(Content),
5904 Ranges(Offset, Size), Kind(Kind), Ty(Ty) {
5905 verify();
5906 }
5907 Access(const Access &Other) = default;
5908
5909 Access &operator=(const Access &Other) = default;
5910 bool operator==(const Access &R) const {
5911 return LocalI == R.LocalI && RemoteI == R.RemoteI && Ranges == R.Ranges &&
5912 Content == R.Content && Kind == R.Kind;
5913 }
5914 bool operator!=(const Access &R) const { return !(*this == R); }
5915
5917 assert(RemoteI == R.RemoteI && "Expected same instruction!");
5918 assert(LocalI == R.LocalI && "Expected same instruction!");
5919
5920 // Note that every Access object corresponds to a unique Value, and only
5921 // accesses to the same Value are merged. Hence we assume that all ranges
5922 // are the same size. If ranges can be different size, then the contents
5923 // must be dropped.
5924 Ranges.merge(R.Ranges);
5925 Content =
5926 AA::combineOptionalValuesInAAValueLatice(Content, R.Content, Ty);
5927
5928 // Combine the access kind, which results in a bitwise union.
5929 // If there is more than one range, then this must be a MAY.
5930 // If we combine a may and a must access we clear the must bit.
5931 Kind = AccessKind(Kind | R.Kind);
5932 if ((Kind & AK_MAY) || Ranges.size() > 1) {
5933 Kind = AccessKind(Kind | AK_MAY);
5934 Kind = AccessKind(Kind & ~AK_MUST);
5935 }
5936 verify();
5937 return *this;
5938 }
5939
5940 void verify() {
5941 assert(isMustAccess() + isMayAccess() == 1 &&
5942 "Expect must or may access, not both.");
5943 assert(isAssumption() + isWrite() <= 1 &&
5944 "Expect assumption access or write access, never both.");
5945 assert((isMayAccess() || Ranges.size() == 1) &&
5946 "Cannot be a must access if there are multiple ranges.");
5947 }
5948
5949 /// Return the access kind.
5950 AccessKind getKind() const { return Kind; }
5951
5952 /// Return true if this is a read access.
5953 bool isRead() const { return Kind & AK_R; }
5954
5955 /// Return true if this is a write access.
5956 bool isWrite() const { return Kind & AK_W; }
5957
5958 /// Return true if this is a write access.
5959 bool isWriteOrAssumption() const { return isWrite() || isAssumption(); }
5960
5961 /// Return true if this is an assumption access.
5962 bool isAssumption() const { return Kind == AK_ASSUMPTION; }
5963
5964 bool isMustAccess() const {
5965 bool MustAccess = Kind & AK_MUST;
5966 assert((!MustAccess || Ranges.size() < 2) &&
5967 "Cannot be a must access if there are multiple ranges.");
5968 return MustAccess;
5969 }
5970
5971 bool isMayAccess() const {
5972 bool MayAccess = Kind & AK_MAY;
5973 assert((MayAccess || Ranges.size() < 2) &&
5974 "Cannot be a must access if there are multiple ranges.");
5975 return MayAccess;
5976 }
5977
5978 /// Return the instruction that causes the access with respect to the local
5979 /// scope of the associated attribute.
5980 Instruction *getLocalInst() const { return LocalI; }
5981
5982 /// Return the actual instruction that causes the access.
5983 Instruction *getRemoteInst() const { return RemoteI; }
5984
5985 /// Return true if the value written is not known yet.
5986 bool isWrittenValueYetUndetermined() const { return !Content; }
5987
5988 /// Return true if the value written cannot be determined at all.
5990 return Content.has_value() && !*Content;
5991 }
5992
5993 /// Return the type associated with the access, if known.
5994 Type *getType() const { return Ty; }
5995
5996 /// Return the value writen, if any.
5999 "Value needs to be determined before accessing it.");
6000 return *Content;
6001 }
6002
6003 /// Return the written value which can be `llvm::null` if it is not yet
6004 /// determined.
6005 std::optional<Value *> getContent() const { return Content; }
6006
6007 const RangeList &getRanges() const { return Ranges; }
6008
6010 const_iterator begin() const { return Ranges.begin(); }
6011 const_iterator end() const { return Ranges.end(); }
6012
6013 private:
6014 /// The instruction responsible for the access with respect to the local
6015 /// scope of the associated attribute.
6016 Instruction *LocalI;
6017
6018 /// The instruction responsible for the access.
6019 Instruction *RemoteI;
6020
6021 /// The value written, if any. `std::nullopt` means "not known yet",
6022 /// `nullptr` cannot be determined.
6023 std::optional<Value *> Content;
6024
6025 /// Set of potential ranges accessed from the base pointer.
6026 RangeList Ranges;
6027
6028 /// The access kind, e.g., READ, as bitset (could be more than one).
6030
6031 /// The type of the content, thus the type read/written, can be null if not
6032 /// available.
6033 Type *Ty;
6034 };
6035
6036 /// Create an abstract attribute view for the position \p IRP.
6038 Attributor &A);
6039
6040 StringRef getName() const override { return "AAPointerInfo"; }
6041
6042 const char *getIdAddr() const override { return &ID; }
6043
6045 using const_bin_iterator = OffsetBinsTy::const_iterator;
6046 virtual const_bin_iterator begin() const = 0;
6047 virtual const_bin_iterator end() const = 0;
6048 virtual int64_t numOffsetBins() const = 0;
6049 virtual bool reachesReturn() const = 0;
6050 virtual void addReturnedOffsetsTo(OffsetInfo &) const = 0;
6051
6052 /// Call \p CB on all accesses that might interfere with \p Range and return
6053 /// true if all such accesses were known and the callback returned true for
6054 /// all of them, false otherwise. An access interferes with an offset-size
6055 /// pair if it might read or write that memory region.
6057 AA::RangeTy Range, function_ref<bool(const Access &, bool)> CB) const = 0;
6058
6059 /// Call \p CB on all accesses that might interfere with \p I and
6060 /// return true if all such accesses were known and the callback returned true
6061 /// for all of them, false otherwise. In contrast to forallInterferingAccesses
6062 /// this function will perform reasoning to exclude write accesses that cannot
6063 /// affect the load even if they on the surface look as if they would. The
6064 /// flag \p HasBeenWrittenTo will be set to true if we know that \p I does not
6065 /// read the initial value of the underlying memory. If \p SkipCB is given and
6066 /// returns false for a potentially interfering access, that access is not
6067 /// checked for actual interference.
6069 Attributor &A, const AbstractAttribute &QueryingAA, Instruction &I,
6070 bool FindInterferingWrites, bool FindInterferingReads,
6071 function_ref<bool(const Access &, bool)> CB, bool &HasBeenWrittenTo,
6073 function_ref<bool(const Access &)> SkipCB = nullptr) const = 0;
6074
6075 /// This function should return true if the type of the \p AA is AAPointerInfo
6076 static bool classof(const AbstractAttribute *AA) {
6077 return (AA->getIdAddr() == &ID);
6078 }
6079
6080 /// Unique ID (due to the unique address)
6081 LLVM_ABI static const char ID;
6082};
6083
6085
6086/// An abstract attribute for getting assumption information.
6088 : public StateWrapper<SetState<StringRef>, AbstractAttribute,
6089 DenseSet<StringRef>> {
6090 using Base =
6092
6094 const DenseSet<StringRef> &Known)
6095 : Base(IRP, Known) {}
6096
6097 /// Returns true if the assumption set contains the assumption \p Assumption.
6098 virtual bool hasAssumption(const StringRef Assumption) const = 0;
6099
6100 /// Create an abstract attribute view for the position \p IRP.
6102 Attributor &A);
6103
6104 StringRef getName() const override { return "AAAssumptionInfo"; }
6105
6106 const char *getIdAddr() const override { return &ID; }
6107
6108 /// This function should return true if the type of the \p AA is
6109 /// AAAssumptionInfo
6110 static bool classof(const AbstractAttribute *AA) {
6111 return (AA->getIdAddr() == &ID);
6112 }
6113
6114 /// Unique ID (due to the unique address)
6115 LLVM_ABI static const char ID;
6116};
6117
6118/// An abstract attribute for getting all assumption underlying objects.
6121
6124 return false;
6126 }
6127
6128 static bool requiresCallersForArgOrFunction() { return true; }
6129
6130 /// Create an abstract attribute biew for the position \p IRP.
6132 Attributor &A);
6133
6134 StringRef getName() const override { return "AAUnderlyingObjects"; }
6135
6136 const char *getIdAddr() const override { return &ID; }
6137
6138 /// This function should return true if the type of the \p AA is
6139 /// AAUnderlyingObjects.
6140 static bool classof(const AbstractAttribute *AA) {
6141 return (AA->getIdAddr() == &ID);
6142 }
6143
6144 /// Unique ID (due to the unique address)
6145 LLVM_ABI static const char ID;
6146
6147 /// Check \p Pred on all underlying objects in \p Scope collected so far.
6148 ///
6149 /// This method will evaluate \p Pred on all underlying objects in \p Scope
6150 /// collected so far and return true if \p Pred holds on all of them.
6151 virtual bool
6153 AA::ValueScope Scope = AA::Interprocedural) const = 0;
6154};
6155
6156/// An abstract interface for identifying pointers from which loads can be
6157/// marked invariant.
6160
6162 if (!IRP.getAssociatedType()->isPointerTy())
6163 return false;
6164
6166 }
6167
6168 /// Create an abstract attribute view for the position \p IRP.
6171
6172 /// Return true if the pointer's contents are known to remain invariant.
6173 virtual bool isKnownInvariant() const = 0;
6174 virtual bool isKnownLocallyInvariant() const = 0;
6175
6176 /// Return true if the pointer's contents are assumed to remain invariant.
6177 virtual bool isAssumedInvariant() const = 0;
6178 virtual bool isAssumedLocallyInvariant() const = 0;
6179
6180 StringRef getName() const override { return "AAInvariantLoadPointer"; }
6181
6182 const char *getIdAddr() const override { return &ID; }
6183
6184 /// This function should return true if the type of the \p AA is
6185 /// AAInvariantLoadPointer
6186 static bool classof(const AbstractAttribute *AA) {
6187 return (AA->getIdAddr() == &ID);
6188 }
6189
6190 /// Unique ID (due to the unique address).
6191 LLVM_ABI static const char ID;
6192};
6193
6194/// An abstract interface for address space information.
6195struct AAAddressSpace : public StateWrapper<BooleanState, AbstractAttribute> {
6198
6201 return false;
6203 }
6204
6205 static bool requiresCallersForArgOrFunction() { return true; }
6206
6207 /// Return the address space of the associated value. \p NoAddressSpace is
6208 /// returned if the associated value is dead. This functions is not supposed
6209 /// to be called if the AA is invalid.
6210 virtual uint32_t getAddressSpace() const = 0;
6211
6212 /// Create an abstract attribute view for the position \p IRP.
6214 Attributor &A);
6215
6216 StringRef getName() const override { return "AAAddressSpace"; }
6217
6218 const char *getIdAddr() const override { return &ID; }
6219
6220 /// This function should return true if the type of the \p AA is
6221 /// AAAssumptionInfo
6222 static bool classof(const AbstractAttribute *AA) {
6223 return (AA->getIdAddr() == &ID);
6224 }
6225
6226 /// Unique ID (due to the unique address)
6227 LLVM_ABI static const char ID;
6228
6229protected:
6230 // Invalid address space which indicates the associated value is dead.
6231 static const uint32_t InvalidAddressSpace = ~0U;
6232};
6233
6234/// An abstract interface for potential address space information.
6236 : public StateWrapper<BooleanState, AbstractAttribute> {
6241
6244 return false;
6246 }
6247
6248 static bool requiresCallersForArgOrFunction() { return true; }
6249
6250 /// Create an abstract attribute view for the position \p IRP.
6252 Attributor &A);
6253 StringRef getName() const override { return "AANoAliasAddrSpace"; }
6254
6255 const char *getIdAddr() const override { return &ID; }
6256
6257 /// This function should return true if the type of the \p AA is
6258 /// AAAssumptionInfo
6259 static bool classof(const AbstractAttribute *AA) {
6260 return (AA->getIdAddr() == &ID);
6261 }
6262
6263 /// Unique ID (due to the unique address)
6264 LLVM_ABI static const char ID;
6265
6266protected:
6269};
6270
6271struct AAAllocationInfo : public StateWrapper<BooleanState, AbstractAttribute> {
6274
6277 return false;
6279 }
6280
6281 /// Create an abstract attribute view for the position \p IRP.
6283 Attributor &A);
6284
6285 virtual std::optional<TypeSize> getAllocatedSize() const = 0;
6286
6287 StringRef getName() const override { return "AAAllocationInfo"; }
6288
6289 const char *getIdAddr() const override { return &ID; }
6290
6291 /// This function should return true if the type of the \p AA is
6292 /// AAAllocationInfo
6293 static bool classof(const AbstractAttribute *AA) {
6294 return (AA->getIdAddr() == &ID);
6295 }
6296
6297 constexpr static const std::optional<TypeSize> HasNoAllocationSize =
6298 std::make_optional<TypeSize>(-1, true);
6299
6300 LLVM_ABI static const char ID;
6301};
6302
6303/// An abstract interface for llvm::GlobalValue information interference.
6305 : public StateWrapper<BooleanState, AbstractAttribute> {
6308
6311 return false;
6312 auto *GV = dyn_cast<GlobalValue>(&IRP.getAnchorValue());
6313 if (!GV)
6314 return false;
6315 return GV->hasLocalLinkage();
6316 }
6317
6318 /// Create an abstract attribute view for the position \p IRP.
6320 Attributor &A);
6321
6322 /// Return true iff \p U is a potential use of the associated global value.
6323 virtual bool isPotentialUse(const Use &U) const = 0;
6324
6325 StringRef getName() const override { return "AAGlobalValueInfo"; }
6326
6327 const char *getIdAddr() const override { return &ID; }
6328
6329 /// This function should return true if the type of the \p AA is
6330 /// AAGlobalValueInfo
6331 static bool classof(const AbstractAttribute *AA) {
6332 return (AA->getIdAddr() == &ID);
6333 }
6334
6335 /// Unique ID (due to the unique address)
6336 LLVM_ABI static const char ID;
6337};
6338
6339/// An abstract interface for indirect call information interference.
6341 : public StateWrapper<BooleanState, AbstractAttribute> {
6344
6347 return false;
6348 auto *CB = cast<CallBase>(IRP.getCtxI());
6349 return CB->getOpcode() == Instruction::Call && CB->isIndirectCall() &&
6350 !CB->isMustTailCall();
6351 }
6352
6353 /// Create an abstract attribute view for the position \p IRP.
6355 Attributor &A);
6356
6357 /// Call \CB on each potential callee value and return true if all were known
6358 /// and \p CB returned true on all of them. Otherwise, return false.
6359 virtual bool foreachCallee(function_ref<bool(Function *)> CB) const = 0;
6360
6361 StringRef getName() const override { return "AAIndirectCallInfo"; }
6362
6363 const char *getIdAddr() const override { return &ID; }
6364
6365 /// This function should return true if the type of the \p AA is
6366 /// AAIndirectCallInfo
6367 /// This function should return true if the type of the \p AA is
6368 /// AADenormalFPMath.
6369 static bool classof(const AbstractAttribute *AA) {
6370 return (AA->getIdAddr() == &ID);
6371 }
6372
6373 /// Unique ID (due to the unique address)
6374 LLVM_ABI static const char ID;
6375};
6376
6377/// An abstract Attribute for specializing "dynamic" components of
6378/// denormal_fpenv to a known denormal mode.
6380 : public StateWrapper<DenormalFPMathState, AbstractAttribute> {
6382
6384
6385 /// Create an abstract attribute view for the position \p IRP.
6387 Attributor &A);
6388
6389 StringRef getName() const override { return "AADenormalFPMath"; }
6390
6391 const char *getIdAddr() const override { return &ID; }
6392
6393 /// This function should return true if the type of the \p AA is
6394 /// AADenormalFPMath.
6395 static bool classof(const AbstractAttribute *AA) {
6396 return (AA->getIdAddr() == &ID);
6397 }
6398
6399 /// Unique ID (due to the unique address)
6400 LLVM_ABI static const char ID;
6401};
6402
6403/// Run options, used by the pass manager.
6414
6415namespace AA {
6416/// Helper to avoid creating an AA for IR Attributes that might already be set.
6417template <Attribute::AttrKind AK, typename AAType = AbstractAttribute>
6419 const IRPosition &IRP, DepClassTy DepClass, bool &IsKnown,
6420 bool IgnoreSubsumingPositions = false,
6421 const AAType **AAPtr = nullptr) {
6422 IsKnown = false;
6423 switch (AK) {
6424#define CASE(ATTRNAME, AANAME, ...) \
6425 case Attribute::ATTRNAME: { \
6426 if (AANAME::isImpliedByIR(A, IRP, AK, IgnoreSubsumingPositions)) \
6427 return IsKnown = true; \
6428 if (!QueryingAA) \
6429 return false; \
6430 const auto *AA = A.getAAFor<AANAME>(*QueryingAA, IRP, DepClass); \
6431 if (AAPtr) \
6432 *AAPtr = reinterpret_cast<const AAType *>(AA); \
6433 if (!AA || !AA->isAssumed(__VA_ARGS__)) \
6434 return false; \
6435 IsKnown = AA->isKnown(__VA_ARGS__); \
6436 return true; \
6437 }
6438 CASE(NoUnwind, AANoUnwind, );
6439 CASE(WillReturn, AAWillReturn, );
6440 CASE(NoFree, AANoFree, );
6441 CASE(Captures, AANoCapture, );
6442 CASE(NoRecurse, AANoRecurse, );
6443 CASE(NoReturn, AANoReturn, );
6444 CASE(NoSync, AANoSync, );
6445 CASE(NoAlias, AANoAlias, );
6446 CASE(NonNull, AANonNull, );
6447 CASE(MustProgress, AAMustProgress, );
6448 CASE(NoUndef, AANoUndef, );
6452#undef CASE
6453 default:
6454 llvm_unreachable("hasAssumedIRAttr not available for this attribute kind");
6455 };
6456}
6457} // namespace AA
6458
6459namespace detail {
6460template <const char *...IDs> struct AAKindIDList {};
6461
6462/// The IDs of the abstract attributes declared here, by their bit in
6463/// AAKindSet.
6478
6479template <const char *...IDs>
6481 return sizeof...(IDs);
6482}
6483
6484constexpr size_t NumAAKinds = getNumAAKinds(AAKindIDs());
6485static_assert(NumAAKinds <= 64, "Too many kinds for the mask");
6486
6487/// Return the bit of \p ID in AAKindSet, or the number of kinds if it has
6488/// none. The IDs are compared as template arguments since older compilers
6489/// cannot compare their addresses in constant expressions.
6490template <const char *ID, const char *...IDs>
6492 constexpr bool Matches[] = {
6493 std::is_same_v<AAKindIDList<ID>, AAKindIDList<IDs>>...};
6494 for (size_t I = 0; I != sizeof...(IDs); ++I) {
6495 if (Matches[I])
6496 return I;
6497 }
6498 return sizeof...(IDs);
6499}
6500
6501/// Return the bit of \p ID in the mask of AAKindSet, or 0 if it has none.
6502template <const char *ID> constexpr uint64_t getAAKindMask() {
6503 constexpr size_t Bit = getAAKindBit<ID>(AAKindIDs());
6504 return Bit < NumAAKinds ? uint64_t(1) << Bit : 0;
6505}
6506
6507/// The storage of the IDs of an AAKindSet.
6508template <const char *...IDs>
6509inline constexpr const char *AAKindSetIDs[] = {IDs...};
6510} // namespace detail
6511
6512template <const char *...KindIDs> constexpr AAKindSet AAKindSet::get() {
6513 return AAKindSet((detail::getAAKindMask<KindIDs>() | ...),
6515}
6516
6517template <typename AAType> bool AAKindSet::contains() const {
6518 constexpr uint64_t KindMask = detail::getAAKindMask<&AAType::ID>();
6519 if constexpr (KindMask != 0)
6520 return Mask & KindMask;
6521 else
6522 return is_contained(IDs, &AAType::ID);
6523}
6524
6525} // end namespace llvm
6526
6527#endif // LLVM_TRANSFORMS_IPO_ATTRIBUTOR_H
const TargetLowering & TLI
SDValue Pred
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
aarch64 promote const
uint64_t uint64_t
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file defines the BumpPtrAllocator interface.
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
This file contains the simple types necessary to represent the attributes associated with functions a...
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))
#define CASE(ATTRNAME, AANAME,...)
static const Function * getParent(const Value *V)
block Block Frequency Analysis
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This header provides classes for managing passes over SCCs of the call graph.
This file provides interfaces used to manipulate a call graph, regardless if it is a "old style" Call...
#define LLVM_ABI
Definition Compiler.h:211
This file contains the declarations for the subclasses of Constant, which represent the different fla...
DXIL Resource Access
This file defines the DenseSet and SmallDenseSet classes.
This file defines the little GraphTraits<X> template class that should be specialized by classes that...
Module.h This file contains the declarations for the Module class.
This header defines various interfaces for pass management in LLVM.
This file implements a coalescing interval map for small objects.
Implements a lazy call graph analysis and related passes for the new pass manager.
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
#define G(x, y, z)
Definition MD5.cpp:55
#define H(x, y, z)
Definition MD5.cpp:56
This file implements a map that provides insertion order iteration.
This file provides utility analysis objects describing memory locations.
Contains a collection of routines for determining if a given instruction is guaranteed to execute if ...
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
uint64_t IntrinsicInst * II
#define P(N)
ppc ctr loops verify
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
This file contains some templates that are useful if you are working with the STL at all.
BaseType
A given derived pointer can have multiple base pointers through phi/selects.
This file defines generic set operations that may be used on set's of different types,...
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallSet class.
static SymbolRef::Type getType(const Symbol *Sym)
Definition TapiFile.cpp:39
static unsigned getBitWidth(Type *Ty, const DataLayout &DL)
Returns the bitwidth of the given scalar or pointer type.
Value * RHS
Value * LHS
An Iterator for call edges, creates AACallEdges attributes in a lazy way.
LLVM_ABI AACallGraphNode * operator*() const
bool contains() const
Return true if abstract attributes of type AAType are in the set.
static constexpr AAKindSet get()
Return the set of the kinds with the IDs KindIDs.
Class for arbitrary precision integers.
Definition APInt.h:78
CallBase * getInstruction() const
Return the underlying instruction.
int getCallArgOperandNo(Argument &Arg) const
Return the operand index of the underlying instruction associated with Arg.
unsigned getNumArgOperands() const
Return the number of parameters of the callee.
This class represents an incoming formal argument to a Function.
Definition Argument.h:32
const Function * getParent() const
Definition Argument.h:44
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
This represents the llvm.assume intrinsic.
This class stores enough information to efficiently remove some attributes from an existing AttrBuild...
This class holds the attributes for a particular argument, parameter, function, or return value.
Definition Attributes.h:448
Functions, function parameters, and return types can have attributes to indicate how they should be t...
Definition Attributes.h:107
static LLVM_ABI Attribute get(LLVMContext &Context, AttrKind Kind, uint64_t Val=0)
Return a uniquified Attribute object.
static bool isEnumAttrKind(AttrKind Kind)
Definition Attributes.h:140
AttrKind
This enumeration lists the attributes that can be associated with parameters, function results,...
Definition Attributes.h:126
@ None
No attributes have been set.
Definition Attributes.h:128
LLVM Basic Block Representation.
Definition BasicBlock.h:62
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
const Use & getArgOperandUse(unsigned i) const
Wrappers for getting the Use of a call argument.
Wrapper to unify "old style" CallGraph and "new style" LazyCallGraph.
This class represents a range of values.
const APInt * getSingleElement() const
If this set contains a single element, return it, otherwise return null.
LLVM_ABI bool isEmptySet() const
Return true if this set contains no members.
This is an important base class in LLVM.
Definition Constant.h:44
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
Implements a dense probed hash-table based set.
Definition DenseSet.h:283
Analysis pass which computes a DominatorTree.
Definition Dominators.h:241
An instruction for ordering other memory operations.
Argument * arg_iterator
Definition Function.h:73
AttributeList getAttributes() const
Return the attribute list for this Function.
Definition Function.h:329
void setAttributes(AttributeList Attrs)
Set the attribute list for this Function.
Definition Function.h:332
Type * getReturnType() const
Returns the type of the ret val.
Definition Function.h:217
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition Function.cpp:731
bool hasLocalLinkage() const
typename Sizer::Allocator Allocator
Invoke instruction.
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:76
An SCC of the call graph.
A lazily constructed view of the call graph of a module.
An instruction for reading from memory.
Analysis pass that exposes the LoopInfo for a function.
Definition LoopInfo.h:598
bool onlyReadsMemory() const
Whether this function only (at most) reads memory.
Definition ModRef.h:249
static MemoryEffectsBase unknown()
Definition ModRef.h:123
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:68
The optimization diagnostic interface.
Pass interface - Implemented by all 'passes'.
Definition Pass.h:97
PointerIntPair - This class implements a pair of a pointer and small integer.
PointerTy getPointer() const
void setFromOpaqueValue(void *Val) &
Analysis pass which computes a PostDominatorTree.
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
A vector that has set insertion semantics.
Definition SetVector.h:57
size_type size() const
Determine the number of elements in the SetVector.
Definition SetVector.h:103
typename vector_type::const_iterator iterator
Definition SetVector.h:72
bool empty() const
Determine if the SetVector is empty or not.
Definition SetVector.h:100
iterator begin()
Get an iterator to the beginning of the SetVector.
Definition SetVector.h:112
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
iterator find(ConstPtrType Ptr) const
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
A SetVector that performs no allocations if smaller than a certain size.
Definition SetVector.h:346
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
Definition SmallSet.h:134
SmallSetIterator< int64_t, N, std::less< int64_t > > const_iterator
Definition SmallSet.h:150
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
Definition SmallSet.h:184
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
std::string str() const
Get the contents as an std::string.
Definition StringRef.h:222
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition StringRef.h:258
LLVM_ABI SubsumingPositionIterator(const IRPosition &IRP)
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
bool isPointerTy() const
True if this is an instance of PointerType.
Definition Type.h:277
bool isPtrOrPtrVectorTy() const
Return true if this is a pointer type or a vector of pointer types.
Definition Type.h:280
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:252
static LLVM_ABI UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
A Use represents the edge between a Value definition and its users.
Definition Use.h:35
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:257
LLVMContext & getContext() const
All values hold a context through their type.
Definition Value.h:260
LLVM_ABI const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
Definition Value.cpp:707
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:314
An efficient, type-erasing, non-owning reference to a callable.
A range adaptor for a pair of iterators.
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Abstract Attribute helper functions.
Definition Attributor.h:165
LLVM_ABI bool isAssumedReadNone(Attributor &A, const IRPosition &IRP, const AbstractAttribute &QueryingAA, bool &IsKnown)
Return true if IRP is readnone.
LLVM_ABI bool isAssumedReadOnly(Attributor &A, const IRPosition &IRP, const AbstractAttribute &QueryingAA, bool &IsKnown)
Return true if IRP is readonly.
raw_ostream & operator<<(raw_ostream &OS, const RangeTy &R)
Definition Attributor.h:327
LLVM_ABI std::optional< Value * > combineOptionalValuesInAAValueLatice(const std::optional< Value * > &A, const std::optional< Value * > &B, Type *Ty)
Return the combination of A and B such that the result is a possible value of both.
LLVM_ABI bool isValidAtPosition(const ValueAndContext &VAC, InformationCache &InfoCache)
Return true if the value of VAC is a valid at the position of VAC, that is a constant,...
LLVM_ABI bool isAssumedThreadLocalObject(Attributor &A, Value &Obj, const AbstractAttribute &QueryingAA)
Return true if Obj is assumed to be a thread local object.
LLVM_ABI bool isGPUConstantAddressSpace(const Module &M, unsigned AS)
Check if the given address space AS corresponds to a GPU constant address space for the target triple...
LLVM_ABI bool isDynamicallyUnique(Attributor &A, const AbstractAttribute &QueryingAA, const Value &V, bool ForAnalysisOnly=true)
Return true if V is dynamically unique, that is, there are no two "instances" of V at runtime with di...
LLVM_ABI bool getPotentialCopiesOfStoredValue(Attributor &A, StoreInst &SI, SmallSetVector< Value *, 4 > &PotentialCopies, const AbstractAttribute &QueryingAA, bool &UsedAssumedInformation, bool OnlyExact=false)
Collect all potential values of the one stored by SI into PotentialCopies.
LLVM_ABI bool isGPUSharedAddressSpace(const Module &M, unsigned AS)
Check if the given address space AS corresponds to a GPU shared address space for the target triple i...
bool operator!=(const RangeTy &A, const RangeTy &B)
Definition Attributor.h:336
LLVM_ABI bool isGPULocalAddressSpace(const Module &M, unsigned AS)
Check if the given address space AS corresponds to a GPU local/private address space for the target t...
LLVM_ABI bool isPotentiallyAffectedByBarrier(Attributor &A, const Instruction &I, const AbstractAttribute &QueryingAA)
Return true if I is potentially affected by a barrier.
SmallPtrSet< Instruction *, 4 > InstExclusionSetTy
Definition Attributor.h:166
LLVM_ABI bool isGPU(const Module &M)
Return true iff M target a GPU (and we can use GPU AS reasoning).
LLVM_ABI Constant * getInitialValueForObj(Attributor &A, const AbstractAttribute &QueryingAA, Value &Obj, Type &Ty, const TargetLibraryInfo *TLI, const DataLayout &DL, RangeTy *RangePtr=nullptr)
Return the initial value of Obj with type Ty if that is a constant.
bool operator==(const RangeTy &A, const RangeTy &B)
Definition Attributor.h:332
ValueScope
Flags to distinguish intra-procedural queries from potentially inter-procedural queries.
Definition Attributor.h:186
@ Intraprocedural
Definition Attributor.h:187
@ Interprocedural
Definition Attributor.h:188
LLVM_ABI bool isValidInScope(const Value &V, const Function *Scope)
Return true if V is a valid value in Scope, that is a constant or an instruction/argument of Scope.
LLVM_ABI bool isPotentiallyReachable(Attributor &A, const Instruction &FromI, const Instruction &ToI, const AbstractAttribute &QueryingAA, const AA::InstExclusionSetTy *ExclusionSet=nullptr, std::function< bool(const Function &F)> GoBackwardsCB=nullptr)
Return true if ToI is potentially reachable from FromI without running into any instruction in Exclus...
LLVM_ABI bool isNoSyncInst(Attributor &A, const Instruction &I, const AbstractAttribute &QueryingAA)
Return true if I is a nosync instruction.
bool hasAssumedIRAttr(Attributor &A, const AbstractAttribute *QueryingAA, const IRPosition &IRP, DepClassTy DepClass, bool &IsKnown, bool IgnoreSubsumingPositions=false, const AAType **AAPtr=nullptr)
Helper to avoid creating an AA for IR Attributes that might already be set.
LLVM_ABI bool getPotentiallyLoadedValues(Attributor &A, LoadInst &LI, SmallSetVector< Value *, 4 > &PotentialValues, SmallSetVector< Instruction *, 4 > &PotentialValueOrigins, const AbstractAttribute &QueryingAA, bool &UsedAssumedInformation, bool OnlyExact=false)
Collect all potential values LI could read into PotentialValues.
LLVM_ABI Value * getWithType(Value &V, Type &Ty)
Try to convert V to type Ty without introducing new instructions.
constexpr E & operator^=(E &LHS, E RHS)
constexpr size_t getNumAAKinds(AAKindIDList< IDs... >)
constexpr size_t NumAAKinds
constexpr const char * AAKindSetIDs[]
The storage of the IDs of an AAKindSet.
AAKindIDList< &AANoUnwind::ID, &AANoSync::ID, &AAMustProgress::ID, &AANonNull::ID, &AANoRecurse::ID, &AAWillReturn::ID, &AAUndefinedBehavior::ID, &AAIntraFnReachability::ID, &AANoAlias::ID, &AANoFree::ID, &AANoReturn::ID, &AAIsDead::ID, &AADereferenceable::ID, &AAAlign::ID, &AAInstanceInfo::ID, &AANoCapture::ID, &AAValueSimplify::ID, &AAHeapToStack::ID, &AAPrivatizablePtr::ID, &AAMemoryBehavior::ID, &AAMemoryLocation::ID, &AAValueConstantRange::ID, &AAPotentialConstantValues::ID, &AAPotentialValues::ID, &AANoUndef::ID, &AANoFPClass::ID, &AACallEdges::ID, &AAExecutionDomain::ID, &AAInterFnReachability::ID, &AANonConvergent::ID, &AAPointerInfo::ID, &AAAssumptionInfo::ID, &AAUnderlyingObjects::ID, &AAInvariantLoadPointer::ID, &AAAddressSpace::ID, &AANoAliasAddrSpace::ID, &AAAllocationInfo::ID, &AAGlobalValueInfo::ID, &AAIndirectCallInfo::ID, &AADenormalFPMath::ID > AAKindIDs
The IDs of the abstract attributes declared here, by their bit in AAKindSet.
constexpr size_t getAAKindBit(AAKindIDList< IDs... >)
Return the bit of ID in AAKindSet, or the number of kinds if it has none.
constexpr uint64_t getAAKindMask()
Return the bit of ID in the mask of AAKindSet, or 0 if it has none.
unsigned combineHashValue(unsigned a, unsigned b)
Simplistic combination of 32-bit hash values into 32-bit hash values.
NodeAddr< UseNode * > Use
Definition RDFGraph.h:385
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:577
bool isEqual(const GCNRPTracker::LiveRegSet &S1, const GCNRPTracker::LiveRegSet &S2)
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
Definition STLExtras.h:1685
LLVM_ABI unsigned MaxInitializationChainLength
The value passed to the line option that defines the maximal initialization chain length.
RelativeUniformCounterPtr Values
Definition InstrProf.h:91
APInt operator&(APInt a, const APInt &b)
Definition APInt.h:2149
@ Known
Known to have no common set bits.
void set_intersect(S1Ty &S1, const S2Ty &S2)
set_intersect(A, B) - Compute A := A ^ B Identical to set_intersection, except that it works on set<>...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
bool operator!=(uint64_t V1, const APInt &V2)
Definition APInt.h:2139
auto dyn_cast_if_present(const Y &Val)
dyn_cast_if_present<X> - Functionally identical to dyn_cast, except that a null (or none in the case ...
Definition Casting.h:732
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt & operator+=(DynamicAPInt &A, int64_t B)
bool set_is_subset(const S1Ty &S1, const S2Ty &S2)
set_is_subset(A, B) - Return true iff A in B
auto cast_or_null(const Y &Val)
Definition Casting.h:714
MemoryEffectsBase< IRMemLocation > MemoryEffects
Summary of how a function affects memory in the program.
Definition ModRef.h:356
bool isa_and_nonnull(const Y &Val)
Definition Casting.h:676
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
AttributorRunOption
Run options, used by the pass manager.
@ CGSCC_LIGHT
@ MODULE_LIGHT
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
AnalysisManager< LazyCallGraph::SCC, LazyCallGraph & > CGSCCAnalysisManager
The CGSCC analysis manager.
LLVM_ABI bool canSimplifyInvokeNoUnwind(const Function *F)
LLVM_ABI bool shouldCreateAbstractAttribute()
Check the debug counter used to limit the number of AAs created.
DenseMap< RetainedKnowledgeKey, Assume2KnowledgeMap > RetainedKnowledgeMap
PotentialValuesState< std::pair< AA::ValueAndContext, AA::ValueScope > > PotentialLLVMValuesState
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
FPClassTest
Floating-point class tests, supported by 'is_fpclass' intrinsic.
bool timeTraceProfilerEnabled()
Is the time trace profiler enabled, i.e. initialized?
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
bool set_union(S1Ty &S1, const S2Ty &S2)
set_union(A, B) - Compute A := A u B, return whether A changed.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
@ Success
The lock was released successfully.
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
iterator_range(Container &&) -> iterator_range< llvm::detail::IterOfRange< Container > >
@ Other
Any other memory.
Definition ModRef.h:68
PotentialValuesState< APInt > PotentialConstantIntValuesState
bool operator&=(SparseBitVector< ElementSize > *LHS, const SparseBitVector< ElementSize > &RHS)
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
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...
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1933
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
iterator_range< pointer_iterator< WrappedIteratorT > > make_pointer_range(RangeT &&Range)
Definition iterator.h:368
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition STLExtras.h:1963
ChangeStatus
{
Definition Attributor.h:477
bool operator|=(SparseBitVector< ElementSize > &LHS, const SparseBitVector< ElementSize > *RHS)
@ OPTIONAL
The target may be valid if the source is not.
Definition Attributor.h:489
@ NONE
Do not track a dependence between source and target.
Definition Attributor.h:490
@ REQUIRED
The target cannot be valid if the source is not.
Definition Attributor.h:488
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
APInt operator|(APInt a, const APInt &b)
Definition APInt.h:2169
BumpPtrAllocatorImpl<> BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
Definition Allocator.h:391
IncIntegerState< uint64_t, Value::MaximumAlignment, 1 > AAAlignmentStateType
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
Definition MIRParser.h:39
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:879
static LLVM_ABI AAAddressSpace & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
const char * getIdAddr() const override
This function should return the address of the ID of the AbstractAttribute.
static bool requiresCallersForArgOrFunction()
StringRef getName() const override
This function should return the name of the AbstractAttribute.
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAAssumptionInfo.
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
virtual uint32_t getAddressSpace() const =0
Return the address space of the associated value.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
AAAddressSpace(const IRPosition &IRP, Attributor &A)
static const uint32_t InvalidAddressSpace
AAAlign(const IRPosition &IRP, Attributor &A)
static LLVM_ABI AAAlign & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
const char * getIdAddr() const override
This function should return the address of the ID of the AbstractAttribute.
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
Align getAssumedAlign() const
Return assumed alignment.
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAAlign.
Align getKnownAlign() const
Return known alignment.
StringRef getName() const override
This function should return the name of the AbstractAttribute.
static LLVM_ABI const char ID
virtual std::optional< TypeSize > getAllocatedSize() const =0
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
const char * getIdAddr() const override
This function should return the address of the ID of the AbstractAttribute.
static LLVM_ABI AAAllocationInfo & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
StringRef getName() const override
This function should return the name of the AbstractAttribute.
AAAllocationInfo(const IRPosition &IRP, Attributor &A)
static constexpr const std::optional< TypeSize > HasNoAllocationSize
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAAllocationInfo.
AAAssumptionInfo(const IRPosition &IRP, Attributor &A, const DenseSet< StringRef > &Known)
static LLVM_ABI const char ID
Unique ID (due to the unique address)
StringRef getName() const override
This function should return the name of the AbstractAttribute.
static LLVM_ABI AAAssumptionInfo & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
StateWrapper< SetState< StringRef >, AbstractAttribute, DenseSet< StringRef > > Base
const char * getIdAddr() const override
This function should return the address of the ID of the AbstractAttribute.
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAAssumptionInfo.
virtual bool hasAssumption(const StringRef Assumption) const =0
Returns true if the assumption set contains the assumption Assumption.
An abstract state for querying live call edges.
AACallEdges(const IRPosition &IRP, Attributor &A)
virtual const SetVector< Function * > & getOptimisticEdges() const =0
Get the optimistic edges.
static bool requiresNonAsmForCallBase()
StateWrapper< BooleanState, AbstractAttribute > Base
AACallEdgeIterator optimisticEdgesBegin() const override
Iterator for exploring the call graph.
virtual bool hasUnknownCallee() const =0
Is there any call with a unknown callee.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
StringRef getName() const override
This function should return the name of the AbstractAttribute.
virtual bool hasNonAsmUnknownCallee() const =0
Is there any call with a unknown callee, excluding any inline asm.
AACallEdgeIterator optimisticEdgesEnd() const override
Iterator for exploring the call graph.
static LLVM_ABI AACallEdges & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AACallEdges.
const char * getIdAddr() const override
This function should return the address of the ID of the AbstractAttribute.
iterator_range< AACallEdgeIterator > optimisticEdgesRange() const
Iterator range for exploring the call graph.
virtual AACallEdgeIterator optimisticEdgesBegin() const =0
AACallGraphNode(Attributor &A)
virtual AACallEdgeIterator optimisticEdgesEnd() const =0
virtual ~AACallGraphNode()=default
Attributor & A
Reference to Attributor needed for GraphTraits implementation.
const char * getIdAddr() const override
This function should return the address of the ID of the AbstractAttribute.
StringRef getName() const override
This function should return the name of the AbstractAttribute.
AADenormalFPMath(const IRPosition &IRP, Attributor &A)
static LLVM_ABI const char ID
Unique ID (due to the unique address)
StateWrapper< DenormalFPMathState, AbstractAttribute > Base
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AADenormalFPMath.
static LLVM_ABI AADenormalFPMath & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
static AbstractAttribute * DepGetValAA(const DepTy &DT)
Definition Attributor.h:507
friend struct Attributor
Definition Attributor.h:528
mapped_iterator< DepSetTy::iterator, decltype(&DepGetVal)> iterator
Definition Attributor.h:514
mapped_iterator< DepSetTy::iterator, decltype(&DepGetValAA)> aaiterator
Definition Attributor.h:515
virtual ~AADepGraphNode()=default
SmallSetVector< DepTy, 2 > DepSetTy
Definition Attributor.h:499
static AADepGraphNode * DepGetVal(const DepTy &DT)
Definition Attributor.h:506
iterator child_begin()
Definition Attributor.h:520
DepSetTy Deps
Set of dependency graph nodes which should be updated if this one is updated.
Definition Attributor.h:504
friend struct AADepGraph
Definition Attributor.h:529
virtual void print(Attributor *, raw_ostream &OS) const
Definition Attributor.h:524
aaiterator begin()
Definition Attributor.h:518
PointerIntPair< AADepGraphNode *, 1 > DepTy
Definition Attributor.h:498
void print(raw_ostream &OS) const
Definition Attributor.h:523
The data structure for the dependency graph.
Definition Attributor.h:537
~AADepGraph()=default
iterator begin()
Definition Attributor.h:552
mapped_iterator< AADepGraphNode::DepSetTy::iterator, decltype(&DepGetVal)> iterator
Definition Attributor.h:543
LLVM_ABI void viewGraph()
AADepGraphNode SyntheticRoot
There is no root node for the dependency graph.
Definition Attributor.h:549
LLVM_ABI void print()
Print dependency graph.
static AADepGraphNode * DepGetVal(const DepTy &DT)
Definition Attributor.h:542
iterator end()
Definition Attributor.h:553
LLVM_ABI void dumpGraph()
Dump graph to file.
AADepGraphNode * GetEntryNode()
Definition Attributor.h:550
AADepGraph()=default
AADepGraphNode::DepTy DepTy
Definition Attributor.h:541
uint32_t getKnownDereferenceableBytes() const
Return known dereferenceable bytes.
bool isAssumedGlobal() const
Return true if we assume that underlying value is dereferenceable(_or_null) globally.
bool isKnownGlobal() const
Return true if we know that underlying value is dereferenceable(_or_null) globally.
AADereferenceable(const IRPosition &IRP, Attributor &A)
uint32_t getAssumedDereferenceableBytes() const
Return assumed dereferenceable bytes.
StringRef getName() const override
This function should return the name of the AbstractAttribute.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AADereferenceable.
const char * getIdAddr() const override
This function should return the address of the ID of the AbstractAttribute.
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
static LLVM_ABI AADereferenceable & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
Summary about the execution domain of a block or instruction.
void addAssumeInst(Attributor &A, AssumeInst &AI)
SmallPtrSet< AssumeInst *, 4 > AssumesSetTy
void addAlignedBarrier(Attributor &A, CallBase &CB)
SmallPtrSet< CallBase *, 2 > BarriersSetTy
virtual bool isExecutedByInitialThreadOnly(const BasicBlock &) const =0
Check if a basic block is executed only by the initial thread.
StateWrapper< BooleanState, AbstractAttribute > Base
bool isExecutedByInitialThreadOnly(const Instruction &I) const
Check if an instruction is executed only by the initial thread.
static LLVM_ABI AAExecutionDomain & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAExecutionDomain.
const char * getIdAddr() const override
This function should return the address of the ID of the AbstractAttribute.
virtual ExecutionDomainTy getFunctionExecutionDomain() const =0
virtual ExecutionDomainTy getExecutionDomain(const BasicBlock &) const =0
virtual bool isExecutedInAlignedRegion(Attributor &A, const Instruction &I) const =0
Check if the instruction I is executed in an aligned region, that is, the synchronizing effects befor...
AAExecutionDomain(const IRPosition &IRP, Attributor &A)
virtual bool isNoOpFence(const FenceInst &FI) const =0
Helper function to determine if FI is a no-op given the information about its execution from ExecDoma...
StringRef getName() const override
This function should return the name of the AbstractAttribute.
virtual std::pair< ExecutionDomainTy, ExecutionDomainTy > getExecutionDomain(const CallBase &CB) const =0
Return the execution domain with which the call CB is entered and the one with which it is left.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAGlobalValueInfo.
AAGlobalValueInfo(const IRPosition &IRP, Attributor &A)
StringRef getName() const override
This function should return the name of the AbstractAttribute.
static LLVM_ABI AAGlobalValueInfo & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
const char * getIdAddr() const override
This function should return the address of the ID of the AbstractAttribute.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
virtual bool isPotentialUse(const Use &U) const =0
Return true iff U is a potential use of the associated global value.
StringRef getName() const override
This function should return the name of the AbstractAttribute.
StateWrapper< BooleanState, AbstractAttribute > Base
const char * getIdAddr() const override
This function should return the address of the ID of the AbstractAttribute.
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAHeapToStack.
virtual bool isAssumedHeapToStack(const CallBase &CB) const =0
Returns true if HeapToStack conversion is assumed to be possible.
virtual bool isAssumedHeapToStackRemovedFree(CallBase &CB) const =0
Returns true if HeapToStack conversion is assumed and the CB is a callsite to a free operation to be ...
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI AAHeapToStack & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
AAHeapToStack(const IRPosition &IRP, Attributor &A)
StringRef getName() const override
This function should return the name of the AbstractAttribute.
virtual bool foreachCallee(function_ref< bool(Function *)> CB) const =0
Call \CB on each potential callee value and return true if all were known and CB returned true on all...
AAIndirectCallInfo(const IRPosition &IRP, Attributor &A)
const char * getIdAddr() const override
This function should return the address of the ID of the AbstractAttribute.
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAIndirectCallInfo This function should ret...
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI AAIndirectCallInfo & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
static LLVM_ABI const char ID
Unique ID (due to the unique address)
StringRef getName() const override
This function should return the name of the AbstractAttribute.
AAInstanceInfo(const IRPosition &IRP, Attributor &A)
bool isAssumedUniqueForAnalysis() const
Return true if we assume that the underlying value is unique in its scope wrt.
static LLVM_ABI AAInstanceInfo & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAInstanceInfo.
const char * getIdAddr() const override
This function should return the address of the ID of the AbstractAttribute.
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AACallEdges.
static LLVM_ABI AAInterFnReachability & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
const char * getIdAddr() const override
This function should return the address of the ID of the AbstractAttribute.
bool canReach(Attributor &A, const Function &Fn) const
If the function represented by this possition can reach Fn.
StringRef getName() const override
This function should return the name of the AbstractAttribute.
virtual bool instructionCanReach(Attributor &A, const Instruction &Inst, const Function &Fn, const AA::InstExclusionSetTy *ExclusionSet=nullptr) const =0
Can Inst reach Fn.
AAInterFnReachability(const IRPosition &IRP, Attributor &A)
StateWrapper< BooleanState, AbstractAttribute > Base
static LLVM_ABI AAIntraFnReachability & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAIntraFnReachability.
AAIntraFnReachability(const IRPosition &IRP, Attributor &A)
StringRef getName() const override
This function should return the name of the AbstractAttribute.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
const char * getIdAddr() const override
This function should return the address of the ID of the AbstractAttribute.
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.
StateWrapper< BooleanState, AbstractAttribute > Base
An abstract interface for identifying pointers from which loads can be marked invariant.
virtual bool isAssumedInvariant() const =0
Return true if the pointer's contents are assumed to remain invariant.
static LLVM_ABI AAInvariantLoadPointer & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
virtual bool isAssumedLocallyInvariant() const =0
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAInvariantLoadPointer.
static LLVM_ABI const char ID
Unique ID (due to the unique address).
const char * getIdAddr() const override
This function should return the address of the ID of the AbstractAttribute.
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
StringRef getName() const override
This function should return the name of the AbstractAttribute.
virtual bool isKnownInvariant() const =0
Return true if the pointer's contents are known to remain invariant.
AAInvariantLoadPointer(const IRPosition &IRP)
virtual bool isKnownLocallyInvariant() const =0
An abstract interface for liveness abstract attribute.
friend struct Attributor
virtual bool isKnownDead(const BasicBlock *BB) const =0
Returns true if BB is known dead.
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAIsDead.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
virtual bool isKnownDead() const =0
Returns true if the underlying value is known dead.
virtual bool isEdgeDead(const BasicBlock *From, const BasicBlock *To) const
Return if the edge from From BB to To BB is assumed dead.
virtual bool isAssumedDead(const Instruction *I) const =0
Returns true if I is assumed dead.
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
StringRef getName() const override
This function should return the name of the AbstractAttribute.
virtual bool isAssumedDead() const =0
The query functions are protected such that other attributes need to go through the Attributor interf...
virtual bool isRemovableStore() const
Return true if the underlying value is a store that is known to be removable.
virtual bool isAssumedDead(const BasicBlock *BB) const =0
Returns true if BB is assumed dead.
const char * getIdAddr() const override
This function should return the address of the ID of the AbstractAttribute.
StateWrapper< BitIntegerState< uint8_t, 3, 0 >, AbstractAttribute > Base
static LLVM_ABI AAIsDead & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
static bool mayCatchAsynchronousExceptions(const Function &F)
Determine if F might catch asynchronous exceptions.
AAIsDead(const IRPosition &IRP, Attributor &A)
virtual bool isKnownDead(const Instruction *I) const =0
Returns true if I is known dead.
An abstract interface for memory access kind related attributes (readnone/readonly/writeonly).
StringRef getName() const override
This function should return the name of the AbstractAttribute.
bool isAssumedReadOnly() const
Return true if we assume that the underlying value is not accessed (=written) in its respective scope...
static LLVM_ABI AAMemoryBehavior & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
static bool hasTrivialInitializer()
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAMemoryBehavior.
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
bool isKnownReadNone() const
Return true if we know that the underlying value is not read or accessed in its respective scope.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
bool isKnownWriteOnly() const
Return true if we know that the underlying value is not read in its respective scope.
bool isAssumedReadNone() const
Return true if we assume that the underlying value is not read or accessed in its respective scope.
bool isAssumedWriteOnly() const
Return true if we assume that the underlying value is not read in its respective scope.
AAMemoryBehavior(const IRPosition &IRP, Attributor &A)
const char * getIdAddr() const override
This function should return the address of the ID of the AbstractAttribute.
bool isKnownReadOnly() const
Return true if we know that the underlying value is not accessed (=written) in its respective scope.
StringRef getName() const override
This function should return the name of the AbstractAttribute.
const char * getIdAddr() const override
This function should return the address of the ID of the AbstractAttribute.
bool isAssumedStackOnly() const
Return true if we assume that the associated functions has at most local/stack accesses.
static LLVM_ABI std::string getMemoryLocationsAsStr(MemoryLocationsKind MLK)
Return the locations encoded by MLK as a readable string.
bool isKnownArgMemOnly() const
Return true if we know that the underlying value will only access argument pointees (see Attribute::A...
bool isKnownInaccessibleOrArgMemOnly() const
Return true if we know that the underlying value will only access inaccesible memory or argument poin...
static LLVM_ABI const char ID
Unique ID (due to the unique address)
AAMemoryLocation(const IRPosition &IRP, Attributor &A)
bool isKnownReadNone() const
Return true if we know that the associated functions has no observable accesses.
bool isAssumedSpecifiedMemOnly(MemoryLocationsKind MLK) const
Return true if only the memory locations specififed by MLK are assumed to be accessed by the associat...
bool isAssumedInaccessibleMemOnly() const
Return true if we assume that the underlying value will only access inaccesible memory only (see Attr...
bool isKnownInaccessibleMemOnly() const
Return true if we know that the underlying value will only access inaccesible memory only (see Attrib...
static LLVM_ABI AAMemoryLocation & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
bool isAssumedInaccessibleOrArgMemOnly() const
Return true if we assume that the underlying value will only access inaccesible memory or argument po...
bool isKnowStackOnly() const
Return true if we know that the associated functions has at most local/stack accesses.
static bool requiresCalleeForCallBase()
AccessKind
Simple enum to distinguish read/write/read-write accesses.
StateType::base_t MemoryLocationsKind
MemoryLocationsKind getAssumedNotAccessedLocation() const
Return the locations that are assumed to be not accessed by the associated function,...
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAMemoryLocation.
static bool hasTrivialInitializer()
bool isAssumedReadNone() const
Return true if we assume that the associated functions has no observable accesses.
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
virtual bool checkForAllAccessesToMemoryKind(function_ref< bool(const Instruction *, const Value *, AccessKind, MemoryLocationsKind)> Pred, MemoryLocationsKind MLK) const =0
Check Pred on all accesses to the memory kinds specified by MLK.
const std::string getAsStr(Attributor *A) const override
This function should return the "summarized" assumed state as string.
bool mayAccessArgMem() const
Return true if the underlying value may access memory through arguement pointers of the associated fu...
bool isAssumedArgMemOnly() const
Return true if we assume that the underlying value will only access argument pointees (see Attribute:...
static MemoryLocationsKind inverseLocation(MemoryLocationsKind Loc, bool AndLocalMem, bool AndConstMem)
Return the inverse of location Loc, thus for NO_XXX the return describes ONLY_XXX.
An abstract interface for all nonnull attributes.
StringRef getName() const override
This function should return the name of the AbstractAttribute.
bool isKnownMustProgress() const
Return true if we know that underlying value is nonnull.
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAMustProgress.
bool isAssumedMustProgress() const
Return true if we assume that the underlying value is nonnull.
static bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
const char * getIdAddr() const override
This function should return the address of the ID of the AbstractAttribute.
static LLVM_ABI AAMustProgress & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
AAMustProgress(const IRPosition &IRP, Attributor &A)
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAAssumptionInfo.
static bool requiresCallersForArgOrFunction()
IntervalMap< unsigned, bool > RangeMap
static LLVM_ABI AANoAliasAddrSpace & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
static LLVM_ABI const char ID
Unique ID (due to the unique address)
AANoAliasAddrSpace(const IRPosition &IRP, Attributor &A)
const char * getIdAddr() const override
This function should return the address of the ID of the AbstractAttribute.
StateWrapper< BooleanState, AbstractAttribute > Base
RangeMap::Allocator Allocator
StringRef getName() const override
This function should return the name of the AbstractAttribute.
An abstract interface for all noalias attributes.
static LLVM_ABI bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
---------------------— NoAlias Argument Attribute ---------------------—
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AANoAlias.
StringRef getName() const override
This function should return the name of the AbstractAttribute.
static bool requiresCallersForArgOrFunction()
const char * getIdAddr() const override
This function should return the address of the ID of the AbstractAttribute.
bool isKnownNoAlias() const
Return true if we know that underlying value is noalias.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
bool isAssumedNoAlias() const
Return true if we assume that the underlying value is alias.
static LLVM_ABI AANoAlias & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
AANoAlias(const IRPosition &IRP, Attributor &A)
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
An abstract interface for all nocapture attributes.
static LLVM_ABI AANoCapture & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
@ NO_CAPTURE_MAYBE_RETURNED
If we do not capture the value in memory or through integers we can only communicate it back as a der...
@ NO_CAPTURE
If we do not capture the value in memory, through integers, or as a derived pointer we know it is not...
const char * getIdAddr() const override
This function should return the address of the ID of the AbstractAttribute.
AANoCapture(const IRPosition &IRP, Attributor &A)
StringRef getName() const override
This function should return the name of the AbstractAttribute.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
bool isAssumedNoCaptureMaybeReturned() const
Return true if we assume that the underlying value is not captured in its respective scope but we all...
bool isKnownNoCapture() const
Return true if we know that the underlying value is not captured in its respective scope.
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AANoCapture.
bool isKnownNoCaptureMaybeReturned() const
Return true if we know that the underlying value is not captured in its respective scope but we allow...
static LLVM_ABI bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
--------------------— Variable Capturing ------------------------------—
bool isAssumedNoCapture() const
Return true if we assume that the underlying value is not captured in its respective scope.
static LLVM_ABI void determineFunctionCaptureCapabilities(const IRPosition &IRP, const Function &F, BitIntegerState &State)
Update State according to the capture capabilities of F for position IRP.
FPClassTest getAssumedNoFPClass() const
Return the underlying assumed nofpclass.
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
AANoFPClass(const IRPosition &IRP, Attributor &A)
StringRef getName() const override
This function should return the name of the AbstractAttribute.
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AANoFPClass.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
const char * getIdAddr() const override
This function should return the address of the ID of the AbstractAttribute.
FPClassTest getKnownNoFPClass() const
Return the underlying known nofpclass.
StateWrapper< BitIntegerState< uint32_t, fcAllFlags, fcNone >, AbstractAttribute > Base
static LLVM_ABI AANoFPClass & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
An AbstractAttribute for nofree.
bool isKnownNoFree() const
Return true if "nofree" is known.
static LLVM_ABI AANoFree & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
AANoFree(const IRPosition &IRP, Attributor &A)
static bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
bool isAssumedNoFree() const
Return true if "nofree" is assumed.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AANoFree.
StringRef getName() const override
This function should return the name of the AbstractAttribute.
const char * getIdAddr() const override
This function should return the address of the ID of the AbstractAttribute.
An abstract attribute for norecurse.
StringRef getName() const override
This function should return the name of the AbstractAttribute.
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AANoRecurse.
AANoRecurse(const IRPosition &IRP, Attributor &A)
const char * getIdAddr() const override
This function should return the address of the ID of the AbstractAttribute.
bool isAssumedNoRecurse() const
Return true if "norecurse" is assumed.
static LLVM_ABI AANoRecurse & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
bool isKnownNoRecurse() const
Return true if "norecurse" is known.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An AbstractAttribute for noreturn.
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AANoReturn.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
bool isAssumedNoReturn() const
Return true if the underlying object is assumed to never return.
static LLVM_ABI AANoReturn & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
StringRef getName() const override
This function should return the name of the AbstractAttribute.
AANoReturn(const IRPosition &IRP, Attributor &A)
const char * getIdAddr() const override
This function should return the address of the ID of the AbstractAttribute.
bool isKnownNoReturn() const
Return true if the underlying object is known to never return.
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
AANoSync(const IRPosition &IRP, Attributor &A)
const char * getIdAddr() const override
This function should return the address of the ID of the AbstractAttribute.
StringRef getName() const override
This function should return the name of the AbstractAttribute.
static bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI bool isAlignedBarrier(const CallBase &CB, bool ExecutedAligned)
Helper function to determine if CB is an aligned (GPU) barrier.
bool isAssumedNoSync() const
Returns true if "nosync" is assumed.
static LLVM_ABI bool isNonRelaxedAtomic(const Instruction *I)
Helper function used to determine whether an instruction is non-relaxed atomic.
bool isKnownNoSync() const
Returns true if "nosync" is known.
static LLVM_ABI AANoSync & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AANoSync.
An abstract interface for all noundef attributes.
bool isKnownNoUndef() const
Return true if we know that underlying value is noundef.
static bool isImpliedByUndef()
StringRef getName() const override
This function should return the name of the AbstractAttribute.
bool isAssumedNoUndef() const
Return true if we assume that the underlying value is noundef.
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AANoUndef.
const char * getIdAddr() const override
This function should return the address of the ID of the AbstractAttribute.
static LLVM_ABI AANoUndef & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
AANoUndef(const IRPosition &IRP, Attributor &A)
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static bool isImpliedByPoison()
static LLVM_ABI bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
---------------------— NoUndef Attribute ------------------------------—
AANoUnwind(const IRPosition &IRP, Attributor &A)
bool isAssumedNoUnwind() const
Returns true if nounwind is assumed.
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AANoUnwind.
StringRef getName() const override
This function should return the name of the AbstractAttribute.
static LLVM_ABI AANoUnwind & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
bool isKnownNoUnwind() const
Returns true if nounwind is known.
const char * getIdAddr() const override
This function should return the address of the ID of the AbstractAttribute.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
const char * getIdAddr() const override
This function should return the address of the ID of the AbstractAttribute.
StateWrapper< BooleanState, AbstractAttribute > Base
static LLVM_ABI AANonConvergent & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
StringRef getName() const override
This function should return the name of the AbstractAttribute.
bool isAssumedNotConvergent() const
Return true if "non-convergent" is assumed.
bool isKnownNotConvergent() const
Return true if "non-convergent" is known.
AANonConvergent(const IRPosition &IRP, Attributor &A)
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AANonConvergent.
An abstract interface for all nonnull attributes.
static bool isImpliedByUndef()
Undef is not necessarily nonnull as nonnull + noundef would cause poison.
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
static LLVM_ABI const char ID
Unique ID (due to the unique address)
const char * getIdAddr() const override
This function should return the address of the ID of the AbstractAttribute.
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AANonNull.
static LLVM_ABI AANonNull & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
AANonNull(const IRPosition &IRP, Attributor &A)
StringRef getName() const override
This function should return the name of the AbstractAttribute.
static LLVM_ABI bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
---------------------— NonNull Argument Attribute ---------------------—
bool isAssumedNonNull() const
Return true if we assume that the underlying value is nonnull.
bool isKnownNonNull() const
Return true if we know that underlying value is nonnull.
static bool hasTrivialInitializer()
An access description.
bool isWrittenValueUnknown() const
Return true if the value written cannot be determined at all.
const_iterator end() const
bool operator!=(const Access &R) const
std::optional< Value * > getContent() const
Return the written value which can be llvm::null if it is not yet determined.
Access & operator=(const Access &Other)=default
bool isAssumption() const
Return true if this is an assumption access.
const RangeList & getRanges() const
bool isWriteOrAssumption() const
Return true if this is a write access.
bool isRead() const
Return true if this is a read access.
bool isWrite() const
Return true if this is a write access.
Value * getWrittenValue() const
Return the value writen, if any.
Instruction * getLocalInst() const
Return the instruction that causes the access with respect to the local scope of the associated attri...
Access(Instruction *LocalI, Instruction *RemoteI, const RangeList &Ranges, std::optional< Value * > Content, AccessKind K, Type *Ty)
Access(Instruction *LocalI, Instruction *RemoteI, int64_t Offset, int64_t Size, std::optional< Value * > Content, AccessKind Kind, Type *Ty)
Access(Instruction *I, int64_t Offset, int64_t Size, std::optional< Value * > Content, AccessKind Kind, Type *Ty)
Access(const Access &Other)=default
Type * getType() const
Return the type associated with the access, if known.
Access & operator&=(const Access &R)
const_iterator begin() const
RangeList::const_iterator const_iterator
Instruction * getRemoteInst() const
Return the actual instruction that causes the access.
bool operator==(const Access &R) const
bool isWrittenValueYetUndetermined() const
Return true if the value written is not known yet.
AccessKind getKind() const
Return the access kind.
A helper containing a list of offsets computed for a Use.
SmallSet< int64_t, 4 > VecTy
VecTy::const_iterator const_iterator
bool operator==(const OffsetInfo &RHS) const
bool insert(int64_t Offset)
bool operator!=(const OffsetInfo &RHS) const
const_iterator begin() const
const_iterator end() const
bool merge(const OffsetInfo &R)
Copy offsets from R into the current list.
A container for a list of ranges.
const_iterator end() const
SmallVector< RangeTy > VecTy
void addToAllOffsets(int64_t Inc)
Add the increment Inc to the offset of every range.
bool operator==(const RangeList &OI) const
RangeList(ArrayRef< int64_t > Offsets, int64_t Size)
std::pair< iterator, bool > insert(iterator Pos, const RangeTy &R)
Insert R at the given iterator Pos, and merge if necessary.
bool isUnknown() const
Return true iff the list contains an unknown range.
VecTy::const_iterator const_iterator
const_iterator begin() const
bool isUnassigned() const
Return true if no ranges have been inserted.
static void set_difference(const RangeList &L, const RangeList &R, RangeList &D)
Copy ranges from L that are not in R, into D.
bool merge(const RangeList &RHS)
Merge the ranges in RHS into the current ranges.
iterator setUnknown()
Discard all ranges and insert a single unknown range.
void push_back(const RangeTy &R)
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
virtual bool reachesReturn() const =0
StringRef getName() const override
This function should return the name of the AbstractAttribute.
virtual bool forallInterferingAccesses(Attributor &A, const AbstractAttribute &QueryingAA, Instruction &I, bool FindInterferingWrites, bool FindInterferingReads, function_ref< bool(const Access &, bool)> CB, bool &HasBeenWrittenTo, AA::RangeTy &Range, function_ref< bool(const Access &)> SkipCB=nullptr) const =0
Call CB on all accesses that might interfere with I and return true if all such accesses were known a...
virtual void addReturnedOffsetsTo(OffsetInfo &) const =0
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAPointerInfo.
OffsetBinsTy::const_iterator const_bin_iterator
const char * getIdAddr() const override
This function should return the address of the ID of the AbstractAttribute.
virtual const_bin_iterator begin() const =0
DenseMap< AA::RangeTy, SmallSet< unsigned, 4 > > OffsetBinsTy
virtual bool forallInterferingAccesses(AA::RangeTy Range, function_ref< bool(const Access &, bool)> CB) const =0
Call CB on all accesses that might interfere with Range and return true if all such accesses were kno...
virtual const_bin_iterator end() const =0
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI AAPointerInfo & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
AAPointerInfo(const IRPosition &IRP)
virtual int64_t numOffsetBins() const =0
An abstract interface for potential values analysis.
PotentialConstantIntValuesState & getState() override
Return the internal abstract state for inspection.
const PotentialConstantIntValuesState & getState() const override
AAPotentialConstantValues(const IRPosition &IRP, Attributor &A)
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAPotentialConstantValues.
static bool requiresCallersForArgOrFunction()
unsigned getAssumedMinTrailingZeros() const
Return the minimum trailing zeros of potential constants.
std::optional< Constant * > getAssumedConstant(Attributor &A, const Instruction *CtxI=nullptr) const
Return assumed constant for the associated value.
StateWrapper< PotentialConstantIntValuesState, AbstractAttribute > Base
static LLVM_ABI AAPotentialConstantValues & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
const char * getIdAddr() const override
This function should return the address of the ID of the AbstractAttribute.
StringRef getName() const override
This function should return the name of the AbstractAttribute.
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
friend struct Attributor
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAPotentialValues.
PotentialLLVMValuesState & getState() override
Return the internal abstract state for inspection.
AAPotentialValues(const IRPosition &IRP, Attributor &A)
static LLVM_ABI AAPotentialValues & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
static bool requiresCallersForArgOrFunction()
StateWrapper< PotentialLLVMValuesState, AbstractAttribute > Base
const PotentialLLVMValuesState & getState() const override
const char * getIdAddr() const override
This function should return the address of the ID of the AbstractAttribute.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
StringRef getName() const override
This function should return the name of the AbstractAttribute.
static LLVM_ABI Value * getSingleValue(Attributor &A, const AbstractAttribute &AA, const IRPosition &IRP, SmallVectorImpl< AA::ValueAndContext > &Values)
Extract the single value in Values if any.
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
bool isAssumedPrivatizablePtr() const
Returns true if pointer privatization is assumed to be possible.
virtual std::optional< Type * > getPrivatizableType() const =0
Return the type we can choose for a private copy of the underlying value.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
StringRef getName() const override
This function should return the name of the AbstractAttribute.
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAPricatizablePtr.
static bool requiresCallersForArgOrFunction()
static LLVM_ABI AAPrivatizablePtr & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
AAPrivatizablePtr(const IRPosition &IRP, Attributor &A)
const char * getIdAddr() const override
This function should return the address of the ID of the AbstractAttribute.
StateWrapper< BooleanState, AbstractAttribute > Base
static LLVM_ABI AAUndefinedBehavior & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
const char * getIdAddr() const override
This function should return the address of the ID of the AbstractAttribute.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
virtual bool isAssumedToCauseUB(Instruction *I) const =0
Return true if "undefined behavior" is assumed for a specific instruction.
StateWrapper< BooleanState, AbstractAttribute > Base
AAUndefinedBehavior(const IRPosition &IRP, Attributor &A)
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAUndefineBehavior.
StringRef getName() const override
This function should return the name of the AbstractAttribute.
virtual bool isKnownToCauseUB(Instruction *I) const =0
Return true if "undefined behavior" is known for a specific instruction.
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
virtual bool forallUnderlyingObjects(function_ref< bool(Value &)> Pred, AA::ValueScope Scope=AA::Interprocedural) const =0
Check Pred on all underlying objects in Scope collected so far.
const char * getIdAddr() const override
This function should return the address of the ID of the AbstractAttribute.
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAUnderlyingObjects.
static LLVM_ABI AAUnderlyingObjects & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute biew for the position IRP.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
AAUnderlyingObjects(const IRPosition &IRP)
static bool requiresCallersForArgOrFunction()
StringRef getName() const override
This function should return the name of the AbstractAttribute.
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
StringRef getName() const override
This function should return the name of the AbstractAttribute.
std::optional< Constant * > getAssumedConstant(Attributor &A, const Instruction *CtxI=nullptr) const
Return an assumed constant for the associated value a program point CtxI.
virtual ConstantRange getAssumedConstantRange(Attributor &A, const Instruction *CtxI=nullptr) const =0
Return an assumed range for the associated value a program point CtxI.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static bool requiresCallersForArgOrFunction()
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAValueConstantRange.
AAValueConstantRange(const IRPosition &IRP, Attributor &A)
static LLVM_ABI AAValueConstantRange & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
StateWrapper< IntegerRangeState, AbstractAttribute, uint32_t > Base
const char * getIdAddr() const override
This function should return the address of the ID of the AbstractAttribute.
IntegerRangeState & getState() override
Return the internal abstract state for inspection.
const IntegerRangeState & getState() const override
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAValueSimplify.
friend struct Attributor
StringRef getName() const override
This function should return the name of the AbstractAttribute.
StateWrapper< ValueSimplifyStateType, AbstractAttribute, Type * > Base
static LLVM_ABI const char ID
Unique ID (due to the unique address)
const char * getIdAddr() const override
This function should return the address of the ID of the AbstractAttribute.
static LLVM_ABI AAValueSimplify & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
AAValueSimplify(const IRPosition &IRP, Attributor &A)
An abstract attribute for willreturn.
bool isKnownWillReturn() const
Return true if "willreturn" is known.
const char * getIdAddr() const override
This function should return the address of the ID of the AbstractAttribute.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI AAWillReturn & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
StringRef getName() const override
This function should return the name of the AbstractAttribute.
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAWillReturn.
AAWillReturn(const IRPosition &IRP, Attributor &A)
static bool isImpliedByMustprogressAndReadonly(Attributor &A, const IRPosition &IRP)
Check for mustprogress and readonly as they imply willreturn.
static bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
bool isAssumedWillReturn() const
Return true if "willreturn" is assumed.
Helper to represent an access offset and size, with logic to deal with uncertainty and check for over...
Definition Attributor.h:245
bool offsetAndSizeAreUnknown() const
Return true if offset and size are unknown, thus this is the default unknown object.
Definition Attributor.h:260
static constexpr int64_t Unknown
Definition Attributor.h:324
bool offsetOrSizeAreUnknown() const
Return true if offset or size are unknown.
Definition Attributor.h:254
static constexpr int64_t Unassigned
Constants used to represent special offsets or sizes.
Definition Attributor.h:323
RangeTy & operator&=(const RangeTy &R)
Definition Attributor.h:283
static RangeTy getUnknown()
Definition Attributor.h:251
bool isUnassigned() const
Return true if the offset and size are unassigned.
Definition Attributor.h:265
static bool LessThan(const RangeTy &L, const RangeTy &R)
Comparison for sorting ranges.
Definition Attributor.h:309
bool mayOverlap(const RangeTy &Range) const
Return true if this offset and size pair might describe an address that overlaps with Range.
Definition Attributor.h:273
RangeTy(int64_t Offset, int64_t Size)
Definition Attributor.h:249
Value * getValue() const
Definition Attributor.h:198
std::pair< Value *, const Instruction * > Base
Definition Attributor.h:193
ValueAndContext(Value &V, const Instruction *CtxI)
Definition Attributor.h:195
const Instruction * getCtxI() const
Definition Attributor.h:199
ValueAndContext(Value &V, const Instruction &CtxI)
Definition Attributor.h:196
ValueAndContext(const Base &B)
Definition Attributor.h:194
Base struct for all "concrete attribute" deductions.
ChangeStatus update(Attributor &A)
Hook for the Attributor to trigger an update of the internal state.
friend struct Attributor
}
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
Return false if an AA should not be created for IRP.
virtual ChangeStatus manifest(Attributor &A)
Hook for the Attributor to trigger the manifestation of the information represented by the abstract a...
static bool classof(const AADepGraphNode *DGN)
This function is used to identify if an DGN is of type AbstractAttribute so that the dyn_cast and cas...
virtual bool isStateAtFixpoint() const
Return true if the state is at a fixpoint, like getState().isAtFixpoint() but with a single virtual c...
static bool requiresCalleeForCallBase()
Return true if this AA requires a "callee" (or an associted function) for a call site positon.
void print(raw_ostream &OS) const
Helper functions, for debug purposes only.
IRPosition & getIRPosition()
virtual StateType & getState()=0
Return the internal abstract state for inspection.
virtual void initialize(Attributor &A)
Initialize the state with the information in the Attributor A.
static bool isValidIRPositionForUpdate(Attributor &A, const IRPosition &IRP)
Return false if an AA should not be updated for IRP.
AbstractState StateType
virtual const std::string getAsStr(Attributor *A) const =0
This function should return the "summarized" assumed state as string.
~AbstractAttribute() override=default
Virtual destructor.
static constexpr Attribute::AttrKind IRAttributeKind
Compile time access to the IR attribute kind.
virtual bool isQueryAA() const
A query AA is always scheduled as long as we do updates because it does lazy computation that cannot ...
virtual const StateType & getState() const =0
AbstractAttribute(const IRPosition &IRP)
static bool requiresNonAsmForCallBase()
Return true if this AA requires non-asm "callee" for a call site positon.
virtual ChangeStatus updateImpl(Attributor &A)=0
The actual update/transfer function which has to be implemented by the derived classes.
virtual void trackStatistics() const =0
Hook to enable custom statistic tracking, called after manifest that resulted in a change if statisti...
static bool requiresCallersForArgOrFunction()
Return true if this AA requires all callees for an argument or function positon.
virtual StringRef getName() const =0
This function should return the name of the AbstractAttribute.
const IRPosition & getIRPosition() const
Return an IR position, see struct IRPosition.
virtual const char * getIdAddr() const =0
This function should return the address of the ID of the AbstractAttribute.
static bool hasTrivialInitializer()
Return false if this AA does anything non-trivial (hence not done by default) in its initializer.
An interface to query the internal state of an abstract attribute.
virtual ~AbstractState()=default
virtual ChangeStatus indicatePessimisticFixpoint()=0
Indicate that the abstract state should converge to the pessimistic state.
virtual bool isAtFixpoint() const =0
Return if this abstract state is fixed, thus does not need to be updated if information changes as it...
virtual bool isValidState() const =0
Return if this abstract state is in a valid state.
virtual ChangeStatus indicateOptimisticFixpoint()=0
Indicate that the abstract state should converge to the optimistic state.
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
Wrapper for FunctionAnalysisManager.
AnalysisGetter()=default
static constexpr bool HasLegacyWrapper
Analysis::Result * getAnalysis(const Function &F, bool RequestCachedOnly=false)
AnalysisGetter(FunctionAnalysisManager &FAM, bool CachedOnly=false)
void invalidateAnalyses()
Invalidates the analyses. Valid only when using the new pass manager.
AnalysisGetter(Pass *P, bool CachedOnly=false)
LLVM_ABI PreservedAnalyses run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM, LazyCallGraph &CG, CGSCCUpdateResult &UR)
~AttributorCallGraph() override=default
AACallEdgeIterator optimisticEdgesEnd() const override
AttributorCallGraph(Attributor &A)
AACallEdgeIterator optimisticEdgesBegin() const override
void populateAll() const
Force populate the entire call graph.
Configuration for the Attributor.
bool UseLiveness
Flag to determine if we should skip all liveness checks early on.
std::function< void(Attributor &A, const Function &F)> InitializationCallback
Callback function to be invoked on internal functions marked live.
std::optional< unsigned > MaxFixpointIterations
Maximum number of iterations to run until fixpoint.
bool RewriteSignatures
Flag to determine if we rewrite function signatures.
const char * PassName
}
OptimizationRemarkGetter OREGetter
bool DeleteFns
Flag to determine if we can delete functions or keep dead ones around.
std::function< bool(const Function &F)> IPOAmendableCBTy
bool IsClosedWorldModule
Flag to indicate if the entire world is contained in this module, that is, no outside functions exist...
function_ref< OptimizationRemarkEmitter &(Function *)> OptimizationRemarkGetter
A callback function that returns an ORE object from a Function pointer.
CallGraphUpdater & CGUpdater
Helper to update an underlying call graph and to delete functions.
std::optional< AAKindSet > Allowed
If set, the only kinds of abstract attributes to create.
IPOAmendableCBTy IPOAmendableCB
bool IsModulePass
Is the user of the Attributor a module pass or not.
std::function< bool(Attributor &A, const AbstractAttribute &AA, CallBase &CB, Function &AssumedCallee, unsigned NumAssumedCallees)> IndirectCalleeSpecializationCallback
Callback function to determine if an indirect call targets should be made direct call targets (with a...
bool DefaultInitializeLiveInternals
Flag to determine if we want to initialize all default AAs for an internal function marked live.
AttributorConfig(CallGraphUpdater &CGUpdater)
A more lightweight version of the Attributor which only runs attribute inference but no simplificatio...
LLVM_ABI PreservedAnalyses run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM, LazyCallGraph &CG, CGSCCUpdateResult &UR)
A more lightweight version of the Attributor which only runs attribute inference but no simplificatio...
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
Helper struct used in the communication between an abstract attribute (AA) that wants to change the s...
friend struct Attributor
Allow access to the private members from the Attributor.
std::function< void( const ArgumentReplacementInfo &, Function &, Function::arg_iterator)> CalleeRepairCBTy
Callee repair callback type.
const Argument & getReplacedArg() const
Attributor & getAttributor() const
Simple getters, see the corresponding members for details.
const Function & getReplacedFn() const
std::function< void(const ArgumentReplacementInfo &, AbstractCallSite, SmallVectorImpl< Value * > &)> ACSRepairCBTy
Abstract call site (ACS) repair callback type.
The fixpoint analysis framework that orchestrates the attribute deduction.
LLVM_ABI bool registerFunctionSignatureRewrite(Argument &Arg, ArrayRef< Type * > ReplacementTypes, ArgumentReplacementInfo::CalleeRepairCBTy &&CalleeRepairCB, ArgumentReplacementInfo::ACSRepairCBTy &&ACSRepairCB)
Register a rewrite for a function signature.
AAType & registerAA(AAType &AA)
Introduce a new abstract attribute into the fixpoint analysis.
LLVM_ABI ~Attributor()
const SmallSetVector< Function *, 8 > & getAttrModifiedFunctions()
Return the functions whose attributes, or whose call site attributes, were changed.
LLVM_ABI bool checkForAllCallees(function_ref< bool(ArrayRef< const Function * > Callees)> Pred, const AbstractAttribute &QueryingAA, const CallBase &CB)
Check Pred on all potential Callees of CB.
bool isModulePass() const
Return true if this is a module pass, false otherwise.
void registerInvokeWithDeadSuccessor(InvokeInst &II)
Record that II has at least one dead successor block.
void registerSimplificationCallback(const IRPosition &IRP, const SimplifictionCallbackTy &CB)
bool changeAfterManifest(const IRPosition IRP, Value &NV, bool ChangeDroppable=true)
Helper function to replace all uses associated with IRP with NV.
LLVM_ABI bool isValidFunctionSignatureRewrite(Argument &Arg, ArrayRef< Type * > ReplacementTypes)
Check if we can rewrite a function signature.
static LLVM_ABI bool isInternalizable(Function &F)
Returns true if the function F can be internalized.
LLVM_ABI ChangeStatus removeAttrs(const IRPosition &IRP, ArrayRef< Attribute::AttrKind > AttrKinds)
Remove all AttrKinds attached to IRP.
void emitRemark(Instruction *I, StringRef RemarkName, RemarkCallBack &&RemarkCB) const
Emit a remark generically.
bool isRunOn(Function &Fn) const
Return true if we derive attributes for Fn.
LLVM_ABI bool isAssumedDead(const AbstractAttribute &AA, const AAIsDead *LivenessAA, bool &UsedAssumedInformation, bool CheckBBLivenessOnly=false, DepClassTy DepClass=DepClassTy::OPTIONAL)
Return true if AA (or its context instruction) is assumed dead.
LLVM_ABI bool checkForAllInstructions(function_ref< bool(Instruction &)> Pred, const Function *Fn, const AbstractAttribute *QueryingAA, ArrayRef< unsigned > Opcodes, bool &UsedAssumedInformation, bool CheckBBLivenessOnly=false, bool CheckPotentiallyDead=false)
Check Pred on all instructions in Fn with an opcode present in Opcodes.
LLVM_ABI void recordDependence(const AbstractAttribute &FromAA, const AbstractAttribute &ToAA, DepClassTy DepClass)
Explicitly record a dependence from FromAA to ToAA, that is if FromAA changes ToAA should be updated ...
static LLVM_ABI void createShallowWrapper(Function &F)
Create a shallow wrapper for F such that F has internal linkage afterwards.
bool isRunOn(Function *Fn) const
bool isDuringDeduction() const
Return whether attributes can participate in fixed-point deduction.
const AAType * getAAFor(const AbstractAttribute &QueryingAA, const IRPosition &IRP, DepClassTy DepClass)
Lookup an abstract attribute of type AAType at position IRP.
std::function< std::optional< Value * >( const IRPosition &, const AbstractAttribute *, bool &)> SimplifictionCallbackTy
Register CB as a simplification callback.
std::optional< Constant * > getAssumedInitializerFromCallBack(const GlobalVariable &GV, const AbstractAttribute *AA, bool &UsedAssumedInformation)
Return std::nullopt if there is no call back registered for GV or the call back is still not sure if ...
void deleteAfterManifest(Function &F)
Record that F is deleted after information was manifested.
std::optional< Value * > getAssumedSimplified(const IRPosition &IRP, const AbstractAttribute &AA, bool &UsedAssumedInformation, AA::ValueScope S)
If V is assumed simplified, return it, if it is unclear yet, return std::nullopt, otherwise return nu...
void emitRemark(Function *F, StringRef RemarkName, RemarkCallBack &&RemarkCB) const
Emit a remark on a function.
static LLVM_ABI Function * internalizeFunction(Function &F, bool Force=false)
Make another copy of the function F such that the copied version has internal linkage afterwards and ...
bool isFunctionIPOAmendable(const Function &F)
Determine whether the function F is IPO amendable.
const AAType * getOrCreateAAFor(IRPosition IRP, const AbstractAttribute *QueryingAA, DepClassTy DepClass, bool ForceUpdate=false, bool UpdateAfterInit=true)
The version of getAAFor that allows to omit a querying abstract attribute.
const SmallSetVector< Function *, 8 > & getModifiedFunctions()
LLVM_ABI bool checkForAllReadWriteInstructions(function_ref< bool(Instruction &)> Pred, AbstractAttribute &QueryingAA, bool &UsedAssumedInformation)
Check Pred on all Read/Write instructions.
void changeToUnreachableAfterManifest(Instruction *I)
Record that I is to be replaced with unreachable after information was manifested.
bool hasGlobalVariableSimplificationCallback(const GlobalVariable &GV)
Return true if there is a simplification callback for GV.
std::optional< Constant * > getAssumedConstant(const Value &V, const AbstractAttribute &AA, bool &UsedAssumedInformation)
LLVM_ABI bool checkForAllReturnedValues(function_ref< bool(Value &)> Pred, const AbstractAttribute &QueryingAA, AA::ValueScope S=AA::ValueScope::Intraprocedural, bool RecurseForSelectAndPHI=true)
Check Pred on all values potentially returned by the function associated with QueryingAA.
bool hasSimplificationCallback(const IRPosition &IRP)
Return true if there is a simplification callback for IRP.
std::function< std::optional< Constant * >( const GlobalVariable &, const AbstractAttribute *, bool &)> GlobalVariableSimplifictionCallbackTy
Register CB as a simplification callback.
LLVM_ABI bool isClosedWorldModule() const
Return true if the module contains the whole world, thus, no outside functions exist.
LLVM_ABI std::optional< Constant * > getAssumedConstant(const IRPosition &IRP, const AbstractAttribute &AA, bool &UsedAssumedInformation)
If IRP is assumed to be a constant, return it, if it is unclear yet, return std::nullopt,...
const AAType * getOrCreateAAFor(const IRPosition &IRP)
LLVM_ABI Attributor(SetVector< Function * > &Functions, InformationCache &InfoCache, AttributorConfig Configuration)
Constructor.
void registerGlobalVariableSimplificationCallback(const GlobalVariable &GV, const GlobalVariableSimplifictionCallbackTy &CB)
const DataLayout & getDataLayout() const
Return the data layout associated with the anchor scope.
LLVM_ABI void getAttrs(const IRPosition &IRP, ArrayRef< Attribute::AttrKind > AKs, SmallVectorImpl< Attribute > &Attrs, bool IgnoreSubsumingPositions=false)
Return the attributes of any kind in AKs existing in the IR at a position that will affect this one.
InformationCache & getInfoCache()
Return the internal information cache.
bool changeUseAfterManifest(Use &U, Value &NV)
Record that U is to be replaces with NV after information was manifested.
LLVM_ABI std::optional< Value * > translateArgumentToCallSiteContent(std::optional< Value * > V, CallBase &CB, const AbstractAttribute &AA, bool &UsedAssumedInformation)
Translate V from the callee context into the call site context.
AAType * lookupAAFor(const IRPosition &IRP, const AbstractAttribute *QueryingAA=nullptr, DepClassTy DepClass=DepClassTy::OPTIONAL, bool AllowInvalidState=false)
Return the attribute of AAType for IRP if existing and valid.
void markLiveInternalFunction(const Function &F)
Mark the internal function F as live.
void registerManifestAddedBasicBlock(BasicBlock &BB)
void registerVirtualUseCallback(const Value &V, const VirtualUseCallbackTy &CB)
LLVM_ABI bool checkForAllUses(function_ref< bool(const Use &, bool &)> Pred, const AbstractAttribute &QueryingAA, const Value &V, bool CheckBBLivenessOnly=false, DepClassTy LivenessDepClass=DepClassTy::OPTIONAL, bool IgnoreDroppableUses=true, function_ref< bool(const Use &OldU, const Use &NewU)> EquivalentUseCB=nullptr)
Check Pred on all (transitive) uses of V.
LLVM_ABI ChangeStatus manifestAttrs(const IRPosition &IRP, ArrayRef< Attribute > DeducedAttrs, bool ForceReplace=false)
Attach DeducedAttrs to IRP, if ForceReplace is set we do this even if the same attribute kind was alr...
LLVM_ABI bool hasAttr(const IRPosition &IRP, ArrayRef< Attribute::AttrKind > AKs, bool IgnoreSubsumingPositions=false, Attribute::AttrKind ImpliedAttributeKind=Attribute::None)
Return true if any kind in AKs existing in the IR at a position that will affect this one.
LLVM_ABI void registerForUpdate(AbstractAttribute &AA)
Allows a query AA to request an update if a new query was received.
const Module & getModule()
Return the module.
void deleteAfterManifest(Instruction &I)
Record that I is deleted after information was manifested.
std::function< bool(Attributor &, const AbstractAttribute *)> VirtualUseCallbackTy
void deleteAfterManifest(BasicBlock &BB)
Record that BB is deleted after information was manifested.
LLVM_ABI void identifyDefaultAbstractAttributes(Function &F)
Determine opportunities to derive 'default' attributes in F and create abstract attribute objects for...
bool shouldInitialize(const IRPosition &IRP, bool &ShouldUpdateAA)
LLVM_ABI bool getAssumedSimplifiedValues(const IRPosition &IRP, const AbstractAttribute *AA, SmallVectorImpl< AA::ValueAndContext > &Values, AA::ValueScope S, bool &UsedAssumedInformation, bool RecurseForSelectAndPHI=true)
Try to simplify IRP and in the scope S.
BumpPtrAllocator & Allocator
The allocator used to allocate memory, e.g. for AbstractAttributes.
bool checkForAllCallLikeInstructions(function_ref< bool(Instruction &)> Pred, const AbstractAttribute &QueryingAA, bool &UsedAssumedInformation, bool CheckBBLivenessOnly=false, bool CheckPotentiallyDead=false)
Check Pred on all call-like instructions (=CallBased derived).
bool shouldSpecializeCallSiteForCallee(const AbstractAttribute &AA, CallBase &CB, Function &Callee, unsigned NumAssumedCallees)
Return true if we should specialize the call site CB for the potential callee Fn.
LLVM_ABI ChangeStatus run()
Run the analyses until a fixpoint is reached or enforced (timeout).
static LLVM_ABI bool internalizeFunctions(SmallPtrSetImpl< Function * > &FnSet, DenseMap< Function *, Function * > &FnMap)
Make copies of each function in the set FnSet such that the copied version has internal linkage after...
std::optional< Value * > getAssumedSimplified(const Value &V, const AbstractAttribute &AA, bool &UsedAssumedInformation, AA::ValueScope S)
bool shouldUpdateAA(const IRPosition &IRP)
LLVM_ABI bool checkForAllCallSites(function_ref< bool(AbstractCallSite)> Pred, const AbstractAttribute &QueryingAA, bool RequireAllCallSites, bool &UsedAssumedInformation)
Check Pred on all function call sites.
LLVM_ABI bool getAttrsFromAssumes(const IRPosition &IRP, Attribute::AttrKind AK, SmallVectorImpl< Attribute > &Attrs)
Return the attributes of kind AK existing in the IR as operand bundles of an llvm....
Specialization of the integer state for a bit-wise encoding.
BitIntegerState & removeKnownBits(base_t BitsEncoding)
Remove the bits in BitsEncoding from the "known bits".
bool isAssumed(base_t BitsEncoding=BestState) const
Return true if the bits set in BitsEncoding are "assumed bits".
IntegerStateBase< base_ty, BestState, WorstState > super
BitIntegerState(base_t Assumed)
BitIntegerState & removeAssumedBits(base_t BitsEncoding)
Remove the bits in BitsEncoding from the "assumed bits" if not known.
BitIntegerState & intersectAssumedBits(base_t BitsEncoding)
Keep only "assumed bits" also set in BitsEncoding but all known ones.
bool isKnown(base_t BitsEncoding=BestState) const
Return true if the bits set in BitsEncoding are "known bits".
BitIntegerState & addKnownBits(base_t Bits)
Add the bits in BitsEncoding to the "known bits".
Simple wrapper for a single bit (boolean) state.
IntegerStateBase< bool, true, false > super
bool isKnown() const
Return true if the state is known to hold.
void setKnown(bool Value)
Set the known and asssumed value to Value.
IntegerStateBase::base_t base_t
BooleanState(base_t Assumed)
BooleanState()=default
bool isAssumed() const
Return true if the state is assumed to hold.
Support structure for SCC passes to communicate updates the call graph back to the CGSCC pass manager...
static bool isNodeHidden(const AACallGraphNode *Node, const AttributorCallGraph *Graph)
std::string getNodeLabel(const AACallGraphNode *Node, const AttributorCallGraph *Graph)
Specialization of the integer state for a decreasing value, hence 0 is the best state and ~0u the wor...
DecIntegerState & takeKnownMinimum(base_t Value)
Take minimum of known and Value.
DecIntegerState & takeAssumedMaximum(base_t Value)
Take maximum of assumed and Value.
static DenormalMode unionAssumed(DenormalMode Callee, DenormalMode Caller)
DenormalState unionWith(DenormalState Caller) const
bool operator!=(const DenormalState Other) const
bool operator==(const DenormalState Other) const
static DenormalMode::DenormalModeKind unionDenormalKind(DenormalMode::DenormalModeKind Callee, DenormalMode::DenormalModeKind Caller)
bool IsAtFixedpoint
Explicitly track whether we've hit a fixed point.
ChangeStatus indicateOptimisticFixpoint() override
Indicate that the abstract state should converge to the optimistic state.
DenormalState getKnown() const
DenormalState getAssumed() const
bool isValidState() const override
Return if this abstract state is in a valid state.
ChangeStatus indicatePessimisticFixpoint() override
Indicate that the abstract state should converge to the pessimistic state.
DenormalFPMathState operator^=(const DenormalFPMathState &Caller)
ChangeStatus indicateFixpoint()
bool isModeFixed() const
Return true if there are no dynamic components to the denormal mode worth specializing.
bool isAtFixpoint() const override
Return if this abstract state is fixed, thus does not need to be updated if information changes as it...
Represent subnormal handling kind for floating point instruction inputs and outputs.
DenormalModeKind
Represent handled modes for denormal (aka subnormal) modes in the floating point environment.
@ Dynamic
Denormals have unknown treatment.
static constexpr DenormalMode getInvalid()
static bool isEqual(const AA::ValueAndContext &LHS, const AA::ValueAndContext &RHS)
Definition Attributor.h:430
static unsigned getHashValue(const AA::ValueAndContext &VAC)
Definition Attributor.h:426
DenseMapInfo< AA::ValueAndContext::Base > Base
Definition Attributor.h:425
static bool isEqual(const AA::ValueScope &LHS, const AA::ValueScope &RHS)
Definition Attributor.h:443
DenseMapInfo< unsigned char > Base
Definition Attributor.h:438
static unsigned getHashValue(const AA::ValueScope &S)
Definition Attributor.h:439
static bool isEqual(const IRPosition &a, const IRPosition &b)
static unsigned getHashValue(const IRPosition &IRP)
An information struct used to provide DenseMap with the various necessary components for a given valu...
State for dereferenceable attribute.
IncIntegerState DerefBytesState
State representing for dereferenceable bytes.
static DerefState getBestState(const DerefState &)
static DerefState getWorstState()
Return the worst possible representable state.
static DerefState getBestState()
static DerefState getWorstState(const DerefState &)
std::map< int64_t, uint64_t > AccessedBytesMap
Map representing for accessed memory offsets and sizes.
static AACallEdgeIterator child_end(AACallGraphNode *Node)
static AACallEdgeIterator child_begin(AACallGraphNode *Node)
static AACallGraphNode * getEntryNode(AttributorCallGraph *G)
static AACallEdgeIterator nodes_begin(const AttributorCallGraph *G)
static AACallEdgeIterator nodes_end(const AttributorCallGraph *G)
Attribute::AttrKind getAttrKind() const
Return the kind that identifies the abstract attribute implementation.
static constexpr Attribute::AttrKind IRAttributeKind
Compile time access to the IR attribute kind.
static bool hasTrivialInitializer()
Most boolean IRAttribute AAs don't do anything non-trivial in their initializers while non-boolean on...
static bool isImpliedByUndef()
Return true if the IR attribute(s) associated with this AA are implied for an undef value.
ChangeStatus manifest(Attributor &A) override
static bool isImpliedByPoison()
Return true if the IR attribute(s) associated with this AA are implied for an poison value.
static bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind=AK, bool IgnoreSubsumingPositions=false)
IRAttribute(const IRPosition &IRP)
virtual void getDeducedAttributes(Attributor &A, LLVMContext &Ctx, SmallVectorImpl< Attribute > &Attrs) const
Return the deduced attributes in Attrs.
Helper to describe and deal with positions in the LLVM-IR.
Definition Attributor.h:573
Function * getAssociatedFunction() const
Return the associated function, if any.
Definition Attributor.h:704
void setAttrList(const AttributeList &AttrList) const
Update the attributes associated with this function or call site scope.
Definition Attributor.h:839
unsigned getAttrIdx() const
Return the index in the attribute list for this position.
Definition Attributor.h:804
bool hasCallBaseContext() const
Check if the position has any call base context.
Definition Attributor.h:899
static const IRPosition callsite_returned(const CallBase &CB)
Create a position describing the returned value of CB.
Definition Attributor.h:641
static const IRPosition returned(const Function &F, const CallBaseContext *CBContext=nullptr)
Create a position describing the returned value of F.
Definition Attributor.h:623
LLVM_ABI Argument * getAssociatedArgument() const
Return the associated argument, if any.
bool isAnyCallSitePosition() const
Definition Attributor.h:866
bool operator!=(const IRPosition &RHS) const
Definition Attributor.h:682
static const IRPosition value(const Value &V, const CallBaseContext *CBContext=nullptr)
Create a position describing the value of V.
Definition Attributor.h:597
CallBase CallBaseContext
Definition Attributor.h:576
AttributeList getAttrList() const
Return the attributes associated with this function or call site scope.
Definition Attributor.h:832
int getCalleeArgNo() const
Return the callee argument number of the associated value if it is an argument or call site argument,...
Definition Attributor.h:790
static const IRPosition inst(const Instruction &I, const CallBaseContext *CBContext=nullptr)
Create a position describing the instruction I.
Definition Attributor.h:609
static const IRPosition callsite_argument(const CallBase &CB, unsigned ArgNo)
Create a position describing the argument of CB at position ArgNo.
Definition Attributor.h:646
Kind
The positions we distinguish in the IR.
Definition Attributor.h:579
@ IRP_ARGUMENT
An attribute for a function argument.
Definition Attributor.h:587
@ IRP_RETURNED
An attribute for the function return value.
Definition Attributor.h:583
@ IRP_CALL_SITE
An attribute for a call site (function scope).
Definition Attributor.h:586
@ IRP_CALL_SITE_RETURNED
An attribute for a call site return value.
Definition Attributor.h:584
@ IRP_FUNCTION
An attribute for a function (scope).
Definition Attributor.h:585
@ IRP_FLOAT
A position that is not associated with a spot suitable for attributes.
Definition Attributor.h:581
@ IRP_CALL_SITE_ARGUMENT
An attribute for a call site argument.
Definition Attributor.h:588
@ IRP_INVALID
An invalid position.
Definition Attributor.h:580
Instruction * getCtxI() const
Return the context instruction, if any.
Definition Attributor.h:757
static const IRPosition argument(const Argument &Arg, const CallBaseContext *CBContext=nullptr)
Create a position describing the argument Arg.
Definition Attributor.h:630
Type * getAssociatedType() const
Return the type this abstract attribute is associated with.
Definition Attributor.h:779
bool isFunctionScope() const
Return true if this is a function or call site position.
Definition Attributor.h:734
bool operator==(const IRPosition &RHS) const
Definition Attributor.h:679
static const IRPosition callsite_argument(AbstractCallSite ACS, unsigned ArgNo)
Create a position describing the argument of ACS at position ArgNo.
Definition Attributor.h:653
static const IRPosition function(const Function &F, const CallBaseContext *CBContext=nullptr)
Create a position describing the function scope of F.
Definition Attributor.h:616
const CallBaseContext * getCallBaseContext() const
Get the call base context from the position.
Definition Attributor.h:896
Value & getAssociatedValue() const
Return the value this abstract attribute is associated with.
Definition Attributor.h:771
Value & getAnchorValue() const
Return the value this abstract attribute is anchored with.
Definition Attributor.h:690
Value * getAttrListAnchor() const
Return the value attributes are attached to.
Definition Attributor.h:825
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:799
bool isFnInterfaceKind() const
Return true if the position refers to a function interface, that is the function scope,...
Definition Attributor.h:722
static const IRPosition function_scope(const IRPosition &IRP, const CallBaseContext *CBContext=nullptr)
Create a position with function scope matching the "context" of IRP.
Definition Attributor.h:669
IRPosition stripCallBaseContext() const
Return the same position without the call base context.
Definition Attributor.h:889
Kind getPositionKind() const
Return the associated position kind.
Definition Attributor.h:846
bool isArgumentPosition() const
Return true if the position is an argument or call site argument.
Definition Attributor.h:878
static const IRPosition callsite_function(const CallBase &CB)
Create a position describing the function scope of CB.
Definition Attributor.h:636
IRPosition()
Default constructor available to create invalid positions implicitly.
Definition Attributor.h:594
Function * getAnchorScope() const
Return the Function surrounding the anchor value.
Definition Attributor.h:745
Specialization of the integer state for an increasing value, hence ~0u is the best state and 0 the wo...
IntegerStateBase< base_ty, BestState, WorstState > super
static constexpr base_t getBestState(const IncIntegerState< base_ty, BestState, WorstState > &)
IncIntegerState(base_t Assumed)
static constexpr base_t getBestState()
Return the best possible representable state.
IncIntegerState & takeAssumedMinimum(base_t Value)
Take minimum of assumed and Value.
IncIntegerState & takeKnownMaximum(base_t Value)
Take maximum of known and Value.
Data structure to hold cached (LLVM-IR) information.
bool IsTargetGPU() const
Return true if the target is a GPU.
friend struct Attributor
Give the Attributor access to the members so Attributor::identifyDefaultAbstractAttributes(....
const SetVector< Function * > *const CGSCC
The CG-SCC the pass is run on, or nullptr if it is a module pass.
bool stackIsAccessibleByOtherThreads()
Return true if the stack (llvm::Alloca) can be accessed by other threads.
bool isInvolvedInMustTailCall(const Argument &Arg)
Return true if Arg is involved in a must-tail call, thus the argument of the caller or callee.
MustBeExecutedContextExplorer * getMustBeExecutedContextExplorer()
Return MustBeExecutedContextExplorer.
void invalidateAnalyses()
Invalidates the cached analyses.
virtual unsigned getMaxAddrSpace() const
const AA::InstExclusionSetTy * getOrCreateUniqueBlockExecutionSet(const AA::InstExclusionSetTy *BES)
Given BES, return a uniqued version.
static void foreachUse(Function &F, CBTy CB, bool LookThroughConstantExprUses=true)
Apply CB to all uses of F.
bool isOnlyUsedByAssume(const Instruction &I)
bool isExactOrInlineable(const Function &F) const
Return true if F has an exact definition or is inlineable.
TargetLibraryInfo * getTargetLibraryInfoForFunction(const Function &F)
Return TargetLibraryInfo for function F.
InformationCache(const Module &M, AnalysisGetter &AG, BumpPtrAllocator &Allocator, SetVector< Function * > *CGSCC, bool UseExplorer=true)
const Module & getModule() const
const DataLayout & getDL() const
Return datalayout used in the module.
std::array< InstructionVectorTy *, Instruction::OtherOpsEnd > OpcodeInstMapTy
A map type from opcodes to instructions with this opcode.
LLVM_ABI std::optional< unsigned > getFlatAddressSpace() const
Return the flat address space if the associated target has.
OpcodeInstMapTy & getOpcodeInstMapForFunction(const Function &F)
Return the map that relates "interesting" opcodes with all instructions with that opcode in F.
const RetainedKnowledgeMap & getKnowledgeMap() const
Return the map conaining all the knowledge we have from llvm.assumes.
LLVM_ABI ArrayRef< Function * > getIndirectlyCallableFunctions(Attributor &A) const
Return all functions that might be called indirectly, only valid for closed world modules (see isClos...
SmallVector< Instruction *, 8 > InstructionVectorTy
A vector type to hold instructions.
InstructionVectorTy & getReadOrWriteInstsForFunction(const Function &F)
Return the instructions in F that may read or write memory.
bool isKernel(const Function &F)
Return true if F has the "kernel" function attribute.
AP::Result * getAnalysisResultForFunction(const Function &F, bool CachedOnly=false)
Return the analysis result from a pass AP for function F.
State for an integer range.
IntegerRangeState operator^=(const IntegerRangeState &R)
"Clamp" this state with R.
IntegerRangeState operator&=(const IntegerRangeState &R)
bool isAtFixpoint() const override
Return if this abstract state is fixed, thus does not need to be updated if information changes as it...
void unionAssumed(const IntegerRangeState &R)
See IntegerRangeState::unionAssumed(..).
ConstantRange Assumed
State representing assumed range, initially set to empty.
IntegerRangeState(const ConstantRange &CR)
IntegerRangeState(uint32_t BitWidth)
bool operator==(const IntegerRangeState &R) const
Equality for IntegerRangeState.
void intersectKnown(const IntegerRangeState &R)
See IntegerRangeState::intersectKnown(..).
static ConstantRange getBestState(const IntegerRangeState &IRS)
bool isValidState() const override
Return if this abstract state is in a valid state.
uint32_t BitWidth
Bitwidth of the associated value.
ConstantRange Known
State representing known range, initially set to [-inf, inf].
void unionAssumed(const ConstantRange &R)
Unite assumed range with the passed state.
ChangeStatus indicatePessimisticFixpoint() override
Indicate that the abstract state should converge to the pessimistic state.
ConstantRange getKnown() const
Return the known state encoding.
void intersectKnown(const ConstantRange &R)
Intersect known range with the passed state.
ConstantRange getAssumed() const
Return the assumed state encoding.
uint32_t getBitWidth() const
Return associated values' bit width.
ChangeStatus indicateOptimisticFixpoint() override
Indicate that the abstract state should converge to the optimistic state.
static ConstantRange getWorstState(uint32_t BitWidth)
Return the worst possible representable state.
static ConstantRange getBestState(uint32_t BitWidth)
Return the best possible representable state.
Simple state with integers encoding.
bool isValidState() const override
NOTE: For now we simply pretend that the worst possible state is invalid.
virtual void handleNewAssumedValue(base_t Value)=0
Handle a new assumed value Value. Subtype dependent.
bool isAtFixpoint() const override
Return if this abstract state is fixed, thus does not need to be updated if information changes as it...
void operator|=(const IntegerStateBase< base_t, BestState, WorstState > &R)
virtual void handleNewKnownValue(base_t Value)=0
Handle a new known value Value. Subtype dependent.
base_t getKnown() const
Return the known state encoding.
ChangeStatus indicateOptimisticFixpoint() override
Indicate that the abstract state should converge to the optimistic state.
void operator^=(const IntegerStateBase< base_t, BestState, WorstState > &R)
"Clamp" this state with R.
virtual void joinOR(base_t AssumedValue, base_t KnownValue)=0
Handle a value Value. Subtype dependent.
virtual void joinAND(base_t AssumedValue, base_t KnownValue)=0
Handle a new assumed value Value. Subtype dependent.
IntegerStateBase(base_t Assumed)
void operator+=(const IntegerStateBase< base_t, BestState, WorstState > &R)
"Clamp" this state with R.
base_t getAssumed() const
Return the assumed state encoding.
static constexpr base_t getWorstState()
Return the worst possible representable state.
static constexpr base_t getBestState()
Return the best possible representable state.
ChangeStatus indicatePessimisticFixpoint() override
Indicate that the abstract state should converge to the pessimistic state.
static constexpr base_t getWorstState(const IntegerStateBase &)
bool operator!=(const IntegerStateBase< base_t, BestState, WorstState > &R) const
Inequality for IntegerStateBase.
bool operator==(const IntegerStateBase< base_t, BestState, WorstState > &R) const
Equality for IntegerStateBase.
void operator&=(const IntegerStateBase< base_t, BestState, WorstState > &R)
static constexpr base_t getBestState(const IntegerStateBase &)
A "must be executed context" for a given program point PP is the set of instructions,...
A CRTP mix-in for passes that can be skipped.
static constexpr int NumLowBitsAvailable
Note, we assume here that void* is related to raw malloc'ed memory and that malloc returns objects at...
A class for a set state.
static PotentialValuesState getBestState(const PotentialValuesState &PVS)
PotentialValuesState & getAssumed()
Return the assumed state.
bool undefIsContained() const
Returns whether this state contains an undef value or not.
bool isAtFixpoint() const override
Return if this abstract state is fixed, thus does not need to be updated if information changes as it...
void unionAssumed(const MemberTy &C)
Union assumed set with the passed value.
static PotentialValuesState getBestState()
Return empty set as the best state of potential values.
SmallSetVector< MemberTy, 8 > SetTy
ChangeStatus indicatePessimisticFixpoint() override
Indicate that the abstract state should converge to the pessimistic state.
void unionAssumed(const PotentialValuesState &PVS)
Union assumed set with assumed set of the passed state PVS.
PotentialValuesState(bool IsValid)
bool operator==(const PotentialValuesState &RHS) const
bool isValidState() const override
Return if this abstract state is in a valid state.
PotentialValuesState operator&=(const PotentialValuesState &PVS)
static PotentialValuesState getWorstState()
Return full set as the worst state of potential values.
const PotentialValuesState & getAssumed() const
ChangeStatus indicateOptimisticFixpoint() override
Indicate that the abstract state should converge to the optimistic state.
PotentialValuesState operator^=(const PotentialValuesState &PVS)
"Clamp" this state with PVS.
void unionAssumedWithUndef()
Union assumed set with an undef value.
const SetTy & getAssumedSet() const
Return this set.
A wrapper around a set that has semantics for handling unions and intersections with a "universal" se...
SetContents(bool Universal)
Creates a universal set with no concrete elements or an empty set.
SetContents(bool Universal, const DenseSet< BaseTy > &Assumptions)
bool getIntersection(const SetContents &RHS)
Finds A := A ^ B where A or B could be the "Universal" set which contains every possible attribute.
bool getUnion(const SetContents &RHS)
Finds A := A u B where A or B could be the "Universal" set which contains every possible attribute.
const DenseSet< BaseTy > & getSet() const
SetContents(const DenseSet< BaseTy > &Assumptions)
Creates a non-universal set with concrete values.
bool setContains(const BaseTy &Elem) const
Returns if the set state contains the element.
bool getIntersection(const SetContents &RHS)
Performs the set intersection between this set and RHS.
bool isValidState() const override
Return if this abstract state is in a valid state.
bool isAtFixpoint() const override
Return if this abstract state is fixed, thus does not need to be updated if information changes as it...
const SetContents & getAssumed() const
Return the assumed state encoding.
const SetContents & getKnown() const
Return the known state encoding.
ChangeStatus indicateOptimisticFixpoint() override
Indicate that the abstract state should converge to the optimistic state.
bool getUnion(const SetContents &RHS)
Performs the set union between this set and RHS.
SetState(const DenseSet< BaseTy > &Known)
Initializes the known state with an initial set and initializes the assumed state as universal.
ChangeStatus indicatePessimisticFixpoint() override
Indicate that the abstract state should converge to the pessimistic state.
Helper to tie a abstract state implementation to an abstract attribute.
StateType & getState() override
StateTy StateType
Provide static access to the type of the state.
bool isStateAtFixpoint() const final
StateWrapper(const IRPosition &IRP, Ts... Args)
const StateType & getState() const override
bool isAtFixpoint() const final
static ValueSimplifyStateType getWorstState(Type *Ty)
Return the worst possible representable state.
static ValueSimplifyStateType getBestState(const ValueSimplifyStateType &VS)
LLVM_ABI bool unionAssumed(std::optional< Value * > Other)
Merge Other into the currently assumed simplified value.
ChangeStatus indicateOptimisticFixpoint() override
Indicate that the abstract state should converge to the optimistic state.
ValueSimplifyStateType operator^=(const ValueSimplifyStateType &VS)
"Clamp" this state with PVS.
ChangeStatus indicatePessimisticFixpoint() override
Indicate that the abstract state should converge to the pessimistic state.
static ValueSimplifyStateType getBestState(Type *Ty)
bool isAtFixpoint() const override
Return if this abstract state is fixed, thus does not need to be updated if information changes as it...
bool isValidState() const override
Return if this abstract state is in a valid state.
std::optional< Value * > SimplifiedAssociatedValue
An assumed simplified value.
static ValueSimplifyStateType getWorstState(const ValueSimplifyStateType &VS)
BooleanState BS
Helper to track validity and fixpoint.
Type * Ty
The type of the original value.
bool operator==(const ValueSimplifyStateType &RHS) const
ValueSimplifyStateType getAssumed()
Return the assumed state encoding.
const ValueSimplifyStateType & getAssumed() const