LLVM 23.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"
137#include "llvm/Support/ModRef.h"
142
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 generic
172/// address space for the target triple in module \p M.
173LLVM_ABI bool isGPUGenericAddressSpace(const Module &M, unsigned AS);
174
175/// Check if the given address space \p AS corresponds to a GPU global
176/// address space for the target triple in module \p M.
177LLVM_ABI bool isGPUGlobalAddressSpace(const Module &M, unsigned AS);
178
179/// Check if the given address space \p AS corresponds to a GPU shared
180/// address space for the target triple in module \p M.
181LLVM_ABI bool isGPUSharedAddressSpace(const Module &M, unsigned AS);
182
183/// Check if the given address space \p AS corresponds to a GPU constant
184/// address space for the target triple in module \p M.
185LLVM_ABI bool isGPUConstantAddressSpace(const Module &M, unsigned AS);
186
187/// Check if the given address space \p AS corresponds to a GPU local/private
188/// address space for the target triple in module \p M.
189LLVM_ABI bool isGPULocalAddressSpace(const Module &M, unsigned AS);
190
191/// Flags to distinguish intra-procedural queries from *potentially*
192/// inter-procedural queries. Not that information can be valid for both and
193/// therefore both bits might be set.
199
200struct ValueAndContext : public std::pair<Value *, const Instruction *> {
201 using Base = std::pair<Value *, const Instruction *>;
203 ValueAndContext(Value &V, const Instruction *CtxI) : Base(&V, CtxI) {}
204 ValueAndContext(Value &V, const Instruction &CtxI) : Base(&V, &CtxI) {}
205
206 Value *getValue() const { return this->first; }
207 const Instruction *getCtxI() const { return this->second; }
208};
209
210/// Return true if \p I is a `nosync` instruction. Use generic reasoning and
211/// potentially the corresponding AANoSync.
213 const AbstractAttribute &QueryingAA);
214
215/// Return true if \p V is dynamically unique, that is, there are no two
216/// "instances" of \p V at runtime with different values.
217/// Note: If \p ForAnalysisOnly is set we only check that the Attributor will
218/// never use \p V to represent two "instances" not that \p V could not
219/// technically represent them.
221 const AbstractAttribute &QueryingAA,
222 const Value &V, bool ForAnalysisOnly = true);
223
224/// Return true if \p V is a valid value in \p Scope, that is a constant or an
225/// instruction/argument of \p Scope.
226LLVM_ABI bool isValidInScope(const Value &V, const Function *Scope);
227
228/// Return true if the value of \p VAC is a valid at the position of \p VAC,
229/// that is a constant, an argument of the same function, or an instruction in
230/// that function that dominates the position.
231LLVM_ABI bool isValidAtPosition(const ValueAndContext &VAC,
232 InformationCache &InfoCache);
233
234/// Try to convert \p V to type \p Ty without introducing new instructions. If
235/// this is not possible return `nullptr`. Note: this function basically knows
236/// how to cast various constants.
238
239/// Return the combination of \p A and \p B such that the result is a possible
240/// value of both. \p B is potentially casted to match the type \p Ty or the
241/// type of \p A if \p Ty is null.
242///
243/// Examples:
244/// X + none => X
245/// not_none + undef => not_none
246/// V1 + V2 => nullptr
247LLVM_ABI std::optional<Value *>
248combineOptionalValuesInAAValueLatice(const std::optional<Value *> &A,
249 const std::optional<Value *> &B, Type *Ty);
250
251/// Helper to represent an access offset and size, with logic to deal with
252/// uncertainty and check for overlapping accesses.
253struct RangeTy {
255 int64_t Size = Unassigned;
256
257 RangeTy(int64_t Offset, int64_t Size) : Offset(Offset), Size(Size) {}
258 RangeTy() = default;
259 static RangeTy getUnknown() { return RangeTy{Unknown, Unknown}; }
260
261 /// Return true if offset or size are unknown.
264 }
265
266 /// Return true if offset and size are unknown, thus this is the default
267 /// unknown object.
270 }
271
272 /// Return true if the offset and size are unassigned.
273 bool isUnassigned() const {
275 "Inconsistent state!");
276 return Offset == RangeTy::Unassigned;
277 }
278
279 /// Return true if this offset and size pair might describe an address that
280 /// overlaps with \p Range.
281 bool mayOverlap(const RangeTy &Range) const {
282 // Any unknown value and we are giving up -> overlap.
283 if (offsetOrSizeAreUnknown() || Range.offsetOrSizeAreUnknown())
284 return true;
285
286 // Check if one offset point is in the other interval [offset,
287 // offset+size].
288 return Range.Offset + Range.Size > Offset && Range.Offset < Offset + Size;
289 }
290
292 if (R.isUnassigned())
293 return *this;
294 if (isUnassigned())
295 return *this = R;
296 if (Offset == Unknown || R.Offset == Unknown)
297 Offset = Unknown;
298 if (Size == Unknown || R.Size == Unknown)
299 Size = Unknown;
301 return *this;
302 if (Offset == Unknown) {
303 Size = std::max(Size, R.Size);
304 } else if (Size == Unknown) {
305 Offset = std::min(Offset, R.Offset);
306 } else {
307 Offset = std::min(Offset, R.Offset);
308 Size = std::max(Offset + Size, R.Offset + R.Size) - Offset;
309 }
310 return *this;
311 }
312
313 /// Comparison for sorting ranges.
314 ///
315 /// Returns true if the offset of \p L is less than that of \p R. If the two
316 /// offsets are same, compare the sizes instead.
317 inline static bool LessThan(const RangeTy &L, const RangeTy &R) {
318 if (L.Offset < R.Offset)
319 return true;
320 if (L.Offset == R.Offset)
321 return L.Size < R.Size;
322 return false;
323 }
324
325 /// Constants used to represent special offsets or sizes.
326 /// - We cannot assume that Offsets and Size are non-negative.
327 /// - The constants should not clash with DenseMapInfo, such as EmptyKey
328 /// (INT64_MAX).
329 /// We use values "in the middle" of the 64 bit range to represent these
330 /// special cases.
331 static constexpr int64_t Unassigned = std::numeric_limits<int32_t>::min();
332 static constexpr int64_t Unknown = std::numeric_limits<int32_t>::max();
333};
334
336 OS << "[" << R.Offset << ", " << R.Size << "]";
337 return OS;
338}
339
340inline bool operator==(const RangeTy &A, const RangeTy &B) {
341 return A.Offset == B.Offset && A.Size == B.Size;
342}
343
344inline bool operator!=(const RangeTy &A, const RangeTy &B) { return !(A == B); }
345
346/// Return the initial value of \p Obj with type \p Ty if that is a constant.
349 Value &Obj, Type &Ty, const TargetLibraryInfo *TLI,
350 const DataLayout &DL, RangeTy *RangePtr = nullptr);
351
352/// Collect all potential values \p LI could read into \p PotentialValues. That
353/// is, the only values read by \p LI are assumed to be known and all are in
354/// \p PotentialValues. \p PotentialValueOrigins will contain all the
355/// instructions that might have put a potential value into \p PotentialValues.
356/// Dependences onto \p QueryingAA are properly tracked, \p
357/// UsedAssumedInformation will inform the caller if assumed information was
358/// used.
359///
360/// \returns True if the assumed potential copies are all in \p PotentialValues,
361/// false if something went wrong and the copies could not be
362/// determined.
364 Attributor &A, LoadInst &LI, SmallSetVector<Value *, 4> &PotentialValues,
365 SmallSetVector<Instruction *, 4> &PotentialValueOrigins,
366 const AbstractAttribute &QueryingAA, bool &UsedAssumedInformation,
367 bool OnlyExact = false);
368
369/// Collect all potential values of the one stored by \p SI into
370/// \p PotentialCopies. That is, the only copies that were made via the
371/// store are assumed to be known and all are in \p PotentialCopies. Dependences
372/// onto \p QueryingAA are properly tracked, \p UsedAssumedInformation will
373/// inform the caller if assumed information was used.
374///
375/// \returns True if the assumed potential copies are all in \p PotentialCopies,
376/// false if something went wrong and the copies could not be
377/// determined.
380 const AbstractAttribute &QueryingAA, bool &UsedAssumedInformation,
381 bool OnlyExact = false);
382
383/// Return true if \p IRP is readonly. This will query respective AAs that
384/// deduce the information and introduce dependences for \p QueryingAA.
386 const AbstractAttribute &QueryingAA,
387 bool &IsKnown);
388
389/// Return true if \p IRP is readnone. This will query respective AAs that
390/// deduce the information and introduce dependences for \p QueryingAA.
392 const AbstractAttribute &QueryingAA,
393 bool &IsKnown);
394
395/// Return true if \p ToI is potentially reachable from \p FromI without running
396/// into any instruction in \p ExclusionSet The two instructions do not need to
397/// be in the same function. \p GoBackwardsCB can be provided to convey domain
398/// knowledge about the "lifespan" the user is interested in. By default, the
399/// callers of \p FromI are checked as well to determine if \p ToI can be
400/// reached. If the query is not interested in callers beyond a certain point,
401/// e.g., a GPU kernel entry or the function containing an alloca, the
402/// \p GoBackwardsCB should return false.
404 Attributor &A, const Instruction &FromI, const Instruction &ToI,
405 const AbstractAttribute &QueryingAA,
406 const AA::InstExclusionSetTy *ExclusionSet = nullptr,
407 std::function<bool(const Function &F)> GoBackwardsCB = nullptr);
408
409/// Same as above but it is sufficient to reach any instruction in \p ToFn.
411 Attributor &A, const Instruction &FromI, const Function &ToFn,
412 const AbstractAttribute &QueryingAA,
413 const AA::InstExclusionSetTy *ExclusionSet = nullptr,
414 std::function<bool(const Function &F)> GoBackwardsCB = nullptr);
415
416/// Return true if \p Obj is assumed to be a thread local object.
418 const AbstractAttribute &QueryingAA);
419
420/// Return true if \p I is potentially affected by a barrier.
421LLVM_ABI bool
423 const AbstractAttribute &QueryingAA);
424LLVM_ABI bool
426 const AbstractAttribute &QueryingAA,
427 const Instruction *CtxI);
428} // namespace AA
429
430template <>
431struct DenseMapInfo<AA::ValueAndContext>
432 : public DenseMapInfo<AA::ValueAndContext::Base> {
435 return Base::getEmptyKey();
436 }
437 static unsigned getHashValue(const AA::ValueAndContext &VAC) {
438 return Base::getHashValue(VAC);
439 }
440
441 static bool isEqual(const AA::ValueAndContext &LHS,
442 const AA::ValueAndContext &RHS) {
443 return Base::isEqual(LHS, RHS);
444 }
445};
446
447template <>
448struct DenseMapInfo<AA::ValueScope> : public DenseMapInfo<unsigned char> {
450 static inline AA::ValueScope getEmptyKey() {
451 return AA::ValueScope(Base::getEmptyKey());
452 }
453 static unsigned getHashValue(const AA::ValueScope &S) {
454 return Base::getHashValue(S);
455 }
456
457 static bool isEqual(const AA::ValueScope &LHS, const AA::ValueScope &RHS) {
458 return Base::isEqual(LHS, RHS);
459 }
460};
461
462template <>
463struct DenseMapInfo<const AA::InstExclusionSetTy *>
464 : public DenseMapInfo<void *> {
465 using super = DenseMapInfo<void *>;
466 static inline const AA::InstExclusionSetTy *getEmptyKey() {
467 return static_cast<const AA::InstExclusionSetTy *>(super::getEmptyKey());
468 }
469 static unsigned getHashValue(const AA::InstExclusionSetTy *BES) {
470 unsigned H = 0;
471 if (BES)
472 for (const auto *II : *BES)
473 H += DenseMapInfo<const Instruction *>::getHashValue(II);
474 return H;
475 }
476 static bool isEqual(const AA::InstExclusionSetTy *LHS,
478 if (LHS == RHS)
479 return true;
480 if (LHS == getEmptyKey() || RHS == getEmptyKey())
481 return false;
482 auto SizeLHS = LHS ? LHS->size() : 0;
483 auto SizeRHS = RHS ? RHS->size() : 0;
484 if (SizeLHS != SizeRHS)
485 return false;
486 if (SizeRHS == 0)
487 return true;
488 return llvm::set_is_subset(*LHS, *RHS);
489 }
490};
491
492/// The value passed to the line option that defines the maximal initialization
493/// chain length.
495
496///{
501
506
507enum class DepClassTy {
508 REQUIRED, ///< The target cannot be valid if the source is not.
509 OPTIONAL, ///< The target may be valid if the source is not.
510 NONE, ///< Do not track a dependence between source and target.
511};
512///}
513
514/// The data structure for the nodes of a dependency graph
516public:
517 virtual ~AADepGraphNode() = default;
520
521protected:
522 /// Set of dependency graph nodes which should be updated if this one
523 /// is updated. The bit encodes if it is optional.
525
526 static AADepGraphNode *DepGetVal(const DepTy &DT) { return DT.getPointer(); }
529 }
530
531 operator AbstractAttribute *() { return cast<AbstractAttribute>(this); }
532
533public:
537
538 aaiterator begin() { return aaiterator(Deps.begin(), &DepGetValAA); }
539 aaiterator end() { return aaiterator(Deps.end(), &DepGetValAA); }
540 iterator child_begin() { return iterator(Deps.begin(), &DepGetVal); }
541 iterator child_end() { return iterator(Deps.end(), &DepGetVal); }
542
543 void print(raw_ostream &OS) const { print(nullptr, OS); }
544 virtual void print(Attributor *, raw_ostream &OS) const {
545 OS << "AADepNode Impl\n";
546 }
547 DepSetTy &getDeps() { return Deps; }
548
549 friend struct Attributor;
550 friend struct AADepGraph;
551};
552
553/// The data structure for the dependency graph
554///
555/// Note that in this graph if there is an edge from A to B (A -> B),
556/// then it means that B depends on A, and when the state of A is
557/// updated, node B should also be updated
559 AADepGraph() = default;
560 ~AADepGraph() = default;
561
563 static AADepGraphNode *DepGetVal(const DepTy &DT) { return DT.getPointer(); }
564 using iterator =
566
567 /// There is no root node for the dependency graph. But the SCCIterator
568 /// requires a single entry point, so we maintain a fake("synthetic") root
569 /// node that depends on every node.
572
573 iterator begin() { return SyntheticRoot.child_begin(); }
574 iterator end() { return SyntheticRoot.child_end(); }
575
576 LLVM_ABI void viewGraph();
577
578 /// Dump graph to file
579 LLVM_ABI void dumpGraph();
580
581 /// Print dependency graph
582 LLVM_ABI void print();
583};
584
585/// Helper to describe and deal with positions in the LLVM-IR.
586///
587/// A position in the IR is described by an anchor value and an "offset" that
588/// could be the argument number, for call sites and arguments, or an indicator
589/// of the "position kind". The kinds, specified in the Kind enum below, include
590/// the locations in the attribute list, i.a., function scope and return value,
591/// as well as a distinction between call sites and functions. Finally, there
592/// are floating values that do not have a corresponding attribute list
593/// position.
595 // NOTE: In the future this definition can be changed to support recursive
596 // functions.
598
599 /// The positions we distinguish in the IR.
600 enum Kind : char {
601 IRP_INVALID, ///< An invalid position.
602 IRP_FLOAT, ///< A position that is not associated with a spot suitable
603 ///< for attributes. This could be any value or instruction.
604 IRP_RETURNED, ///< An attribute for the function return value.
605 IRP_CALL_SITE_RETURNED, ///< An attribute for a call site return value.
606 IRP_FUNCTION, ///< An attribute for a function (scope).
607 IRP_CALL_SITE, ///< An attribute for a call site (function scope).
608 IRP_ARGUMENT, ///< An attribute for a function argument.
609 IRP_CALL_SITE_ARGUMENT, ///< An attribute for a call site argument.
610 };
611
612 /// Default constructor available to create invalid positions implicitly. All
613 /// other positions need to be created explicitly through the appropriate
614 /// static member function.
615 IRPosition() : Enc(nullptr, ENC_VALUE) { verify(); }
616
617 /// Create a position describing the value of \p V.
618 static const IRPosition value(const Value &V,
619 const CallBaseContext *CBContext = nullptr) {
620 if (auto *Arg = dyn_cast<Argument>(&V))
621 return IRPosition::argument(*Arg, CBContext);
622 if (auto *CB = dyn_cast<CallBase>(&V))
624 return IRPosition(const_cast<Value &>(V), IRP_FLOAT, CBContext);
625 }
626
627 /// Create a position describing the instruction \p I. This is different from
628 /// the value version because call sites are treated as intrusctions rather
629 /// than their return value in this function.
630 static const IRPosition inst(const Instruction &I,
631 const CallBaseContext *CBContext = nullptr) {
632 return IRPosition(const_cast<Instruction &>(I), IRP_FLOAT, CBContext);
633 }
634
635 /// Create a position describing the function scope of \p F.
636 /// \p CBContext is used for call base specific analysis.
637 static const IRPosition function(const Function &F,
638 const CallBaseContext *CBContext = nullptr) {
639 return IRPosition(const_cast<Function &>(F), IRP_FUNCTION, CBContext);
640 }
641
642 /// Create a position describing the returned value of \p F.
643 /// \p CBContext is used for call base specific analysis.
644 static const IRPosition returned(const Function &F,
645 const CallBaseContext *CBContext = nullptr) {
646 return IRPosition(const_cast<Function &>(F), IRP_RETURNED, CBContext);
647 }
648
649 /// Create a position describing the argument \p Arg.
650 /// \p CBContext is used for call base specific analysis.
651 static const IRPosition argument(const Argument &Arg,
652 const CallBaseContext *CBContext = nullptr) {
653 return IRPosition(const_cast<Argument &>(Arg), IRP_ARGUMENT, CBContext);
654 }
655
656 /// Create a position describing the function scope of \p CB.
657 static const IRPosition callsite_function(const CallBase &CB) {
658 return IRPosition(const_cast<CallBase &>(CB), IRP_CALL_SITE);
659 }
660
661 /// Create a position describing the returned value of \p CB.
662 static const IRPosition callsite_returned(const CallBase &CB) {
663 return IRPosition(const_cast<CallBase &>(CB), IRP_CALL_SITE_RETURNED);
664 }
665
666 /// Create a position describing the argument of \p CB at position \p ArgNo.
667 static const IRPosition callsite_argument(const CallBase &CB,
668 unsigned ArgNo) {
669 return IRPosition(const_cast<Use &>(CB.getArgOperandUse(ArgNo)),
671 }
672
673 /// Create a position describing the argument of \p ACS at position \p ArgNo.
675 unsigned ArgNo) {
676 if (ACS.getNumArgOperands() <= ArgNo)
677 return IRPosition();
678 int CSArgNo = ACS.getCallArgOperandNo(ArgNo);
679 if (CSArgNo >= 0)
681 cast<CallBase>(*ACS.getInstruction()), CSArgNo);
682 return IRPosition();
683 }
684
685 /// Create a position with function scope matching the "context" of \p IRP.
686 /// If \p IRP is a call site (see isAnyCallSitePosition()) then the result
687 /// will be a call site position, otherwise the function position of the
688 /// associated function.
689 static const IRPosition
691 const CallBaseContext *CBContext = nullptr) {
692 if (IRP.isAnyCallSitePosition()) {
695 }
697 return IRPosition::function(*IRP.getAssociatedFunction(), CBContext);
698 }
699
700 bool operator==(const IRPosition &RHS) const {
701 return Enc == RHS.Enc && RHS.CBContext == CBContext;
702 }
703 bool operator!=(const IRPosition &RHS) const { return !(*this == RHS); }
704
705 /// Return the value this abstract attribute is anchored with.
706 ///
707 /// The anchor value might not be the associated value if the latter is not
708 /// sufficient to determine where arguments will be manifested. This is, so
709 /// far, only the case for call site arguments as the value is not sufficient
710 /// to pinpoint them. Instead, we can use the call site as an anchor.
712 switch (getEncodingBits()) {
713 case ENC_VALUE:
714 case ENC_RETURNED_VALUE:
715 case ENC_FLOATING_FUNCTION:
716 return *getAsValuePtr();
717 case ENC_CALL_SITE_ARGUMENT_USE:
718 return *(getAsUsePtr()->getUser());
719 default:
720 llvm_unreachable("Unkown encoding!");
721 };
722 }
723
724 /// Return the associated function, if any.
726 if (auto *CB = dyn_cast<CallBase>(&getAnchorValue())) {
727 // We reuse the logic that associates callback calles to arguments of a
728 // call site here to identify the callback callee as the associated
729 // function.
730 if (Argument *Arg = getAssociatedArgument())
731 return Arg->getParent();
733 CB->getCalledOperand()->stripPointerCasts());
734 }
735 return getAnchorScope();
736 }
737
738 /// Return the associated argument, if any.
740
741 /// Return true if the position refers to a function interface, that is the
742 /// function scope, the function return, or an argument.
743 bool isFnInterfaceKind() const {
744 switch (getPositionKind()) {
748 return true;
749 default:
750 return false;
751 }
752 }
753
754 /// Return true if this is a function or call site position.
755 bool isFunctionScope() const {
756 switch (getPositionKind()) {
759 return true;
760 default:
761 return false;
762 };
763 }
764
765 /// Return the Function surrounding the anchor value.
767 Value &V = getAnchorValue();
768 if (isa<Function>(V))
769 return &cast<Function>(V);
770 if (isa<Argument>(V))
771 return cast<Argument>(V).getParent();
772 if (isa<Instruction>(V))
773 return cast<Instruction>(V).getFunction();
774 return nullptr;
775 }
776
777 /// Return the context instruction, if any.
779 Value &V = getAnchorValue();
780 if (auto *I = dyn_cast<Instruction>(&V))
781 return I;
782 if (auto *Arg = dyn_cast<Argument>(&V))
783 if (!Arg->getParent()->isDeclaration())
784 return &Arg->getParent()->getEntryBlock().front();
785 if (auto *F = dyn_cast<Function>(&V))
786 if (!F->isDeclaration())
787 return &(F->getEntryBlock().front());
788 return nullptr;
789 }
790
791 /// Return the value this abstract attribute is associated with.
794 return getAnchorValue();
795 assert(isa<CallBase>(&getAnchorValue()) && "Expected a call base!");
797 ->getArgOperand(getCallSiteArgNo());
798 }
799
800 /// Return the type this abstract attribute is associated with.
806
807 /// Return the callee argument number of the associated value if it is an
808 /// argument or call site argument, otherwise a negative value. In contrast to
809 /// `getCallSiteArgNo` this method will always return the "argument number"
810 /// from the perspective of the callee. This may not the same as the call site
811 /// if this is a callback call.
812 int getCalleeArgNo() const {
813 return getArgNo(/* CallbackCalleeArgIfApplicable */ true);
814 }
815
816 /// Return the call site argument number of the associated value if it is an
817 /// argument or call site argument, otherwise a negative value. In contrast to
818 /// `getCalleArgNo` this method will always return the "operand number" from
819 /// the perspective of the call site. This may not the same as the callee
820 /// perspective if this is a callback call.
821 int getCallSiteArgNo() const {
822 return getArgNo(/* CallbackCalleeArgIfApplicable */ false);
823 }
824
825 /// Return the index in the attribute list for this position.
826 unsigned getAttrIdx() const {
827 switch (getPositionKind()) {
830 break;
833 return AttributeList::FunctionIndex;
836 return AttributeList::ReturnIndex;
838 return getCalleeArgNo() + AttributeList::FirstArgIndex;
840 return getCallSiteArgNo() + AttributeList::FirstArgIndex;
841 }
843 "There is no attribute index for a floating or invalid position!");
844 }
845
846 /// Return the value attributes are attached to.
848 if (auto *CB = dyn_cast<CallBase>(&getAnchorValue()))
849 return CB;
850 return getAssociatedFunction();
851 }
852
853 /// Return the attributes associated with this function or call site scope.
854 AttributeList getAttrList() const {
855 if (auto *CB = dyn_cast<CallBase>(&getAnchorValue()))
856 return CB->getAttributes();
858 }
859
860 /// Update the attributes associated with this function or call site scope.
861 void setAttrList(const AttributeList &AttrList) const {
862 if (auto *CB = dyn_cast<CallBase>(&getAnchorValue()))
863 return CB->setAttributes(AttrList);
864 return getAssociatedFunction()->setAttributes(AttrList);
865 }
866
867 /// Return the number of arguments associated with this function or call site
868 /// scope.
869 unsigned getNumArgs() const {
872 "Only valid for function/call site positions!");
873 if (auto *CB = dyn_cast<CallBase>(&getAnchorValue()))
874 return CB->arg_size();
876 }
877
878 /// Return theargument \p ArgNo associated with this function or call site
879 /// scope.
880 Value *getArg(unsigned ArgNo) const {
883 "Only valid for function/call site positions!");
884 if (auto *CB = dyn_cast<CallBase>(&getAnchorValue()))
885 return CB->getArgOperand(ArgNo);
886 return getAssociatedFunction()->getArg(ArgNo);
887 }
888
889 /// Return the associated position kind.
891 char EncodingBits = getEncodingBits();
892 if (EncodingBits == ENC_CALL_SITE_ARGUMENT_USE)
894 if (EncodingBits == ENC_FLOATING_FUNCTION)
895 return IRP_FLOAT;
896
897 Value *V = getAsValuePtr();
898 if (!V)
899 return IRP_INVALID;
900 if (isa<Argument>(V))
901 return IRP_ARGUMENT;
902 if (isa<Function>(V))
903 return isReturnPosition(EncodingBits) ? IRP_RETURNED : IRP_FUNCTION;
904 if (isa<CallBase>(V))
905 return isReturnPosition(EncodingBits) ? IRP_CALL_SITE_RETURNED
907 return IRP_FLOAT;
908 }
909
911 switch (getPositionKind()) {
915 return true;
916 default:
917 return false;
918 }
919 }
920
921 /// Return true if the position is an argument or call site argument.
922 bool isArgumentPosition() const {
923 switch (getPositionKind()) {
926 return true;
927 default:
928 return false;
929 }
930 }
931
932 /// Return the same position without the call base context.
934 IRPosition Result = *this;
935 Result.CBContext = nullptr;
936 return Result;
937 }
938
939 /// Get the call base context from the position.
940 const CallBaseContext *getCallBaseContext() const { return CBContext; }
941
942 /// Check if the position has any call base context.
943 bool hasCallBaseContext() const { return CBContext != nullptr; }
944
945 /// Special DenseMap key values.
946 ///
947 ///{
949 ///}
950
951 /// Conversion into a void * to allow reuse of pointer hashing.
952 operator void *() const { return Enc.getOpaqueValue(); }
953
954private:
955 /// Private constructor for special values only!
956 explicit IRPosition(void *Ptr, const CallBaseContext *CBContext = nullptr)
957 : CBContext(CBContext) {
958 Enc.setFromOpaqueValue(Ptr);
959 }
960
961 /// IRPosition anchored at \p AnchorVal with kind/argument numbet \p PK.
962 explicit IRPosition(Value &AnchorVal, Kind PK,
963 const CallBaseContext *CBContext = nullptr)
964 : CBContext(CBContext) {
965 switch (PK) {
967 llvm_unreachable("Cannot create invalid IRP with an anchor value!");
968 break;
970 // Special case for floating functions.
971 if (isa<Function>(AnchorVal) || isa<CallBase>(AnchorVal))
972 Enc = {&AnchorVal, ENC_FLOATING_FUNCTION};
973 else
974 Enc = {&AnchorVal, ENC_VALUE};
975 break;
978 Enc = {&AnchorVal, ENC_VALUE};
979 break;
982 Enc = {&AnchorVal, ENC_RETURNED_VALUE};
983 break;
985 Enc = {&AnchorVal, ENC_VALUE};
986 break;
989 "Cannot create call site argument IRP with an anchor value!");
990 break;
991 }
992 verify();
993 }
994
995 /// Return the callee argument number of the associated value if it is an
996 /// argument or call site argument. See also `getCalleeArgNo` and
997 /// `getCallSiteArgNo`.
998 int getArgNo(bool CallbackCalleeArgIfApplicable) const {
999 if (CallbackCalleeArgIfApplicable)
1000 if (Argument *Arg = getAssociatedArgument())
1001 return Arg->getArgNo();
1002 switch (getPositionKind()) {
1004 return cast<Argument>(getAsValuePtr())->getArgNo();
1006 Use &U = *getAsUsePtr();
1007 return cast<CallBase>(U.getUser())->getArgOperandNo(&U);
1008 }
1009 default:
1010 return -1;
1011 }
1012 }
1013
1014 /// IRPosition for the use \p U. The position kind \p PK needs to be
1015 /// IRP_CALL_SITE_ARGUMENT, the anchor value is the user, the associated value
1016 /// the used value.
1017 explicit IRPosition(Use &U, Kind PK) {
1019 "Use constructor is for call site arguments only!");
1020 Enc = {&U, ENC_CALL_SITE_ARGUMENT_USE};
1021 verify();
1022 }
1023
1024 /// Verify internal invariants.
1025 LLVM_ABI void verify();
1026
1027 /// Return the underlying pointer as Value *, valid for all positions but
1028 /// IRP_CALL_SITE_ARGUMENT.
1029 Value *getAsValuePtr() const {
1030 assert(getEncodingBits() != ENC_CALL_SITE_ARGUMENT_USE &&
1031 "Not a value pointer!");
1032 return reinterpret_cast<Value *>(Enc.getPointer());
1033 }
1034
1035 /// Return the underlying pointer as Use *, valid only for
1036 /// IRP_CALL_SITE_ARGUMENT positions.
1037 Use *getAsUsePtr() const {
1038 assert(getEncodingBits() == ENC_CALL_SITE_ARGUMENT_USE &&
1039 "Not a value pointer!");
1040 return reinterpret_cast<Use *>(Enc.getPointer());
1041 }
1042
1043 /// Return true if \p EncodingBits describe a returned or call site returned
1044 /// position.
1045 static bool isReturnPosition(char EncodingBits) {
1046 return EncodingBits == ENC_RETURNED_VALUE;
1047 }
1048
1049 /// Return true if the encoding bits describe a returned or call site returned
1050 /// position.
1051 bool isReturnPosition() const { return isReturnPosition(getEncodingBits()); }
1052
1053 /// The encoding of the IRPosition is a combination of a pointer and two
1054 /// encoding bits. The values of the encoding bits are defined in the enum
1055 /// below. The pointer is either a Value* (for the first three encoding bit
1056 /// combinations) or Use* (for ENC_CALL_SITE_ARGUMENT_USE).
1057 ///
1058 ///{
1059 enum {
1060 ENC_VALUE = 0b00,
1061 ENC_RETURNED_VALUE = 0b01,
1062 ENC_FLOATING_FUNCTION = 0b10,
1063 ENC_CALL_SITE_ARGUMENT_USE = 0b11,
1064 };
1065
1066 // Reserve the maximal amount of bits so there is no need to mask out the
1067 // remaining ones. We will not encode anything else in the pointer anyway.
1068 static constexpr int NumEncodingBits =
1070 static_assert(NumEncodingBits >= 2, "At least two bits are required!");
1071
1072 /// The pointer with the encoding bits.
1073 PointerIntPair<void *, NumEncodingBits, char> Enc;
1074 ///}
1075
1076 /// Call base context. Used for callsite specific analysis.
1077 const CallBaseContext *CBContext = nullptr;
1078
1079 /// Return the encoding bits.
1080 char getEncodingBits() const { return Enc.getInt(); }
1081};
1082
1083/// Helper that allows IRPosition as a key in a DenseMap.
1084template <> struct DenseMapInfo<IRPosition> {
1085 static inline IRPosition getEmptyKey() { return IRPosition::EmptyKey; }
1086 static unsigned getHashValue(const IRPosition &IRP) {
1087 return (DenseMapInfo<void *>::getHashValue(IRP) << 4) ^
1089 }
1090
1091 static bool isEqual(const IRPosition &a, const IRPosition &b) {
1092 return a == b;
1093 }
1094};
1095
1096/// A visitor class for IR positions.
1097///
1098/// Given a position P, the SubsumingPositionIterator allows to visit "subsuming
1099/// positions" wrt. attributes/information. Thus, if a piece of information
1100/// holds for a subsuming position, it also holds for the position P.
1101///
1102/// The subsuming positions always include the initial position and then,
1103/// depending on the position kind, additionally the following ones:
1104/// - for IRP_RETURNED:
1105/// - the function (IRP_FUNCTION)
1106/// - for IRP_ARGUMENT:
1107/// - the function (IRP_FUNCTION)
1108/// - for IRP_CALL_SITE:
1109/// - the callee (IRP_FUNCTION), if known
1110/// - for IRP_CALL_SITE_RETURNED:
1111/// - the callee (IRP_RETURNED), if known
1112/// - the call site (IRP_FUNCTION)
1113/// - the callee (IRP_FUNCTION), if known
1114/// - for IRP_CALL_SITE_ARGUMENT:
1115/// - the argument of the callee (IRP_ARGUMENT), if known
1116/// - the callee (IRP_FUNCTION), if known
1117/// - the position the call site argument is associated with if it is not
1118/// anchored to the call site, e.g., if it is an argument then the argument
1119/// (IRP_ARGUMENT)
1121 SmallVector<IRPosition, 4> IRPositions;
1122 using iterator = decltype(IRPositions)::iterator;
1123
1124public:
1126 iterator begin() { return IRPositions.begin(); }
1127 iterator end() { return IRPositions.end(); }
1128};
1129
1130/// Wrapper for FunctionAnalysisManager.
1132 // The client may be running the old pass manager, in which case, we need to
1133 // map the requested Analysis to its equivalent wrapper in the old pass
1134 // manager. The scheme implemented here does not require every Analysis to be
1135 // updated. Only those new analyses that the client cares about in the old
1136 // pass manager need to expose a LegacyWrapper type, and that wrapper should
1137 // support a getResult() method that matches the new Analysis.
1138 //
1139 // We need SFINAE to check for the LegacyWrapper, but function templates don't
1140 // allow partial specialization, which is needed in this case. So instead, we
1141 // use a constexpr bool to perform the SFINAE, and then use this information
1142 // inside the function template.
1143 template <typename, typename = void>
1144 static constexpr bool HasLegacyWrapper = false;
1145
1146 template <typename Analysis>
1147 typename Analysis::Result *getAnalysis(const Function &F,
1148 bool RequestCachedOnly = false) {
1149 if (!LegacyPass && !FAM)
1150 return nullptr;
1151 if (FAM) {
1152 if (CachedOnly || RequestCachedOnly)
1153 return FAM->getCachedResult<Analysis>(const_cast<Function &>(F));
1154 return &FAM->getResult<Analysis>(const_cast<Function &>(F));
1155 }
1156 if constexpr (HasLegacyWrapper<Analysis>) {
1157 if (!CachedOnly && !RequestCachedOnly)
1158 return &LegacyPass
1159 ->getAnalysis<typename Analysis::LegacyWrapper>(
1160 const_cast<Function &>(F))
1161 .getResult();
1162 if (auto *P =
1163 LegacyPass
1164 ->getAnalysisIfAvailable<typename Analysis::LegacyWrapper>())
1165 return &P->getResult();
1166 }
1167 return nullptr;
1168 }
1169
1170 /// Invalidates the analyses. Valid only when using the new pass manager.
1172 assert(FAM && "Can only be used from the new PM!");
1173 FAM->clear();
1174 }
1175
1176 AnalysisGetter(FunctionAnalysisManager &FAM, bool CachedOnly = false)
1177 : FAM(&FAM), CachedOnly(CachedOnly) {}
1178 AnalysisGetter(Pass *P, bool CachedOnly = false)
1179 : LegacyPass(P), CachedOnly(CachedOnly) {}
1180 AnalysisGetter() = default;
1181
1182private:
1183 FunctionAnalysisManager *FAM = nullptr;
1184 Pass *LegacyPass = nullptr;
1185
1186 /// If \p CachedOnly is true, no pass is created, just existing results are
1187 /// used. Also available per request.
1188 bool CachedOnly = false;
1189};
1190
1191template <typename Analysis>
1193 Analysis, std::void_t<typename Analysis::LegacyWrapper>> = true;
1194
1195/// Data structure to hold cached (LLVM-IR) information.
1196///
1197/// All attributes are given an InformationCache object at creation time to
1198/// avoid inspection of the IR by all of them individually. This default
1199/// InformationCache will hold information required by 'default' attributes,
1200/// thus the ones deduced when Attributor::identifyDefaultAbstractAttributes(..)
1201/// is called.
1202///
1203/// If custom abstract attributes, registered manually through
1204/// Attributor::registerAA(...), need more information, especially if it is not
1205/// reusable, it is advised to inherit from the InformationCache and cast the
1206/// instance down in the abstract attributes.
1210 bool UseExplorer = true)
1211 : CGSCC(CGSCC), M(M), Allocator(Allocator), AG(AG) {
1212 if (UseExplorer)
1213 Explorer = new (Allocator) MustBeExecutedContextExplorer(
1214 /* ExploreInterBlock */
1215 true, /* ExploreCFGForward */ true,
1216 /* ExploreCFGBackward */ true,
1217 /* LIGetter */
1218 [&](const Function &F) { return AG.getAnalysis<LoopAnalysis>(F); },
1219 /* DTGetter */
1220 [&](const Function &F) {
1221 return AG.getAnalysis<DominatorTreeAnalysis>(F);
1222 },
1223 /* PDTGetter */
1224 [&](const Function &F) {
1225 return AG.getAnalysis<PostDominatorTreeAnalysis>(F);
1226 });
1227 }
1228
1230 // The FunctionInfo objects are allocated via a BumpPtrAllocator, we call
1231 // the destructor manually.
1232 for (auto &It : FuncInfoMap)
1233 It.getSecond()->~FunctionInfo();
1234 // Same is true for the instruction exclusions sets.
1236 for (auto *BES : BESets)
1237 BES->~InstExclusionSetTy();
1238 if (Explorer)
1239 Explorer->~MustBeExecutedContextExplorer();
1240 }
1241
1242 /// Apply \p CB to all uses of \p F. If \p LookThroughConstantExprUses is
1243 /// true, constant expression users are not given to \p CB but their uses are
1244 /// traversed transitively.
1245 template <typename CBTy>
1246 static void foreachUse(Function &F, CBTy CB,
1247 bool LookThroughConstantExprUses = true) {
1248 SmallVector<Use *, 8> Worklist(make_pointer_range(F.uses()));
1249
1250 for (unsigned Idx = 0; Idx < Worklist.size(); ++Idx) {
1251 Use &U = *Worklist[Idx];
1252
1253 // Allow use in constant bitcasts and simply look through them.
1254 if (LookThroughConstantExprUses && isa<ConstantExpr>(U.getUser())) {
1255 for (Use &CEU : cast<ConstantExpr>(U.getUser())->uses())
1256 Worklist.push_back(&CEU);
1257 continue;
1258 }
1259
1260 CB(U);
1261 }
1262 }
1263
1264 /// The CG-SCC the pass is run on, or nullptr if it is a module pass.
1265 const SetVector<Function *> *const CGSCC = nullptr;
1266
1267 /// A vector type to hold instructions.
1269
1270 /// A map type from opcodes to instructions with this opcode.
1272
1273 /// Return the map that relates "interesting" opcodes with all instructions
1274 /// with that opcode in \p F.
1276 return getFunctionInfo(F).OpcodeInstMap;
1277 }
1278
1279 /// Return the instructions in \p F that may read or write memory.
1281 return getFunctionInfo(F).RWInsts;
1282 }
1283
1284 /// Return MustBeExecutedContextExplorer
1288
1289 /// Return TargetLibraryInfo for function \p F.
1293
1294 /// Return true if \p F has the "kernel" function attribute
1295 bool isKernel(const Function &F) {
1296 FunctionInfo &FI = getFunctionInfo(F);
1297 return FI.IsKernel;
1298 }
1299
1300 /// Return true if \p Arg is involved in a must-tail call, thus the argument
1301 /// of the caller or callee.
1303 FunctionInfo &FI = getFunctionInfo(*Arg.getParent());
1304 return FI.CalledViaMustTail || FI.ContainsMustTailCall;
1305 }
1306
1307 bool isOnlyUsedByAssume(const Instruction &I) const {
1308 return AssumeOnlyValues.contains(&I);
1309 }
1310
1311 /// Invalidates the cached analyses. Valid only when using the new pass
1312 /// manager.
1313 void invalidateAnalyses() { AG.invalidateAnalyses(); }
1314
1315 /// Return the analysis result from a pass \p AP for function \p F.
1316 template <typename AP>
1317 typename AP::Result *getAnalysisResultForFunction(const Function &F,
1318 bool CachedOnly = false) {
1319 return AG.getAnalysis<AP>(F, CachedOnly);
1320 }
1321
1322 const Module &getModule() const { return M; }
1323
1324 /// Return datalayout used in the module.
1325 const DataLayout &getDL() const { return M.getDataLayout(); }
1326
1327 /// Return the map conaining all the knowledge we have from `llvm.assume`s.
1328 const RetainedKnowledgeMap &getKnowledgeMap() const { return KnowledgeMap; }
1329
1330 /// Given \p BES, return a uniqued version.
1333 auto It = BESets.find(BES);
1334 if (It != BESets.end())
1335 return *It;
1336 auto *UniqueBES = new (Allocator) AA::InstExclusionSetTy(*BES);
1337 bool Success = BESets.insert(UniqueBES).second;
1338 (void)Success;
1339 assert(Success && "Expected only new entries to be added");
1340 return UniqueBES;
1341 }
1342
1343 /// Return true if the stack (llvm::Alloca) can be accessed by other threads.
1345
1346 /// Return true if the target is a GPU.
1347 bool IsTargetGPU() const { return M.getTargetTriple().isGPU(); }
1348
1349 /// Return all functions that might be called indirectly, only valid for
1350 /// closed world modules (see isClosedWorldModule).
1353
1354 /// Return the flat address space if the associated target has.
1355 LLVM_ABI std::optional<unsigned> getFlatAddressSpace() const;
1356
1357 virtual unsigned getMaxAddrSpace() const { return ~0U; }
1358
1359private:
1360 struct FunctionInfo {
1361 LLVM_ABI ~FunctionInfo();
1362
1363 /// A nested map that remembers all instructions in a function with a
1364 /// certain instruction opcode (Instruction::getOpcode()).
1365 OpcodeInstMapTy OpcodeInstMap;
1366
1367 /// A map from functions to their instructions that may read or write
1368 /// memory.
1369 InstructionVectorTy RWInsts;
1370
1371 /// Function is called by a `musttail` call.
1372 bool CalledViaMustTail;
1373
1374 /// Function contains a `musttail` call.
1375 bool ContainsMustTailCall;
1376
1377 /// Function has the `"kernel"` attribute
1378 bool IsKernel;
1379 };
1380
1381 /// A map type from functions to informatio about it.
1382 DenseMap<const Function *, FunctionInfo *> FuncInfoMap;
1383
1384 /// Return information about the function \p F, potentially by creating it.
1385 FunctionInfo &getFunctionInfo(const Function &F) {
1386 FunctionInfo *&FI = FuncInfoMap[&F];
1387 if (!FI) {
1388 FI = new (Allocator) FunctionInfo();
1389 initializeInformationCache(F, *FI);
1390 }
1391 return *FI;
1392 }
1393
1394 /// Vector of functions that might be callable indirectly, i.a., via a
1395 /// function pointer.
1396 SmallVector<Function *> IndirectlyCallableFunctions;
1397
1398 /// Initialize the function information cache \p FI for the function \p F.
1399 ///
1400 /// This method needs to be called for all function that might be looked at
1401 /// through the information cache interface *prior* to looking at them.
1402 LLVM_ABI void initializeInformationCache(const Function &F, FunctionInfo &FI);
1403
1404 /// The module.
1405 const Module &M;
1406
1407 /// The allocator used to allocate memory, e.g. for `FunctionInfo`s.
1408 BumpPtrAllocator &Allocator;
1409
1410 /// MustBeExecutedContextExplorer
1411 MustBeExecutedContextExplorer *Explorer = nullptr;
1412
1413 /// A map with knowledge retained in `llvm.assume` instructions.
1414 RetainedKnowledgeMap KnowledgeMap;
1415
1416 /// A container for all instructions that are only used by `llvm.assume`.
1417 SetVector<const Instruction *> AssumeOnlyValues;
1418
1419 /// Cache for block sets to allow reuse.
1420 DenseSet<const AA::InstExclusionSetTy *> BESets;
1421
1422 /// Getters for analysis.
1423 AnalysisGetter &AG;
1424
1425 /// Set of inlineable functions
1426 SmallPtrSet<const Function *, 8> InlineableFunctions;
1427
1428 /// Give the Attributor access to the members so
1429 /// Attributor::identifyDefaultAbstractAttributes(...) can initialize them.
1430 friend struct Attributor;
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 not null, a set limiting the attribute opportunities.
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/// A debug counter to limit the number of AAs created.
1498DEBUG_COUNTER(NumAbstractAttributes, "num-abstract-attributes",
1499 "How many AAs should be initialized");
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
1602 if (!DebugCounter::shouldExecute(NumAbstractAttributes))
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 TimeTraceScope TimeScope("initialize", [&]() {
1623 return AA.getName().str() +
1624 std::to_string(AA.getIRPosition().getPositionKind());
1625 });
1626 ++InitializationChainLength;
1627 AA.initialize(*this);
1628 --InitializationChainLength;
1629 }
1630
1631 if (!ShouldUpdateAA) {
1632 AA.getState().indicatePessimisticFixpoint();
1633 return &AA;
1634 }
1635
1636 // Allow seeded attributes to declare dependencies.
1637 // Remember the seeding state.
1638 if (UpdateAfterInit) {
1639 AttributorPhase OldPhase = Phase;
1640 Phase = AttributorPhase::UPDATE;
1641
1642 updateAA(AA);
1643
1644 Phase = OldPhase;
1645 }
1646
1647 if (QueryingAA && AA.getState().isValidState())
1648 recordDependence(AA, const_cast<AbstractAttribute &>(*QueryingAA),
1649 DepClass);
1650 return &AA;
1651 }
1652
1653 template <typename AAType>
1654 const AAType *getOrCreateAAFor(const IRPosition &IRP) {
1655 return getOrCreateAAFor<AAType>(IRP, /* QueryingAA */ nullptr,
1657 }
1658
1659 /// Return the attribute of \p AAType for \p IRP if existing and valid. This
1660 /// also allows non-AA users lookup.
1661 template <typename AAType>
1662 AAType *lookupAAFor(const IRPosition &IRP,
1663 const AbstractAttribute *QueryingAA = nullptr,
1665 bool AllowInvalidState = false) {
1666 static_assert(std::is_base_of<AbstractAttribute, AAType>::value,
1667 "Cannot query an attribute with a type not derived from "
1668 "'AbstractAttribute'!");
1669 // Lookup the abstract attribute of type AAType. If found, return it after
1670 // registering a dependence of QueryingAA on the one returned attribute.
1671 AbstractAttribute *AAPtr = AAMap.lookup({&AAType::ID, IRP});
1672 if (!AAPtr)
1673 return nullptr;
1674
1675 AAType *AA = static_cast<AAType *>(AAPtr);
1676
1677 // Do not register a dependence on an attribute with an invalid state.
1678 if (DepClass != DepClassTy::NONE && QueryingAA &&
1679 AA->getState().isValidState())
1680 recordDependence(*AA, const_cast<AbstractAttribute &>(*QueryingAA),
1681 DepClass);
1682
1683 // Return nullptr if this attribute has an invalid state.
1684 if (!AllowInvalidState && !AA->getState().isValidState())
1685 return nullptr;
1686 return AA;
1687 }
1688
1689 /// Allows a query AA to request an update if a new query was received.
1691
1692 /// Explicitly record a dependence from \p FromAA to \p ToAA, that is if
1693 /// \p FromAA changes \p ToAA should be updated as well.
1694 ///
1695 /// This method should be used in conjunction with the `getAAFor` method and
1696 /// with the DepClass enum passed to the method set to None. This can
1697 /// be beneficial to avoid false dependences but it requires the users of
1698 /// `getAAFor` to explicitly record true dependences through this method.
1699 /// The \p DepClass flag indicates if the dependence is striclty necessary.
1700 /// That means for required dependences, if \p FromAA changes to an invalid
1701 /// state, \p ToAA can be moved to a pessimistic fixpoint because it required
1702 /// information from \p FromAA but none are available anymore.
1703 LLVM_ABI void recordDependence(const AbstractAttribute &FromAA,
1704 const AbstractAttribute &ToAA,
1705 DepClassTy DepClass);
1706
1707 /// Introduce a new abstract attribute into the fixpoint analysis.
1708 ///
1709 /// Note that ownership of the attribute is given to the Attributor. It will
1710 /// invoke delete for the Attributor on destruction of the Attributor.
1711 ///
1712 /// Attributes are identified by their IR position (AAType::getIRPosition())
1713 /// and the address of their static member (see AAType::ID).
1714 template <typename AAType> AAType &registerAA(AAType &AA) {
1715 static_assert(std::is_base_of<AbstractAttribute, AAType>::value,
1716 "Cannot register an attribute with a type not derived from "
1717 "'AbstractAttribute'!");
1718 // Put the attribute in the lookup map structure and the container we use to
1719 // keep track of all attributes.
1720 const IRPosition &IRP = AA.getIRPosition();
1721 AbstractAttribute *&AAPtr = AAMap[{&AAType::ID, IRP}];
1722
1723 assert(!AAPtr && "Attribute already in map!");
1724 AAPtr = &AA;
1725
1726 // Register AA with the synthetic root only before the manifest stage.
1727 if (Phase == AttributorPhase::SEEDING || Phase == AttributorPhase::UPDATE)
1728 DG.SyntheticRoot.Deps.insert(
1730
1731 return AA;
1732 }
1733
1734 /// Return the internal information cache.
1735 InformationCache &getInfoCache() { return InfoCache; }
1736
1737 /// Return the module.
1738 const Module &getModule() { return InfoCache.getModule(); }
1739
1740 /// Return true if this is a module pass, false otherwise.
1741 bool isModulePass() const { return Configuration.IsModulePass; }
1742
1743 /// Return true if we should specialize the call site \b CB for the potential
1744 /// callee \p Fn.
1746 CallBase &CB, Function &Callee,
1747 unsigned NumAssumedCallees) {
1748 return Configuration.IndirectCalleeSpecializationCallback
1749 ? Configuration.IndirectCalleeSpecializationCallback(
1750 *this, AA, CB, Callee, NumAssumedCallees)
1751 : true;
1752 }
1753
1754 /// Return true if the module contains the whole world, thus, no outside
1755 /// functions exist.
1756 LLVM_ABI bool isClosedWorldModule() const;
1757
1758 /// Return true if we derive attributes for \p Fn
1759 bool isRunOn(Function &Fn) const { return isRunOn(&Fn); }
1760 bool isRunOn(Function *Fn) const {
1761 return Functions.empty() || Functions.count(Fn);
1762 }
1763
1764 template <typename AAType> bool shouldUpdateAA(const IRPosition &IRP) {
1765 // If this is queried in the manifest stage, we force the AA to indicate
1766 // pessimistic fixpoint immediately.
1767 if (Phase == AttributorPhase::MANIFEST || Phase == AttributorPhase::CLEANUP)
1768 return false;
1769
1770 Function *AssociatedFn = IRP.getAssociatedFunction();
1771
1772 if (IRP.isAnyCallSitePosition()) {
1773 // Check if we require a callee but there is none.
1774 if (!AssociatedFn && AAType::requiresCalleeForCallBase())
1775 return false;
1776
1777 // Check if we require non-asm but it is inline asm.
1778 if (AAType::requiresNonAsmForCallBase() &&
1779 cast<CallBase>(IRP.getAnchorValue()).isInlineAsm())
1780 return false;
1781 }
1782
1783 // Check if we require a calles but we can't see all.
1784 if (AAType::requiresCallersForArgOrFunction())
1787 if (!AssociatedFn->hasLocalLinkage())
1788 return false;
1789
1790 if (!AAType::isValidIRPositionForUpdate(*this, IRP))
1791 return false;
1792
1793 // We update only AAs associated with functions in the Functions set or
1794 // call sites of them.
1795 return (!AssociatedFn || isModulePass() || isRunOn(AssociatedFn) ||
1796 isRunOn(IRP.getAnchorScope()));
1797 }
1798
1799 template <typename AAType>
1800 bool shouldInitialize(const IRPosition &IRP, bool &ShouldUpdateAA) {
1801 if (!AAType::isValidIRPositionForInit(*this, IRP))
1802 return false;
1803
1804 if (Configuration.Allowed && !Configuration.Allowed->count(&AAType::ID))
1805 return false;
1806
1807 // For now we skip anything in naked and optnone functions.
1808 const Function *AnchorFn = IRP.getAnchorScope();
1809 if (AnchorFn && (AnchorFn->hasFnAttribute(Attribute::Naked) ||
1810 AnchorFn->hasFnAttribute(Attribute::OptimizeNone)))
1811 return false;
1812
1813 // Avoid too many nested initializations to prevent a stack overflow.
1814 if (InitializationChainLength > MaxInitializationChainLength)
1815 return false;
1816
1817 ShouldUpdateAA = shouldUpdateAA<AAType>(IRP);
1818
1819 return !AAType::hasTrivialInitializer() || ShouldUpdateAA;
1820 }
1821
1822 /// Determine opportunities to derive 'default' attributes in \p F and create
1823 /// abstract attribute objects for them.
1824 ///
1825 /// \param F The function that is checked for attribute opportunities.
1826 ///
1827 /// Note that abstract attribute instances are generally created even if the
1828 /// IR already contains the information they would deduce. The most important
1829 /// reason for this is the single interface, the one of the abstract attribute
1830 /// instance, which can be queried without the need to look at the IR in
1831 /// various places.
1833
1834 /// Determine whether the function \p F is IPO amendable
1835 ///
1836 /// If a function is exactly defined or it has alwaysinline attribute
1837 /// and is viable to be inlined, we say it is IPO amendable
1839 return F.hasExactDefinition() || InfoCache.InlineableFunctions.count(&F) ||
1840 (Configuration.IPOAmendableCB && Configuration.IPOAmendableCB(F));
1841 }
1842
1843 /// Mark the internal function \p F as live.
1844 ///
1845 /// This will trigger the identification and initialization of attributes for
1846 /// \p F.
1848 assert(F.hasLocalLinkage() &&
1849 "Only local linkage is assumed dead initially.");
1850
1851 if (Configuration.DefaultInitializeLiveInternals)
1853 if (Configuration.InitializationCallback)
1854 Configuration.InitializationCallback(*this, F);
1855 }
1856
1857 /// Record that \p U is to be replaces with \p NV after information was
1858 /// manifested. This also triggers deletion of trivially dead istructions.
1860 Value *&V = ToBeChangedUses[&U];
1861 if (V && (V->stripPointerCasts() == NV.stripPointerCasts() ||
1863 return false;
1864 assert((!V || V == &NV || isa<UndefValue>(NV)) &&
1865 "Use was registered twice for replacement with different values!");
1866 V = &NV;
1867 return true;
1868 }
1869
1870 /// Helper function to replace all uses associated with \p IRP with \p NV.
1871 /// Return true if there is any change. The flag \p ChangeDroppable indicates
1872 /// if dropppable uses should be changed too.
1874 bool ChangeDroppable = true) {
1876 auto *CB = cast<CallBase>(IRP.getCtxI());
1878 CB->getArgOperandUse(IRP.getCallSiteArgNo()), NV);
1879 }
1880 Value &V = IRP.getAssociatedValue();
1881 auto &Entry = ToBeChangedValues[&V];
1882 Value *CurNV = get<0>(Entry);
1883 if (CurNV && (CurNV->stripPointerCasts() == NV.stripPointerCasts() ||
1884 isa<UndefValue>(CurNV)))
1885 return false;
1886 assert((!CurNV || CurNV == &NV || isa<UndefValue>(NV)) &&
1887 "Value replacement was registered twice with different values!");
1888 Entry = {&NV, ChangeDroppable};
1889 return true;
1890 }
1891
1892 /// Record that \p I is to be replaced with `unreachable` after information
1893 /// was manifested.
1895 ToBeChangedToUnreachableInsts.insert(I);
1896 }
1897
1898 /// Record that \p II has at least one dead successor block. This information
1899 /// is used, e.g., to replace \p II with a call, after information was
1900 /// manifested.
1902 InvokeWithDeadSuccessor.insert(&II);
1903 }
1904
1905 /// Record that \p I is deleted after information was manifested. This also
1906 /// triggers deletion of trivially dead istructions.
1907 void deleteAfterManifest(Instruction &I) { ToBeDeletedInsts.insert(&I); }
1908
1909 /// Record that \p BB is deleted after information was manifested. This also
1910 /// triggers deletion of trivially dead istructions.
1911 void deleteAfterManifest(BasicBlock &BB) { ToBeDeletedBlocks.insert(&BB); }
1912
1913 // Record that \p BB is added during the manifest of an AA. Added basic blocks
1914 // are preserved in the IR.
1916 ManifestAddedBlocks.insert(&BB);
1917 }
1918
1919 /// Record that \p F is deleted after information was manifested.
1921 if (Configuration.DeleteFns)
1922 ToBeDeletedFunctions.insert(&F);
1923 }
1924
1925 /// Return the attributes of kind \p AK existing in the IR as operand bundles
1926 /// of an llvm.assume.
1927 LLVM_ABI bool getAttrsFromAssumes(const IRPosition &IRP,
1930
1931 /// Return true if any kind in \p AKs existing in the IR at a position that
1932 /// will affect this one. See also getAttrs(...).
1933 /// \param IgnoreSubsumingPositions Flag to determine if subsuming positions,
1934 /// e.g., the function position if this is an
1935 /// argument position, should be ignored.
1936 LLVM_ABI bool
1938 bool IgnoreSubsumingPositions = false,
1939 Attribute::AttrKind ImpliedAttributeKind = Attribute::None);
1940
1941 /// Return the attributes of any kind in \p AKs existing in the IR at a
1942 /// position that will affect this one. While each position can only have a
1943 /// single attribute of any kind in \p AKs, there are "subsuming" positions
1944 /// that could have an attribute as well. This method returns all attributes
1945 /// found in \p Attrs.
1946 /// \param IgnoreSubsumingPositions Flag to determine if subsuming positions,
1947 /// e.g., the function position if this is an
1948 /// argument position, should be ignored.
1949 LLVM_ABI void getAttrs(const IRPosition &IRP,
1952 bool IgnoreSubsumingPositions = false);
1953
1954 /// Remove all \p AttrKinds attached to \p IRP.
1958 ArrayRef<StringRef> Attrs);
1959
1960 /// Attach \p DeducedAttrs to \p IRP, if \p ForceReplace is set we do this
1961 /// even if the same attribute kind was already present.
1963 ArrayRef<Attribute> DeducedAttrs,
1964 bool ForceReplace = false);
1965
1966private:
1967 /// Helper to check \p Attrs for \p AK, if not found, check if \p
1968 /// AAType::isImpliedByIR is true, and if not, create AAType for \p IRP.
1969 /// If \p SkipHasAttrCheck is true, don't check whether the attribute is set
1970 /// first. This should be used if only some values of a complex IR attribute
1971 /// imply the AAType.
1972 template <Attribute::AttrKind AK, typename AAType>
1973 void checkAndQueryIRAttr(const IRPosition &IRP, AttributeSet Attrs,
1974 bool SkipHasAttrCheck = false);
1975
1976 /// Helper to apply \p CB on all attributes of type \p AttrDescs of \p IRP.
1977 template <typename DescTy>
1978 ChangeStatus updateAttrMap(const IRPosition &IRP, ArrayRef<DescTy> AttrDescs,
1979 function_ref<bool(const DescTy &, AttributeSet,
1980 AttributeMask &, AttrBuilder &)>
1981 CB);
1982
1983 /// Mapping from functions/call sites to their attributes.
1985
1986public:
1987 /// If \p IRP is assumed to be a constant, return it, if it is unclear yet,
1988 /// return std::nullopt, otherwise return `nullptr`.
1989 LLVM_ABI std::optional<Constant *>
1991 bool &UsedAssumedInformation);
1992 std::optional<Constant *> getAssumedConstant(const Value &V,
1993 const AbstractAttribute &AA,
1994 bool &UsedAssumedInformation) {
1995 return getAssumedConstant(IRPosition::value(V), AA, UsedAssumedInformation);
1996 }
1997
1998 /// If \p V is assumed simplified, return it, if it is unclear yet,
1999 /// return std::nullopt, otherwise return `nullptr`.
2000 std::optional<Value *> getAssumedSimplified(const IRPosition &IRP,
2001 const AbstractAttribute &AA,
2002 bool &UsedAssumedInformation,
2003 AA::ValueScope S) {
2004 return getAssumedSimplified(IRP, &AA, UsedAssumedInformation, S);
2005 }
2006 std::optional<Value *> getAssumedSimplified(const Value &V,
2007 const AbstractAttribute &AA,
2008 bool &UsedAssumedInformation,
2009 AA::ValueScope S) {
2011 UsedAssumedInformation, S);
2012 }
2013
2014 /// If \p V is assumed simplified, return it, if it is unclear yet,
2015 /// return std::nullopt, otherwise return `nullptr`. Same as the public
2016 /// version except that it can be used without recording dependences on any \p
2017 /// AA.
2018 LLVM_ABI std::optional<Value *>
2020 bool &UsedAssumedInformation, AA::ValueScope S);
2021
2022 /// Try to simplify \p IRP and in the scope \p S. If successful, true is
2023 /// returned and all potential values \p IRP can take are put into \p Values.
2024 /// If the result in \p Values contains select or PHI instructions it means
2025 /// those could not be simplified to a single value. Recursive calls with
2026 /// these instructions will yield their respective potential values. If false
2027 /// is returned no other information is valid.
2028 LLVM_ABI bool
2031 AA::ValueScope S, bool &UsedAssumedInformation,
2032 bool RecurseForSelectAndPHI = true);
2033
2034 /// Register \p CB as a simplification callback.
2035 /// `Attributor::getAssumedSimplified` will use these callbacks before
2036 /// we it will ask `AAValueSimplify`. It is important to ensure this
2037 /// is called before `identifyDefaultAbstractAttributes`, assuming the
2038 /// latter is called at all.
2039 using SimplifictionCallbackTy = std::function<std::optional<Value *>(
2040 const IRPosition &, const AbstractAttribute *, bool &)>;
2042 const SimplifictionCallbackTy &CB) {
2043 SimplificationCallbacks[IRP].emplace_back(CB);
2044 }
2045
2046 /// Return true if there is a simplification callback for \p IRP.
2048 return SimplificationCallbacks.count(IRP);
2049 }
2050
2051 /// Register \p CB as a simplification callback.
2052 /// Similar to \p registerSimplificationCallback, the call back will be called
2053 /// first when we simplify a global variable \p GV.
2055 std::function<std::optional<Constant *>(
2056 const GlobalVariable &, const AbstractAttribute *, bool &)>;
2058 const GlobalVariable &GV,
2060 GlobalVariableSimplificationCallbacks[&GV].emplace_back(CB);
2061 }
2062
2063 /// Return true if there is a simplification callback for \p GV.
2065 return GlobalVariableSimplificationCallbacks.count(&GV);
2066 }
2067
2068 /// Return \p std::nullopt if there is no call back registered for \p GV or
2069 /// the call back is still not sure if \p GV can be simplified. Return \p
2070 /// nullptr if \p GV can't be simplified.
2071 std::optional<Constant *>
2073 const AbstractAttribute *AA,
2074 bool &UsedAssumedInformation) {
2075 assert(GlobalVariableSimplificationCallbacks.contains(&GV));
2076 for (auto &CB : GlobalVariableSimplificationCallbacks.lookup(&GV)) {
2077 auto SimplifiedGV = CB(GV, AA, UsedAssumedInformation);
2078 // For now we assume the call back will not return a std::nullopt.
2079 assert(SimplifiedGV.has_value() && "SimplifiedGV has not value");
2080 return *SimplifiedGV;
2081 }
2082 llvm_unreachable("there must be a callback registered");
2083 }
2084
2086 std::function<bool(Attributor &, const AbstractAttribute *)>;
2088 const VirtualUseCallbackTy &CB) {
2089 VirtualUseCallbacks[&V].emplace_back(CB);
2090 }
2091
2092private:
2093 /// The vector with all simplification callbacks registered by outside AAs.
2095 SimplificationCallbacks;
2096
2097 /// The vector with all simplification callbacks for global variables
2098 /// registered by outside AAs.
2099 DenseMap<const GlobalVariable *,
2101 GlobalVariableSimplificationCallbacks;
2102
2104 VirtualUseCallbacks;
2105
2106public:
2107 /// Translate \p V from the callee context into the call site context.
2108 LLVM_ABI std::optional<Value *>
2109 translateArgumentToCallSiteContent(std::optional<Value *> V, CallBase &CB,
2110 const AbstractAttribute &AA,
2111 bool &UsedAssumedInformation);
2112
2113 /// Return true if \p AA (or its context instruction) is assumed dead.
2114 ///
2115 /// If \p LivenessAA is not provided it is queried.
2117 const AAIsDead *LivenessAA,
2118 bool &UsedAssumedInformation,
2119 bool CheckBBLivenessOnly = false,
2120 DepClassTy DepClass = DepClassTy::OPTIONAL);
2121
2122 /// Return true if \p I is assumed dead.
2123 ///
2124 /// If \p LivenessAA is not provided it is queried.
2125 LLVM_ABI bool isAssumedDead(const Instruction &I,
2126 const AbstractAttribute *QueryingAA,
2127 const AAIsDead *LivenessAA,
2128 bool &UsedAssumedInformation,
2129 bool CheckBBLivenessOnly = false,
2131 bool CheckForDeadStore = false);
2132
2133 /// Return true if \p U is assumed dead.
2134 ///
2135 /// If \p FnLivenessAA is not provided it is queried.
2136 LLVM_ABI bool isAssumedDead(const Use &U, const AbstractAttribute *QueryingAA,
2137 const AAIsDead *FnLivenessAA,
2138 bool &UsedAssumedInformation,
2139 bool CheckBBLivenessOnly = false,
2140 DepClassTy DepClass = DepClassTy::OPTIONAL);
2141
2142 /// Return true if \p IRP is assumed dead.
2143 ///
2144 /// If \p FnLivenessAA is not provided it is queried.
2145 LLVM_ABI bool isAssumedDead(const IRPosition &IRP,
2146 const AbstractAttribute *QueryingAA,
2147 const AAIsDead *FnLivenessAA,
2148 bool &UsedAssumedInformation,
2149 bool CheckBBLivenessOnly = false,
2150 DepClassTy DepClass = DepClassTy::OPTIONAL);
2151
2152 /// Return true if \p BB is assumed dead.
2153 ///
2154 /// If \p LivenessAA is not provided it is queried.
2155 LLVM_ABI bool isAssumedDead(const BasicBlock &BB,
2156 const AbstractAttribute *QueryingAA,
2157 const AAIsDead *FnLivenessAA,
2158 DepClassTy DepClass = DepClassTy::OPTIONAL);
2159
2160 /// Check \p Pred on all potential Callees of \p CB.
2161 ///
2162 /// This method will evaluate \p Pred with all potential callees of \p CB as
2163 /// input and return true if \p Pred does. If some callees might be unknown
2164 /// this function will return false.
2166 function_ref<bool(ArrayRef<const Function *> Callees)> Pred,
2167 const AbstractAttribute &QueryingAA, const CallBase &CB);
2168
2169 /// Check \p Pred on all (transitive) uses of \p V.
2170 ///
2171 /// This method will evaluate \p Pred on all (transitive) uses of the
2172 /// associated value and return true if \p Pred holds every time.
2173 /// If uses are skipped in favor of equivalent ones, e.g., if we look through
2174 /// memory, the \p EquivalentUseCB will be used to give the caller an idea
2175 /// what original used was replaced by a new one (or new ones). The visit is
2176 /// cut short if \p EquivalentUseCB returns false and the function will return
2177 /// false as well.
2179 function_ref<bool(const Use &, bool &)> Pred,
2180 const AbstractAttribute &QueryingAA, const Value &V,
2181 bool CheckBBLivenessOnly = false,
2182 DepClassTy LivenessDepClass = DepClassTy::OPTIONAL,
2183 bool IgnoreDroppableUses = true,
2184 function_ref<bool(const Use &OldU, const Use &NewU)> EquivalentUseCB =
2185 nullptr);
2186
2187 /// Emit a remark generically.
2188 ///
2189 /// This template function can be used to generically emit a remark. The
2190 /// RemarkKind should be one of the following:
2191 /// - OptimizationRemark to indicate a successful optimization attempt
2192 /// - OptimizationRemarkMissed to report a failed optimization attempt
2193 /// - OptimizationRemarkAnalysis to provide additional information about an
2194 /// optimization attempt
2195 ///
2196 /// The remark is built using a callback function \p RemarkCB that takes a
2197 /// RemarkKind as input and returns a RemarkKind.
2198 template <typename RemarkKind, typename RemarkCallBack>
2200 RemarkCallBack &&RemarkCB) const {
2201 if (!Configuration.OREGetter)
2202 return;
2203
2204 Function *F = I->getFunction();
2205 auto &ORE = Configuration.OREGetter(F);
2206
2207 if (RemarkName.starts_with("OMP"))
2208 ORE.emit([&]() {
2209 return RemarkCB(RemarkKind(Configuration.PassName, RemarkName, I))
2210 << " [" << RemarkName << "]";
2211 });
2212 else
2213 ORE.emit([&]() {
2214 return RemarkCB(RemarkKind(Configuration.PassName, RemarkName, I));
2215 });
2216 }
2217
2218 /// Emit a remark on a function.
2219 template <typename RemarkKind, typename RemarkCallBack>
2220 void emitRemark(Function *F, StringRef RemarkName,
2221 RemarkCallBack &&RemarkCB) const {
2222 if (!Configuration.OREGetter)
2223 return;
2224
2225 auto &ORE = Configuration.OREGetter(F);
2226
2227 if (RemarkName.starts_with("OMP"))
2228 ORE.emit([&]() {
2229 return RemarkCB(RemarkKind(Configuration.PassName, RemarkName, F))
2230 << " [" << RemarkName << "]";
2231 });
2232 else
2233 ORE.emit([&]() {
2234 return RemarkCB(RemarkKind(Configuration.PassName, RemarkName, F));
2235 });
2236 }
2237
2238 /// Helper struct used in the communication between an abstract attribute (AA)
2239 /// that wants to change the signature of a function and the Attributor which
2240 /// applies the changes. The struct is partially initialized with the
2241 /// information from the AA (see the constructor). All other members are
2242 /// provided by the Attributor prior to invoking any callbacks.
2243 struct ArgumentReplacementInfo {
2244 /// Callee repair callback type
2245 ///
2246 /// The function repair callback is invoked once to rewire the replacement
2247 /// arguments in the body of the new function. The argument replacement info
2248 /// is passed, as build from the registerFunctionSignatureRewrite call, as
2249 /// well as the replacement function and an iteratore to the first
2250 /// replacement argument.
2251 using CalleeRepairCBTy = std::function<void(
2252 const ArgumentReplacementInfo &, Function &, Function::arg_iterator)>;
2253
2254 /// Abstract call site (ACS) repair callback type
2255 ///
2256 /// The abstract call site repair callback is invoked once on every abstract
2257 /// call site of the replaced function (\see ReplacedFn). The callback needs
2258 /// to provide the operands for the call to the new replacement function.
2259 /// The number and type of the operands appended to the provided vector
2260 /// (second argument) is defined by the number and types determined through
2261 /// the replacement type vector (\see ReplacementTypes). The first argument
2262 /// is the ArgumentReplacementInfo object registered with the Attributor
2263 /// through the registerFunctionSignatureRewrite call.
2265 std::function<void(const ArgumentReplacementInfo &, AbstractCallSite,
2267
2268 /// Simple getters, see the corresponding members for details.
2269 ///{
2270
2271 Attributor &getAttributor() const { return A; }
2272 const Function &getReplacedFn() const { return ReplacedFn; }
2273 const Argument &getReplacedArg() const { return ReplacedArg; }
2274 unsigned getNumReplacementArgs() const { return ReplacementTypes.size(); }
2276 return ReplacementTypes;
2277 }
2278
2279 ///}
2280
2281 private:
2282 /// Constructor that takes the argument to be replaced, the types of
2283 /// the replacement arguments, as well as callbacks to repair the call sites
2284 /// and new function after the replacement happened.
2286 ArrayRef<Type *> ReplacementTypes,
2287 CalleeRepairCBTy &&CalleeRepairCB,
2288 ACSRepairCBTy &&ACSRepairCB)
2289 : A(A), ReplacedFn(*Arg.getParent()), ReplacedArg(Arg),
2290 ReplacementTypes(ReplacementTypes),
2291 CalleeRepairCB(std::move(CalleeRepairCB)),
2292 ACSRepairCB(std::move(ACSRepairCB)) {}
2293
2294 /// Reference to the attributor to allow access from the callbacks.
2295 Attributor &A;
2296
2297 /// The "old" function replaced by ReplacementFn.
2298 const Function &ReplacedFn;
2299
2300 /// The "old" argument replaced by new ones defined via ReplacementTypes.
2301 const Argument &ReplacedArg;
2302
2303 /// The types of the arguments replacing ReplacedArg.
2304 const SmallVector<Type *, 8> ReplacementTypes;
2305
2306 /// Callee repair callback, see CalleeRepairCBTy.
2307 const CalleeRepairCBTy CalleeRepairCB;
2308
2309 /// Abstract call site (ACS) repair callback, see ACSRepairCBTy.
2310 const ACSRepairCBTy ACSRepairCB;
2311
2312 /// Allow access to the private members from the Attributor.
2313 friend struct Attributor;
2314 };
2315
2316 /// Check if we can rewrite a function signature.
2317 ///
2318 /// The argument \p Arg is replaced with new ones defined by the number,
2319 /// order, and types in \p ReplacementTypes.
2320 ///
2321 /// \returns True, if the replacement can be registered, via
2322 /// registerFunctionSignatureRewrite, false otherwise.
2323 LLVM_ABI bool
2325 ArrayRef<Type *> ReplacementTypes);
2326
2327 /// Register a rewrite for a function signature.
2328 ///
2329 /// The argument \p Arg is replaced with new ones defined by the number,
2330 /// order, and types in \p ReplacementTypes. The rewiring at the call sites is
2331 /// done through \p ACSRepairCB and at the callee site through
2332 /// \p CalleeRepairCB.
2333 ///
2334 /// \returns True, if the replacement was registered, false otherwise.
2336 Argument &Arg, ArrayRef<Type *> ReplacementTypes,
2339
2340 /// Check \p Pred on all function call sites.
2341 ///
2342 /// This method will evaluate \p Pred on call sites and return
2343 /// true if \p Pred holds in every call sites. However, this is only possible
2344 /// all call sites are known, hence the function has internal linkage.
2345 /// If true is returned, \p UsedAssumedInformation is set if assumed
2346 /// information was used to skip or simplify potential call sites.
2348 const AbstractAttribute &QueryingAA,
2349 bool RequireAllCallSites,
2350 bool &UsedAssumedInformation);
2351
2352 /// Check \p Pred on all call sites of \p Fn.
2353 ///
2354 /// This method will evaluate \p Pred on call sites and return
2355 /// true if \p Pred holds in every call sites. However, this is only possible
2356 /// all call sites are known, hence the function has internal linkage.
2357 /// If true is returned, \p UsedAssumedInformation is set if assumed
2358 /// information was used to skip or simplify potential call sites.
2360 const Function &Fn,
2361 bool RequireAllCallSites,
2362 const AbstractAttribute *QueryingAA,
2363 bool &UsedAssumedInformation,
2364 bool CheckPotentiallyDead = false);
2365
2366 /// Check \p Pred on all values potentially returned by the function
2367 /// associated with \p QueryingAA.
2368 ///
2369 /// This is the context insensitive version of the method above.
2370 LLVM_ABI bool
2372 const AbstractAttribute &QueryingAA,
2374 bool RecurseForSelectAndPHI = true);
2375
2376 /// Check \p Pred on all instructions in \p Fn with an opcode present in
2377 /// \p Opcodes.
2378 ///
2379 /// This method will evaluate \p Pred on all instructions with an opcode
2380 /// present in \p Opcode and return true if \p Pred holds on all of them.
2382 const Function *Fn,
2383 const AbstractAttribute *QueryingAA,
2384 ArrayRef<unsigned> Opcodes,
2385 bool &UsedAssumedInformation,
2386 bool CheckBBLivenessOnly = false,
2387 bool CheckPotentiallyDead = false);
2388
2389 /// Check \p Pred on all instructions with an opcode present in \p Opcodes.
2390 ///
2391 /// This method will evaluate \p Pred on all instructions with an opcode
2392 /// present in \p Opcode and return true if \p Pred holds on all of them.
2394 const AbstractAttribute &QueryingAA,
2395 ArrayRef<unsigned> Opcodes,
2396 bool &UsedAssumedInformation,
2397 bool CheckBBLivenessOnly = false,
2398 bool CheckPotentiallyDead = false);
2399
2400 /// Check \p Pred on all call-like instructions (=CallBased derived).
2401 ///
2402 /// See checkForAllCallLikeInstructions(...) for more information.
2404 const AbstractAttribute &QueryingAA,
2405 bool &UsedAssumedInformation,
2406 bool CheckBBLivenessOnly = false,
2407 bool CheckPotentiallyDead = false) {
2409 Pred, QueryingAA,
2410 {(unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,
2411 (unsigned)Instruction::Call},
2412 UsedAssumedInformation, CheckBBLivenessOnly, CheckPotentiallyDead);
2413 }
2414
2415 /// Check \p Pred on all Read/Write instructions.
2416 ///
2417 /// This method will evaluate \p Pred on all instructions that read or write
2418 /// to memory present in the information cache and return true if \p Pred
2419 /// holds on all of them.
2420 LLVM_ABI bool
2422 AbstractAttribute &QueryingAA,
2423 bool &UsedAssumedInformation);
2424
2425 /// Create a shallow wrapper for \p F such that \p F has internal linkage
2426 /// afterwards. It also sets the original \p F 's name to anonymous
2427 ///
2428 /// A wrapper is a function with the same type (and attributes) as \p F
2429 /// that will only call \p F and return the result, if any.
2430 ///
2431 /// Assuming the declaration of looks like:
2432 /// rty F(aty0 arg0, ..., atyN argN);
2433 ///
2434 /// The wrapper will then look as follows:
2435 /// rty wrapper(aty0 arg0, ..., atyN argN) {
2436 /// return F(arg0, ..., argN);
2437 /// }
2438 ///
2440
2441 /// Returns true if the function \p F can be internalized. i.e. it has a
2442 /// compatible linkage.
2443 LLVM_ABI static bool isInternalizable(Function &F);
2444
2445 /// Make another copy of the function \p F such that the copied version has
2446 /// internal linkage afterwards and can be analysed. Then we replace all uses
2447 /// of the original function to the copied one
2448 ///
2449 /// Only non-locally linked functions that have `linkonce_odr` or `weak_odr`
2450 /// linkage can be internalized because these linkages guarantee that other
2451 /// definitions with the same name have the same semantics as this one.
2452 ///
2453 /// This will only be run if the `attributor-allow-deep-wrappers` option is
2454 /// set, or if the function is called with \p Force set to true.
2455 ///
2456 /// If the function \p F failed to be internalized the return value will be a
2457 /// null pointer.
2459 bool Force = false);
2460
2461 /// Make copies of each function in the set \p FnSet such that the copied
2462 /// version has internal linkage afterwards and can be analysed. Then we
2463 /// replace all uses of the original function to the copied one. The map
2464 /// \p FnMap contains a mapping of functions to their internalized versions.
2465 ///
2466 /// Only non-locally linked functions that have `linkonce_odr` or `weak_odr`
2467 /// linkage can be internalized because these linkages guarantee that other
2468 /// definitions with the same name have the same semantics as this one.
2469 ///
2470 /// This version will internalize all the functions in the set \p FnSet at
2471 /// once and then replace the uses. This prevents internalized functions being
2472 /// called by external functions when there is an internalized version in the
2473 /// module.
2474 LLVM_ABI static bool
2477
2478 /// Return the data layout associated with the anchor scope.
2479 const DataLayout &getDataLayout() const { return InfoCache.getDL(); }
2480
2481 /// The allocator used to allocate memory, e.g. for `AbstractAttribute`s.
2483
2485 return CGModifiedFunctions;
2486 }
2487
2488private:
2489 /// This method will do fixpoint iteration until fixpoint or the
2490 /// maximum iteration count is reached.
2491 ///
2492 /// If the maximum iteration count is reached, This method will
2493 /// indicate pessimistic fixpoint on attributes that transitively depend
2494 /// on attributes that were scheduled for an update.
2495 void runTillFixpoint();
2496
2497 /// Gets called after scheduling, manifests attributes to the LLVM IR.
2498 ChangeStatus manifestAttributes();
2499
2500 /// Gets called after attributes have been manifested, cleans up the IR.
2501 /// Deletes dead functions, blocks and instructions.
2502 /// Rewrites function signitures and updates the call graph.
2503 ChangeStatus cleanupIR();
2504
2505 /// Identify internal functions that are effectively dead, thus not reachable
2506 /// from a live entry point. The functions are added to ToBeDeletedFunctions.
2507 void identifyDeadInternalFunctions();
2508
2509 /// Run `::update` on \p AA and track the dependences queried while doing so.
2510 /// Also adjust the state if we know further updates are not necessary.
2512
2513 /// Remember the dependences on the top of the dependence stack such that they
2514 /// may trigger further updates. (\see DependenceStack)
2515 void rememberDependences();
2516
2517 /// Determine if CallBase context in \p IRP should be propagated.
2518 LLVM_ABI bool shouldPropagateCallBaseContext(const IRPosition &IRP);
2519
2520 /// Apply all requested function signature rewrites
2521 /// (\see registerFunctionSignatureRewrite) and return Changed if the module
2522 /// was altered.
2524 rewriteFunctionSignatures(SmallSetVector<Function *, 8> &ModifiedFns);
2525
2526 /// Check if the Attribute \p AA should be seeded.
2527 /// See getOrCreateAAFor.
2528 LLVM_ABI bool shouldSeedAttribute(AbstractAttribute &AA);
2529
2530 /// A nested map to lookup abstract attributes based on the argument position
2531 /// on the outer level, and the addresses of the static member (AAType::ID) on
2532 /// the inner level.
2533 ///{
2534 using AAMapKeyTy = std::pair<const char *, IRPosition>;
2536 ///}
2537
2538 /// Map to remember all requested signature changes (= argument replacements).
2540 ArgumentReplacementMap;
2541
2542 /// The set of functions we are deriving attributes for.
2543 SetVector<Function *> &Functions;
2544
2545 /// The information cache that holds pre-processed (LLVM-IR) information.
2546 InformationCache &InfoCache;
2547
2548 /// Abstract Attribute dependency graph
2549 AADepGraph DG;
2550
2551 /// Set of functions for which we modified the content such that it might
2552 /// impact the call graph.
2553 SmallSetVector<Function *, 8> CGModifiedFunctions;
2554
2555 /// Information about a dependence. If FromAA is changed ToAA needs to be
2556 /// updated as well.
2557 struct DepInfo {
2558 const AbstractAttribute *FromAA;
2559 const AbstractAttribute *ToAA;
2560 DepClassTy DepClass;
2561 };
2562
2563 /// The dependence stack is used to track dependences during an
2564 /// `AbstractAttribute::update` call. As `AbstractAttribute::update` can be
2565 /// recursive we might have multiple vectors of dependences in here. The stack
2566 /// size, should be adjusted according to the expected recursion depth and the
2567 /// inner dependence vector size to the expected number of dependences per
2568 /// abstract attribute. Since the inner vectors are actually allocated on the
2569 /// stack we can be generous with their size.
2570 using DependenceVector = SmallVector<DepInfo, 8>;
2572
2573 /// A set to remember the functions we already assume to be live and visited.
2574 DenseSet<const Function *> VisitedFunctions;
2575
2576 /// Uses we replace with a new value after manifest is done. We will remove
2577 /// then trivially dead instructions as well.
2578 SmallMapVector<Use *, Value *, 32> ToBeChangedUses;
2579
2580 /// Values we replace with a new value after manifest is done. We will remove
2581 /// then trivially dead instructions as well.
2582 SmallMapVector<Value *, PointerIntPair<Value *, 1, bool>, 32>
2583 ToBeChangedValues;
2584
2585 /// Instructions we replace with `unreachable` insts after manifest is done.
2586 SmallSetVector<WeakVH, 16> ToBeChangedToUnreachableInsts;
2587
2588 /// Invoke instructions with at least a single dead successor block.
2589 SmallSetVector<WeakVH, 16> InvokeWithDeadSuccessor;
2590
2591 /// A flag that indicates which stage of the process we are in. Initially, the
2592 /// phase is SEEDING. Phase is changed in `Attributor::run()`
2593 enum class AttributorPhase {
2594 SEEDING,
2595 UPDATE,
2596 MANIFEST,
2597 CLEANUP,
2598 } Phase = AttributorPhase::SEEDING;
2599
2600 /// The current initialization chain length. Tracked to avoid stack overflows.
2601 unsigned InitializationChainLength = 0;
2602
2603 /// Functions, blocks, and instructions we delete after manifest is done.
2604 ///
2605 ///{
2606 SmallPtrSet<BasicBlock *, 8> ManifestAddedBlocks;
2607 SmallSetVector<Function *, 8> ToBeDeletedFunctions;
2608 SmallSetVector<BasicBlock *, 8> ToBeDeletedBlocks;
2609 SmallSetVector<WeakVH, 8> ToBeDeletedInsts;
2610 ///}
2611
2612 /// Container with all the query AAs that requested an update via
2613 /// registerForUpdate.
2614 SmallSetVector<AbstractAttribute *, 16> QueryAAsAwaitingUpdate;
2615
2616 /// User provided configuration for this Attributor instance.
2617 const AttributorConfig Configuration;
2618
2619 friend AADepGraph;
2620 friend AttributorCallGraph;
2621};
2622
2623/// An interface to query the internal state of an abstract attribute.
2624///
2625/// The abstract state is a minimal interface that allows the Attributor to
2626/// communicate with the abstract attributes about their internal state without
2627/// enforcing or exposing implementation details, e.g., the (existence of an)
2628/// underlying lattice.
2629///
2630/// It is sufficient to be able to query if a state is (1) valid or invalid, (2)
2631/// at a fixpoint, and to indicate to the state that (3) an optimistic fixpoint
2632/// was reached or (4) a pessimistic fixpoint was enforced.
2633///
2634/// All methods need to be implemented by the subclass. For the common use case,
2635/// a single boolean state or a bit-encoded state, the BooleanState and
2636/// {Inc,Dec,Bit}IntegerState classes are already provided. An abstract
2637/// attribute can inherit from them to get the abstract state interface and
2638/// additional methods to directly modify the state based if needed. See the
2639/// class comments for help.
2641 virtual ~AbstractState() = default;
2642
2643 /// Return if this abstract state is in a valid state. If false, no
2644 /// information provided should be used.
2645 virtual bool isValidState() const = 0;
2646
2647 /// Return if this abstract state is fixed, thus does not need to be updated
2648 /// if information changes as it cannot change itself.
2649 virtual bool isAtFixpoint() const = 0;
2650
2651 /// Indicate that the abstract state should converge to the optimistic state.
2652 ///
2653 /// This will usually make the optimistically assumed state the known to be
2654 /// true state.
2655 ///
2656 /// \returns ChangeStatus::UNCHANGED as the assumed value should not change.
2658
2659 /// Indicate that the abstract state should converge to the pessimistic state.
2660 ///
2661 /// This will usually revert the optimistically assumed state to the known to
2662 /// be true state.
2663 ///
2664 /// \returns ChangeStatus::CHANGED as the assumed value may change.
2666};
2667
2668/// Simple state with integers encoding.
2669///
2670/// The interface ensures that the assumed bits are always a subset of the known
2671/// bits. Users can only add known bits and, except through adding known bits,
2672/// they can only remove assumed bits. This should guarantee monotonicity and
2673/// thereby the existence of a fixpoint (if used correctly). The fixpoint is
2674/// reached when the assumed and known state/bits are equal. Users can
2675/// force/inidicate a fixpoint. If an optimistic one is indicated, the known
2676/// state will catch up with the assumed one, for a pessimistic fixpoint it is
2677/// the other way around.
2678template <typename base_ty, base_ty BestState, base_ty WorstState>
2680 using base_t = base_ty;
2681
2682 IntegerStateBase() = default;
2684
2685 /// Return the best possible representable state.
2686 static constexpr base_t getBestState() { return BestState; }
2687 static constexpr base_t getBestState(const IntegerStateBase &) {
2688 return getBestState();
2689 }
2690
2691 /// Return the worst possible representable state.
2692 static constexpr base_t getWorstState() { return WorstState; }
2693 static constexpr base_t getWorstState(const IntegerStateBase &) {
2694 return getWorstState();
2695 }
2696
2697 /// See AbstractState::isValidState()
2698 /// NOTE: For now we simply pretend that the worst possible state is invalid.
2699 bool isValidState() const override { return Assumed != getWorstState(); }
2700
2701 /// See AbstractState::isAtFixpoint()
2702 bool isAtFixpoint() const override { return Assumed == Known; }
2703
2704 /// See AbstractState::indicateOptimisticFixpoint(...)
2709
2710 /// See AbstractState::indicatePessimisticFixpoint(...)
2715
2716 /// Return the known state encoding
2717 base_t getKnown() const { return Known; }
2718
2719 /// Return the assumed state encoding.
2720 base_t getAssumed() const { return Assumed; }
2721
2722 /// Equality for IntegerStateBase.
2723 bool
2725 return this->getAssumed() == R.getAssumed() &&
2726 this->getKnown() == R.getKnown();
2727 }
2728
2729 /// Inequality for IntegerStateBase.
2730 bool
2732 return !(*this == R);
2733 }
2734
2735 /// "Clamp" this state with \p R. The result is subtype dependent but it is
2736 /// intended that only information assumed in both states will be assumed in
2737 /// this one afterwards.
2741
2742 /// "Clamp" this state with \p R. The result is subtype dependent but it is
2743 /// intended that information known in either state will be known in
2744 /// this one afterwards.
2748
2750 joinOR(R.getAssumed(), R.getKnown());
2751 }
2752
2754 joinAND(R.getAssumed(), R.getKnown());
2755 }
2756
2757protected:
2758 /// Handle a new assumed value \p Value. Subtype dependent.
2760
2761 /// Handle a new known value \p Value. Subtype dependent.
2763
2764 /// Handle a value \p Value. Subtype dependent.
2765 virtual void joinOR(base_t AssumedValue, base_t KnownValue) = 0;
2766
2767 /// Handle a new assumed value \p Value. Subtype dependent.
2768 virtual void joinAND(base_t AssumedValue, base_t KnownValue) = 0;
2769
2770 /// The known state encoding in an integer of type base_t.
2772
2773 /// The assumed state encoding in an integer of type base_t.
2775};
2776
2777/// Specialization of the integer state for a bit-wise encoding.
2778template <typename base_ty = uint32_t, base_ty BestState = ~base_ty(0),
2779 base_ty WorstState = 0>
2781 : public IntegerStateBase<base_ty, BestState, WorstState> {
2783 using base_t = base_ty;
2784 BitIntegerState() = default;
2786
2787 /// Return true if the bits set in \p BitsEncoding are "known bits".
2788 bool isKnown(base_t BitsEncoding = BestState) const {
2789 return (this->Known & BitsEncoding) == BitsEncoding;
2790 }
2791
2792 /// Return true if the bits set in \p BitsEncoding are "assumed bits".
2793 bool isAssumed(base_t BitsEncoding = BestState) const {
2794 return (this->Assumed & BitsEncoding) == BitsEncoding;
2795 }
2796
2797 /// Add the bits in \p BitsEncoding to the "known bits".
2799 // Make sure we never miss any "known bits".
2800 this->Assumed |= Bits;
2801 this->Known |= Bits;
2802 return *this;
2803 }
2804
2805 /// Remove the bits in \p BitsEncoding from the "assumed bits" if not known.
2807 return intersectAssumedBits(~BitsEncoding);
2808 }
2809
2810 /// Remove the bits in \p BitsEncoding from the "known bits".
2812 this->Known = (this->Known & ~BitsEncoding);
2813 return *this;
2814 }
2815
2816 /// Keep only "assumed bits" also set in \p BitsEncoding but all known ones.
2818 // Make sure we never lose any "known bits".
2819 this->Assumed = (this->Assumed & BitsEncoding) | this->Known;
2820 return *this;
2821 }
2822
2823private:
2824 void handleNewAssumedValue(base_t Value) override {
2826 }
2827 void handleNewKnownValue(base_t Value) override { addKnownBits(Value); }
2828 void joinOR(base_t AssumedValue, base_t KnownValue) override {
2829 this->Known |= KnownValue;
2830 this->Assumed |= AssumedValue;
2831 }
2832 void joinAND(base_t AssumedValue, base_t KnownValue) override {
2833 this->Known &= KnownValue;
2834 this->Assumed &= AssumedValue;
2835 }
2836};
2837
2838/// Specialization of the integer state for an increasing value, hence ~0u is
2839/// the best state and 0 the worst.
2840template <typename base_ty = uint32_t, base_ty BestState = ~base_ty(0),
2841 base_ty WorstState = 0>
2843 : public IntegerStateBase<base_ty, BestState, WorstState> {
2845 using base_t = base_ty;
2846
2849
2850 /// Return the best possible representable state.
2851 static constexpr base_t getBestState() { return BestState; }
2852 static constexpr base_t
2856
2857 /// Take minimum of assumed and \p Value.
2859 // Make sure we never lose "known value".
2860 this->Assumed = std::max(std::min(this->Assumed, Value), this->Known);
2861 return *this;
2862 }
2863
2864 /// Take maximum of known and \p Value.
2866 // Make sure we never lose "known value".
2867 this->Assumed = std::max(Value, this->Assumed);
2868 this->Known = std::max(Value, this->Known);
2869 return *this;
2870 }
2871
2872private:
2873 void handleNewAssumedValue(base_t Value) override {
2875 }
2876 void handleNewKnownValue(base_t Value) override { takeKnownMaximum(Value); }
2877 void joinOR(base_t AssumedValue, base_t KnownValue) override {
2878 this->Known = std::max(this->Known, KnownValue);
2879 this->Assumed = std::max(this->Assumed, AssumedValue);
2880 }
2881 void joinAND(base_t AssumedValue, base_t KnownValue) override {
2882 this->Known = std::min(this->Known, KnownValue);
2883 this->Assumed = std::min(this->Assumed, AssumedValue);
2884 }
2885};
2886
2887/// Specialization of the integer state for a decreasing value, hence 0 is the
2888/// best state and ~0u the worst.
2889template <typename base_ty = uint32_t>
2890struct DecIntegerState : public IntegerStateBase<base_ty, 0, ~base_ty(0)> {
2891 using base_t = base_ty;
2892
2893 /// Take maximum of assumed and \p Value.
2895 // Make sure we never lose "known value".
2896 this->Assumed = std::min(std::max(this->Assumed, Value), this->Known);
2897 return *this;
2898 }
2899
2900 /// Take minimum of known and \p Value.
2902 // Make sure we never lose "known value".
2903 this->Assumed = std::min(Value, this->Assumed);
2904 this->Known = std::min(Value, this->Known);
2905 return *this;
2906 }
2907
2908private:
2909 void handleNewAssumedValue(base_t Value) override {
2911 }
2912 void handleNewKnownValue(base_t Value) override { takeKnownMinimum(Value); }
2913 void joinOR(base_t AssumedValue, base_t KnownValue) override {
2914 this->Assumed = std::min(this->Assumed, KnownValue);
2915 this->Assumed = std::min(this->Assumed, AssumedValue);
2916 }
2917 void joinAND(base_t AssumedValue, base_t KnownValue) override {
2918 this->Assumed = std::max(this->Assumed, KnownValue);
2919 this->Assumed = std::max(this->Assumed, AssumedValue);
2920 }
2921};
2922
2923/// Simple wrapper for a single bit (boolean) state.
2924struct BooleanState : public IntegerStateBase<bool, true, false> {
2927
2928 BooleanState() = default;
2930
2931 /// Set the assumed value to \p Value but never below the known one.
2932 void setAssumed(bool Value) { Assumed &= (Known | Value); }
2933
2934 /// Set the known and asssumed value to \p Value.
2935 void setKnown(bool Value) {
2936 Known |= Value;
2937 Assumed |= Value;
2938 }
2939
2940 /// Return true if the state is assumed to hold.
2941 bool isAssumed() const { return getAssumed(); }
2942
2943 /// Return true if the state is known to hold.
2944 bool isKnown() const { return getKnown(); }
2945
2946private:
2947 void handleNewAssumedValue(base_t Value) override {
2948 if (!Value)
2949 Assumed = Known;
2950 }
2951 void handleNewKnownValue(base_t Value) override {
2952 if (Value)
2953 Known = (Assumed = Value);
2954 }
2955 void joinOR(base_t AssumedValue, base_t KnownValue) override {
2956 Known |= KnownValue;
2957 Assumed |= AssumedValue;
2958 }
2959 void joinAND(base_t AssumedValue, base_t KnownValue) override {
2960 Known &= KnownValue;
2961 Assumed &= AssumedValue;
2962 }
2963};
2964
2965/// State for an integer range.
2967
2968 /// Bitwidth of the associated value.
2970
2971 /// State representing assumed range, initially set to empty.
2973
2974 /// State representing known range, initially set to [-inf, inf].
2976
2980
2984
2985 /// Return the worst possible representable state.
2987 return ConstantRange::getFull(BitWidth);
2988 }
2989
2990 /// Return the best possible representable state.
2992 return ConstantRange::getEmpty(BitWidth);
2993 }
2995 return getBestState(IRS.getBitWidth());
2996 }
2997
2998 /// Return associated values' bit width.
2999 uint32_t getBitWidth() const { return BitWidth; }
3000
3001 /// See AbstractState::isValidState()
3002 bool isValidState() const override {
3003 return BitWidth > 0 && !Assumed.isFullSet();
3004 }
3005
3006 /// See AbstractState::isAtFixpoint()
3007 bool isAtFixpoint() const override { return Assumed == Known; }
3008
3009 /// See AbstractState::indicateOptimisticFixpoint(...)
3014
3015 /// See AbstractState::indicatePessimisticFixpoint(...)
3020
3021 /// Return the known state encoding
3022 ConstantRange getKnown() const { return Known; }
3023
3024 /// Return the assumed state encoding.
3026
3027 /// Unite assumed range with the passed state.
3029 // Don't lose a known range.
3030 Assumed = Assumed.unionWith(R).intersectWith(Known);
3031 }
3032
3033 /// See IntegerRangeState::unionAssumed(..).
3035 unionAssumed(R.getAssumed());
3036 }
3037
3038 /// Intersect known range with the passed state.
3040 Assumed = Assumed.intersectWith(R);
3041 Known = Known.intersectWith(R);
3042 }
3043
3044 /// See IntegerRangeState::intersectKnown(..).
3046 intersectKnown(R.getKnown());
3047 }
3048
3049 /// Equality for IntegerRangeState.
3050 bool operator==(const IntegerRangeState &R) const {
3051 return getAssumed() == R.getAssumed() && getKnown() == R.getKnown();
3052 }
3053
3054 /// "Clamp" this state with \p R. The result is subtype dependent but it is
3055 /// intended that only information assumed in both states will be assumed in
3056 /// this one afterwards.
3058 // NOTE: `^=` operator seems like `intersect` but in this case, we need to
3059 // take `union`.
3060 unionAssumed(R);
3061 return *this;
3062 }
3063
3065 // NOTE: `&=` operator seems like `intersect` but in this case, we need to
3066 // take `union`.
3067 Known = Known.unionWith(R.getKnown());
3068 Assumed = Assumed.unionWith(R.getAssumed());
3069 return *this;
3070 }
3071};
3072
3073/// Simple state for a set.
3074///
3075/// This represents a state containing a set of values. The interface supports
3076/// modelling sets that contain all possible elements. The state's internal
3077/// value is modified using union or intersection operations.
3078template <typename BaseTy> struct SetState : public AbstractState {
3079 /// A wrapper around a set that has semantics for handling unions and
3080 /// intersections with a "universal" set that contains all elements.
3082 /// Creates a universal set with no concrete elements or an empty set.
3083 SetContents(bool Universal) : Universal(Universal) {}
3084
3085 /// Creates a non-universal set with concrete values.
3086 SetContents(const DenseSet<BaseTy> &Assumptions)
3087 : Universal(false), Set(Assumptions) {}
3088
3089 SetContents(bool Universal, const DenseSet<BaseTy> &Assumptions)
3090 : Universal(Universal), Set(Assumptions) {}
3091
3092 const DenseSet<BaseTy> &getSet() const { return Set; }
3093
3094 bool isUniversal() const { return Universal; }
3095
3096 bool empty() const { return Set.empty() && !Universal; }
3097
3098 /// Finds A := A ^ B where A or B could be the "Universal" set which
3099 /// contains every possible attribute. Returns true if changes were made.
3101 bool IsUniversal = Universal;
3102 unsigned Size = Set.size();
3103
3104 // A := A ^ U = A
3105 if (RHS.isUniversal())
3106 return false;
3107
3108 // A := U ^ B = B
3109 if (Universal)
3110 Set = RHS.getSet();
3111 else
3112 set_intersect(Set, RHS.getSet());
3113
3114 Universal &= RHS.isUniversal();
3115 return IsUniversal != Universal || Size != Set.size();
3116 }
3117
3118 /// Finds A := A u B where A or B could be the "Universal" set which
3119 /// contains every possible attribute. returns true if changes were made.
3120 bool getUnion(const SetContents &RHS) {
3121 bool IsUniversal = Universal;
3122 unsigned Size = Set.size();
3123
3124 // A := A u U = U = U u B
3125 if (!RHS.isUniversal() && !Universal)
3126 set_union(Set, RHS.getSet());
3127
3128 Universal |= RHS.isUniversal();
3129 return IsUniversal != Universal || Size != Set.size();
3130 }
3131
3132 private:
3133 /// Indicates if this set is "universal", containing every possible element.
3134 bool Universal;
3135
3136 /// The set of currently active assumptions.
3137 DenseSet<BaseTy> Set;
3138 };
3139
3140 SetState() : Known(false), Assumed(true), IsAtFixedpoint(false) {}
3141
3142 /// Initializes the known state with an initial set and initializes the
3143 /// assumed state as universal.
3145 : Known(Known), Assumed(true), IsAtFixedpoint(false) {}
3146
3147 /// See AbstractState::isValidState()
3148 bool isValidState() const override { return !Assumed.empty(); }
3149
3150 /// See AbstractState::isAtFixpoint()
3151 bool isAtFixpoint() const override { return IsAtFixedpoint; }
3152
3153 /// See AbstractState::indicateOptimisticFixpoint(...)
3155 IsAtFixedpoint = true;
3156 Known = Assumed;
3158 }
3159
3160 /// See AbstractState::indicatePessimisticFixpoint(...)
3162 IsAtFixedpoint = true;
3163 Assumed = Known;
3164 return ChangeStatus::CHANGED;
3165 }
3166
3167 /// Return the known state encoding.
3168 const SetContents &getKnown() const { return Known; }
3169
3170 /// Return the assumed state encoding.
3171 const SetContents &getAssumed() const { return Assumed; }
3172
3173 /// Returns if the set state contains the element.
3174 bool setContains(const BaseTy &Elem) const {
3175 return Assumed.getSet().contains(Elem) || Known.getSet().contains(Elem);
3176 }
3177
3178 /// Performs the set intersection between this set and \p RHS. Returns true if
3179 /// changes were made.
3181 bool IsUniversal = Assumed.isUniversal();
3182 unsigned SizeBefore = Assumed.getSet().size();
3183
3184 // Get intersection and make sure that the known set is still a proper
3185 // subset of the assumed set. A := K u (A ^ R).
3186 Assumed.getIntersection(RHS);
3187 Assumed.getUnion(Known);
3188
3189 return SizeBefore != Assumed.getSet().size() ||
3190 IsUniversal != Assumed.isUniversal();
3191 }
3192
3193 /// Performs the set union between this set and \p RHS. Returns true if
3194 /// changes were made.
3195 bool getUnion(const SetContents &RHS) { return Assumed.getUnion(RHS); }
3196
3197private:
3198 /// The set of values known for this state.
3199 SetContents Known;
3200
3201 /// The set of assumed values for this state.
3202 SetContents Assumed;
3203
3204 bool IsAtFixedpoint;
3205};
3206
3207/// Helper to tie a abstract state implementation to an abstract attribute.
3208template <typename StateTy, typename BaseType, class... Ts>
3209struct StateWrapper : public BaseType, public StateTy {
3210 /// Provide static access to the type of the state.
3212
3213 StateWrapper(const IRPosition &IRP, Ts... Args)
3214 : BaseType(IRP), StateTy(Args...) {}
3215
3216 /// See AbstractAttribute::getState(...).
3217 StateType &getState() override { return *this; }
3218
3219 /// See AbstractAttribute::getState(...).
3220 const StateType &getState() const override { return *this; }
3221};
3222
3223/// Helper class that provides common functionality to manifest IR attributes.
3224template <Attribute::AttrKind AK, typename BaseType, typename AAType>
3225struct IRAttribute : public BaseType {
3226 IRAttribute(const IRPosition &IRP) : BaseType(IRP) {}
3227
3228 /// Most boolean IRAttribute AAs don't do anything non-trivial
3229 /// in their initializers while non-boolean ones often do. Subclasses can
3230 /// change this.
3232
3233 /// Compile time access to the IR attribute kind.
3235
3236 /// Return true if the IR attribute(s) associated with this AA are implied for
3237 /// an undef value.
3238 static bool isImpliedByUndef() { return true; }
3239
3240 /// Return true if the IR attribute(s) associated with this AA are implied for
3241 /// an poison value.
3242 static bool isImpliedByPoison() { return true; }
3243
3244 static bool isImpliedByIR(Attributor &A, const IRPosition &IRP,
3245 Attribute::AttrKind ImpliedAttributeKind = AK,
3246 bool IgnoreSubsumingPositions = false) {
3247 if (AAType::isImpliedByUndef() && isa<UndefValue>(IRP.getAssociatedValue()))
3248 return true;
3249 if (AAType::isImpliedByPoison() &&
3251 return true;
3252 return A.hasAttr(IRP, {ImpliedAttributeKind}, IgnoreSubsumingPositions,
3253 ImpliedAttributeKind);
3254 }
3255
3256 /// See AbstractAttribute::manifest(...).
3258 if (isa<UndefValue>(this->getIRPosition().getAssociatedValue()))
3260 SmallVector<Attribute, 4> DeducedAttrs;
3261 getDeducedAttributes(A, this->getAnchorValue().getContext(), DeducedAttrs);
3262 if (DeducedAttrs.empty())
3264 return A.manifestAttrs(this->getIRPosition(), DeducedAttrs);
3265 }
3266
3267 /// Return the kind that identifies the abstract attribute implementation.
3268 Attribute::AttrKind getAttrKind() const { return AK; }
3269
3270 /// Return the deduced attributes in \p Attrs.
3272 SmallVectorImpl<Attribute> &Attrs) const {
3273 Attrs.emplace_back(Attribute::get(Ctx, getAttrKind()));
3274 }
3275};
3276
3277/// Base struct for all "concrete attribute" deductions.
3278///
3279/// The abstract attribute is a minimal interface that allows the Attributor to
3280/// orchestrate the abstract/fixpoint analysis. The design allows to hide away
3281/// implementation choices made for the subclasses but also to structure their
3282/// implementation and simplify the use of other abstract attributes in-flight.
3283///
3284/// To allow easy creation of new attributes, most methods have default
3285/// implementations. The ones that do not are generally straight forward, except
3286/// `AbstractAttribute::updateImpl` which is the location of most reasoning
3287/// associated with the abstract attribute. The update is invoked by the
3288/// Attributor in case the situation used to justify the current optimistic
3289/// state might have changed. The Attributor determines this automatically
3290/// by monitoring the `Attributor::getAAFor` calls made by abstract attributes.
3291///
3292/// The `updateImpl` method should inspect the IR and other abstract attributes
3293/// in-flight to justify the best possible (=optimistic) state. The actual
3294/// implementation is, similar to the underlying abstract state encoding, not
3295/// exposed. In the most common case, the `updateImpl` will go through a list of
3296/// reasons why its optimistic state is valid given the current information. If
3297/// any combination of them holds and is sufficient to justify the current
3298/// optimistic state, the method shall return UNCHAGED. If not, the optimistic
3299/// state is adjusted to the situation and the method shall return CHANGED.
3300///
3301/// If the manifestation of the "concrete attribute" deduced by the subclass
3302/// differs from the "default" behavior, which is a (set of) LLVM-IR
3303/// attribute(s) for an argument, call site argument, function return value, or
3304/// function, the `AbstractAttribute::manifest` method should be overloaded.
3305///
3306/// NOTE: If the state obtained via getState() is INVALID, thus if
3307/// AbstractAttribute::getState().isValidState() returns false, no
3308/// information provided by the methods of this class should be used.
3309/// NOTE: The Attributor currently has certain limitations to what we can do.
3310/// As a general rule of thumb, "concrete" abstract attributes should *for
3311/// now* only perform "backward" information propagation. That means
3312/// optimistic information obtained through abstract attributes should
3313/// only be used at positions that precede the origin of the information
3314/// with regards to the program flow. More practically, information can
3315/// *now* be propagated from instructions to their enclosing function, but
3316/// *not* from call sites to the called function. The mechanisms to allow
3317/// both directions will be added in the future.
3318/// NOTE: The mechanics of adding a new "concrete" abstract attribute are
3319/// described in the file comment.
3322
3324
3325 /// Virtual destructor.
3326 ~AbstractAttribute() override = default;
3327
3328 /// Compile time access to the IR attribute kind.
3330
3331 /// This function is used to identify if an \p DGN is of type
3332 /// AbstractAttribute so that the dyn_cast and cast can use such information
3333 /// to cast an AADepGraphNode to an AbstractAttribute.
3334 ///
3335 /// We eagerly return true here because all AADepGraphNodes except for the
3336 /// Synthethis Node are of type AbstractAttribute
3337 static bool classof(const AADepGraphNode *DGN) { return true; }
3338
3339 /// Return false if this AA does anything non-trivial (hence not done by
3340 /// default) in its initializer.
3341 static bool hasTrivialInitializer() { return false; }
3342
3343 /// Return true if this AA requires a "callee" (or an associted function) for
3344 /// a call site positon. Default is optimistic to minimize AAs.
3345 static bool requiresCalleeForCallBase() { return false; }
3346
3347 /// Return true if this AA requires non-asm "callee" for a call site positon.
3348 static bool requiresNonAsmForCallBase() { return true; }
3349
3350 /// Return true if this AA requires all callees for an argument or function
3351 /// positon.
3352 static bool requiresCallersForArgOrFunction() { return false; }
3353
3354 /// Return false if an AA should not be created for \p IRP.
3356 return true;
3357 }
3358
3359 /// Return false if an AA should not be updated for \p IRP.
3361 Function *AssociatedFn = IRP.getAssociatedFunction();
3362 bool IsFnInterface = IRP.isFnInterfaceKind();
3363 assert((!IsFnInterface || AssociatedFn) &&
3364 "Function interface without a function?");
3365
3366 // TODO: Not all attributes require an exact definition. Find a way to
3367 // enable deduction for some but not all attributes in case the
3368 // definition might be changed at runtime, see also
3369 // http://lists.llvm.org/pipermail/llvm-dev/2018-February/121275.html.
3370 // TODO: We could always determine abstract attributes and if sufficient
3371 // information was found we could duplicate the functions that do not
3372 // have an exact definition.
3373 return !IsFnInterface || A.isFunctionIPOAmendable(*AssociatedFn);
3374 }
3375
3376 /// Initialize the state with the information in the Attributor \p A.
3377 ///
3378 /// This function is called by the Attributor once all abstract attributes
3379 /// have been identified. It can and shall be used for task like:
3380 /// - identify existing knowledge in the IR and use it for the "known state"
3381 /// - perform any work that is not going to change over time, e.g., determine
3382 /// a subset of the IR, or attributes in-flight, that have to be looked at
3383 /// in the `updateImpl` method.
3384 virtual void initialize(Attributor &A) {}
3385
3386 /// A query AA is always scheduled as long as we do updates because it does
3387 /// lazy computation that cannot be determined to be done from the outside.
3388 /// However, while query AAs will not be fixed if they do not have outstanding
3389 /// dependences, we will only schedule them like other AAs. If a query AA that
3390 /// received a new query it needs to request an update via
3391 /// `Attributor::requestUpdateForAA`.
3392 virtual bool isQueryAA() const { return false; }
3393
3394 /// Return the internal abstract state for inspection.
3395 virtual StateType &getState() = 0;
3396 virtual const StateType &getState() const = 0;
3397
3398 /// Return an IR position, see struct IRPosition.
3399 const IRPosition &getIRPosition() const { return *this; };
3400 IRPosition &getIRPosition() { return *this; };
3401
3402 /// Helper functions, for debug purposes only.
3403 ///{
3404 void print(raw_ostream &OS) const { print(nullptr, OS); }
3405 void print(Attributor *, raw_ostream &OS) const override;
3406 virtual void printWithDeps(raw_ostream &OS) const;
3407 void dump() const { this->print(dbgs()); }
3408
3409 /// This function should return the "summarized" assumed state as string.
3410 virtual const std::string getAsStr(Attributor *A) const = 0;
3411
3412 /// This function should return the name of the AbstractAttribute
3413 virtual StringRef getName() const = 0;
3414
3415 /// This function should return the address of the ID of the AbstractAttribute
3416 virtual const char *getIdAddr() const = 0;
3417 ///}
3418
3419 /// Allow the Attributor access to the protected methods.
3420 friend struct Attributor;
3421
3422protected:
3423 /// Hook for the Attributor to trigger an update of the internal state.
3424 ///
3425 /// If this attribute is already fixed, this method will return UNCHANGED,
3426 /// otherwise it delegates to `AbstractAttribute::updateImpl`.
3427 ///
3428 /// \Return CHANGED if the internal state changed, otherwise UNCHANGED.
3430
3431 /// Hook for the Attributor to trigger the manifestation of the information
3432 /// represented by the abstract attribute in the LLVM-IR.
3433 ///
3434 /// \Return CHANGED if the IR was altered, otherwise UNCHANGED.
3438
3439 /// Hook to enable custom statistic tracking, called after manifest that
3440 /// resulted in a change if statistics are enabled.
3441 ///
3442 /// We require subclasses to provide an implementation so we remember to
3443 /// add statistics for them.
3444 virtual void trackStatistics() const = 0;
3445
3446 /// The actual update/transfer function which has to be implemented by the
3447 /// derived classes.
3448 ///
3449 /// If it is called, the environment has changed and we have to determine if
3450 /// the current information is still valid or adjust it otherwise.
3451 ///
3452 /// \Return CHANGED if the internal state changed, otherwise UNCHANGED.
3454};
3455
3456/// Forward declarations of output streams for debug purposes.
3457///
3458///{
3464template <typename base_ty, base_ty BestState, base_ty WorstState>
3468 return OS << "(" << S.getKnown() << "-" << S.getAssumed() << ")"
3469 << static_cast<const AbstractState &>(S);
3470}
3471LLVM_ABI raw_ostream &operator<<(raw_ostream &OS,
3472 const IntegerRangeState &State);
3473///}
3474
3483
3484/// A more lightweight version of the Attributor which only runs attribute
3485/// inference but no simplifications.
3486struct AttributorLightPass : public OptionalPassInfoMixin<AttributorLightPass> {
3488};
3489
3490/// A more lightweight version of the Attributor which only runs attribute
3491/// inference but no simplifications.
3493 : public OptionalPassInfoMixin<AttributorLightCGSCCPass> {
3496 CGSCCUpdateResult &UR);
3497};
3498
3499/// Helper function to clamp a state \p S of type \p StateType with the
3500/// information in \p R and indicate/return if \p S did change (as-in update is
3501/// required to be run again).
3502template <typename StateType>
3503ChangeStatus clampStateAndIndicateChange(StateType &S, const StateType &R) {
3504 auto Assumed = S.getAssumed();
3505 S ^= R;
3506 return Assumed == S.getAssumed() ? ChangeStatus::UNCHANGED
3508}
3509
3510/// ----------------------------------------------------------------------------
3511/// Abstract Attribute Classes
3512/// ----------------------------------------------------------------------------
3513
3515 : public IRAttribute<Attribute::NoUnwind,
3516 StateWrapper<BooleanState, AbstractAttribute>,
3517 AANoUnwind> {
3519
3520 /// Returns true if nounwind is assumed.
3521 bool isAssumedNoUnwind() const { return getAssumed(); }
3522
3523 /// Returns true if nounwind is known.
3524 bool isKnownNoUnwind() const { return getKnown(); }
3525
3526 /// Create an abstract attribute view for the position \p IRP.
3528 Attributor &A);
3529
3530 /// See AbstractAttribute::getName()
3531 StringRef getName() const override { return "AANoUnwind"; }
3532
3533 /// See AbstractAttribute::getIdAddr()
3534 const char *getIdAddr() const override { return &ID; }
3535
3536 /// This function should return true if the type of the \p AA is AANoUnwind
3537 static bool classof(const AbstractAttribute *AA) {
3538 return (AA->getIdAddr() == &ID);
3539 }
3540
3541 /// Unique ID (due to the unique address)
3542 LLVM_ABI static const char ID;
3543};
3544
3546 : public IRAttribute<Attribute::NoSync,
3547 StateWrapper<BooleanState, AbstractAttribute>,
3548 AANoSync> {
3550
3551 static bool isImpliedByIR(Attributor &A, const IRPosition &IRP,
3552 Attribute::AttrKind ImpliedAttributeKind,
3553 bool IgnoreSubsumingPositions = false) {
3554 // Note: This is also run for non-IPO amendable functions.
3555 assert(ImpliedAttributeKind == Attribute::NoSync);
3556 if (A.hasAttr(IRP, {Attribute::NoSync}, IgnoreSubsumingPositions,
3557 Attribute::NoSync))
3558 return true;
3559
3560 // Check for readonly + non-convergent.
3561 // TODO: We should be able to use hasAttr for Attributes, not only
3562 // AttrKinds.
3564 if (!F || F->isConvergent())
3565 return false;
3566
3568 A.getAttrs(IRP, {Attribute::Memory}, Attrs, IgnoreSubsumingPositions);
3569
3571 for (const Attribute &Attr : Attrs)
3572 ME &= Attr.getMemoryEffects();
3573
3574 if (!ME.onlyReadsMemory())
3575 return false;
3576
3577 A.manifestAttrs(IRP, Attribute::get(F->getContext(), Attribute::NoSync));
3578 return true;
3579 }
3580
3581 /// See AbstractAttribute::isValidIRPositionForInit
3583 if (!IRP.isFunctionScope() &&
3585 return false;
3586 return IRAttribute::isValidIRPositionForInit(A, IRP);
3587 }
3588
3589 /// Returns true if "nosync" is assumed.
3590 bool isAssumedNoSync() const { return getAssumed(); }
3591
3592 /// Returns true if "nosync" is known.
3593 bool isKnownNoSync() const { return getKnown(); }
3594
3595 /// Helper function used to determine whether an instruction is non-relaxed
3596 /// atomic. In other words, if an atomic instruction does not have unordered
3597 /// or monotonic ordering
3598 LLVM_ABI static bool isNonRelaxedAtomic(const Instruction *I);
3599
3600 /// Helper function to determine if \p CB is an aligned (GPU) barrier. Aligned
3601 /// barriers have to be executed by all threads. The flag \p ExecutedAligned
3602 /// indicates if the call is executed by all threads in a (thread) block in an
3603 /// aligned way. If that is the case, non-aligned barriers are effectively
3604 /// aligned barriers.
3605 LLVM_ABI static bool isAlignedBarrier(const CallBase &CB,
3606 bool ExecutedAligned);
3607
3608 /// Create an abstract attribute view for the position \p IRP.
3610 Attributor &A);
3611
3612 /// See AbstractAttribute::getName()
3613 StringRef getName() const override { return "AANoSync"; }
3614
3615 /// See AbstractAttribute::getIdAddr()
3616 const char *getIdAddr() const override { return &ID; }
3617
3618 /// This function should return true if the type of the \p AA is AANoSync
3619 static bool classof(const AbstractAttribute *AA) {
3620 return (AA->getIdAddr() == &ID);
3621 }
3622
3623 /// Unique ID (due to the unique address)
3624 LLVM_ABI static const char ID;
3625};
3626
3627/// An abstract interface for all nonnull attributes.
3629 : public IRAttribute<Attribute::MustProgress,
3630 StateWrapper<BooleanState, AbstractAttribute>,
3631 AAMustProgress> {
3633
3634 static bool isImpliedByIR(Attributor &A, const IRPosition &IRP,
3635 Attribute::AttrKind ImpliedAttributeKind,
3636 bool IgnoreSubsumingPositions = false) {
3637 // Note: This is also run for non-IPO amendable functions.
3638 assert(ImpliedAttributeKind == Attribute::MustProgress);
3639 return A.hasAttr(IRP, {Attribute::MustProgress, Attribute::WillReturn},
3640 IgnoreSubsumingPositions, Attribute::MustProgress);
3641 }
3642
3643 /// Return true if we assume that the underlying value is nonnull.
3644 bool isAssumedMustProgress() const { return getAssumed(); }
3645
3646 /// Return true if we know that underlying value is nonnull.
3647 bool isKnownMustProgress() const { return getKnown(); }
3648
3649 /// Create an abstract attribute view for the position \p IRP.
3651 Attributor &A);
3652
3653 /// See AbstractAttribute::getName()
3654 StringRef getName() const override { return "AAMustProgress"; }
3655
3656 /// See AbstractAttribute::getIdAddr()
3657 const char *getIdAddr() const override { return &ID; }
3658
3659 /// This function should return true if the type of the \p AA is
3660 /// AAMustProgress
3661 static bool classof(const AbstractAttribute *AA) {
3662 return (AA->getIdAddr() == &ID);
3663 }
3664
3665 /// Unique ID (due to the unique address)
3666 LLVM_ABI static const char ID;
3667};
3668
3669/// An abstract interface for all nonnull attributes.
3671 : public IRAttribute<Attribute::NonNull,
3672 StateWrapper<BooleanState, AbstractAttribute>,
3673 AANonNull> {
3675
3676 /// See AbstractAttribute::hasTrivialInitializer.
3677 static bool hasTrivialInitializer() { return false; }
3678
3679 /// See IRAttribute::isImpliedByUndef.
3680 /// Undef is not necessarily nonnull as nonnull + noundef would cause poison.
3681 /// Poison implies nonnull though.
3682 static bool isImpliedByUndef() { return false; }
3683
3684 /// See AbstractAttribute::isValidIRPositionForInit
3687 return false;
3688 return IRAttribute::isValidIRPositionForInit(A, IRP);
3689 }
3690
3691 /// See AbstractAttribute::isImpliedByIR(...).
3692 LLVM_ABI static bool isImpliedByIR(Attributor &A, const IRPosition &IRP,
3693 Attribute::AttrKind ImpliedAttributeKind,
3694 bool IgnoreSubsumingPositions = false);
3695
3696 /// Return true if we assume that the underlying value is nonnull.
3697 bool isAssumedNonNull() const { return getAssumed(); }
3698
3699 /// Return true if we know that underlying value is nonnull.
3700 bool isKnownNonNull() const { return getKnown(); }
3701
3702 /// Create an abstract attribute view for the position \p IRP.
3704 Attributor &A);
3705
3706 /// See AbstractAttribute::getName()
3707 StringRef getName() const override { return "AANonNull"; }
3708
3709 /// See AbstractAttribute::getIdAddr()
3710 const char *getIdAddr() const override { return &ID; }
3711
3712 /// This function should return true if the type of the \p AA is AANonNull
3713 static bool classof(const AbstractAttribute *AA) {
3714 return (AA->getIdAddr() == &ID);
3715 }
3716
3717 /// Unique ID (due to the unique address)
3718 LLVM_ABI static const char ID;
3719};
3720
3721/// An abstract attribute for norecurse.
3723 : public IRAttribute<Attribute::NoRecurse,
3724 StateWrapper<BooleanState, AbstractAttribute>,
3725 AANoRecurse> {
3727
3728 /// Return true if "norecurse" is assumed.
3729 bool isAssumedNoRecurse() const { return getAssumed(); }
3730
3731 /// Return true if "norecurse" is known.
3732 bool isKnownNoRecurse() const { return getKnown(); }
3733
3734 /// Create an abstract attribute view for the position \p IRP.
3736 Attributor &A);
3737
3738 /// See AbstractAttribute::getName()
3739 StringRef getName() const override { return "AANoRecurse"; }
3740
3741 /// See AbstractAttribute::getIdAddr()
3742 const char *getIdAddr() const override { return &ID; }
3743
3744 /// This function should return true if the type of the \p AA is AANoRecurse
3745 static bool classof(const AbstractAttribute *AA) {
3746 return (AA->getIdAddr() == &ID);
3747 }
3748
3749 /// Unique ID (due to the unique address)
3750 LLVM_ABI static const char ID;
3751};
3752
3753/// An abstract attribute for willreturn.
3755 : public IRAttribute<Attribute::WillReturn,
3756 StateWrapper<BooleanState, AbstractAttribute>,
3757 AAWillReturn> {
3759
3760 static bool isImpliedByIR(Attributor &A, const IRPosition &IRP,
3761 Attribute::AttrKind ImpliedAttributeKind,
3762 bool IgnoreSubsumingPositions = false) {
3763 // Note: This is also run for non-IPO amendable functions.
3764 assert(ImpliedAttributeKind == Attribute::WillReturn);
3765 if (IRAttribute::isImpliedByIR(A, IRP, ImpliedAttributeKind,
3766 IgnoreSubsumingPositions))
3767 return true;
3769 return false;
3770 A.manifestAttrs(IRP, Attribute::get(IRP.getAnchorValue().getContext(),
3771 Attribute::WillReturn));
3772 return true;
3773 }
3774
3775 /// Check for `mustprogress` and `readonly` as they imply `willreturn`.
3777 const IRPosition &IRP) {
3778 // Check for `mustprogress` in the scope and the associated function which
3779 // might be different if this is a call site.
3780 if (!A.hasAttr(IRP, {Attribute::MustProgress}))
3781 return false;
3782
3784 A.getAttrs(IRP, {Attribute::Memory}, Attrs,
3785 /* IgnoreSubsumingPositions */ false);
3786
3788 for (const Attribute &Attr : Attrs)
3789 ME &= Attr.getMemoryEffects();
3790 return ME.onlyReadsMemory();
3791 }
3792
3793 /// Return true if "willreturn" is assumed.
3794 bool isAssumedWillReturn() const { return getAssumed(); }
3795
3796 /// Return true if "willreturn" is known.
3797 bool isKnownWillReturn() const { return getKnown(); }
3798
3799 /// Create an abstract attribute view for the position \p IRP.
3801 Attributor &A);
3802
3803 /// See AbstractAttribute::getName()
3804 StringRef getName() const override { return "AAWillReturn"; }
3805
3806 /// See AbstractAttribute::getIdAddr()
3807 const char *getIdAddr() const override { return &ID; }
3808
3809 /// This function should return true if the type of the \p AA is AAWillReturn
3810 static bool classof(const AbstractAttribute *AA) {
3811 return (AA->getIdAddr() == &ID);
3812 }
3813
3814 /// Unique ID (due to the unique address)
3815 LLVM_ABI static const char ID;
3816};
3817
3818/// An abstract attribute for undefined behavior.
3820 : public StateWrapper<BooleanState, AbstractAttribute> {
3823
3824 /// Return true if "undefined behavior" is assumed.
3825 bool isAssumedToCauseUB() const { return getAssumed(); }
3826
3827 /// Return true if "undefined behavior" is assumed for a specific instruction.
3828 virtual bool isAssumedToCauseUB(Instruction *I) const = 0;
3829
3830 /// Return true if "undefined behavior" is known.
3831 bool isKnownToCauseUB() const { return getKnown(); }
3832
3833 /// Return true if "undefined behavior" is known for a specific instruction.
3834 virtual bool isKnownToCauseUB(Instruction *I) const = 0;
3835
3836 /// Create an abstract attribute view for the position \p IRP.
3838 Attributor &A);
3839
3840 /// See AbstractAttribute::getName()
3841 StringRef getName() const override { return "AAUndefinedBehavior"; }
3842
3843 /// See AbstractAttribute::getIdAddr()
3844 const char *getIdAddr() const override { return &ID; }
3845
3846 /// This function should return true if the type of the \p AA is
3847 /// AAUndefineBehavior
3848 static bool classof(const AbstractAttribute *AA) {
3849 return (AA->getIdAddr() == &ID);
3850 }
3851
3852 /// Unique ID (due to the unique address)
3853 LLVM_ABI static const char ID;
3854};
3855
3856/// An abstract interface to determine reachability of point A to B.
3858 : public StateWrapper<BooleanState, AbstractAttribute> {
3861
3862 /// Returns true if 'From' instruction is assumed to reach, 'To' instruction.
3863 /// Users should provide two positions they are interested in, and the class
3864 /// determines (and caches) reachability.
3866 Attributor &A, const Instruction &From, const Instruction &To,
3867 const AA::InstExclusionSetTy *ExclusionSet = nullptr) const = 0;
3868
3869 /// Create an abstract attribute view for the position \p IRP.
3872
3873 /// See AbstractAttribute::getName()
3874 StringRef getName() const override { return "AAIntraFnReachability"; }
3875
3876 /// See AbstractAttribute::getIdAddr()
3877 const char *getIdAddr() const override { return &ID; }
3878
3879 /// This function should return true if the type of the \p AA is
3880 /// AAIntraFnReachability
3881 static bool classof(const AbstractAttribute *AA) {
3882 return (AA->getIdAddr() == &ID);
3883 }
3884
3885 /// Unique ID (due to the unique address)
3886 LLVM_ABI static const char ID;
3887};
3888
3889/// An abstract interface for all noalias attributes.
3891 : public IRAttribute<Attribute::NoAlias,
3892 StateWrapper<BooleanState, AbstractAttribute>,
3893 AANoAlias> {
3895
3896 /// See AbstractAttribute::isValidIRPositionForInit
3898 if (!IRP.getAssociatedType()->isPointerTy())
3899 return false;
3900 return IRAttribute::isValidIRPositionForInit(A, IRP);
3901 }
3902
3903 /// See IRAttribute::isImpliedByIR
3904 LLVM_ABI static bool isImpliedByIR(Attributor &A, const IRPosition &IRP,
3905 Attribute::AttrKind ImpliedAttributeKind,
3906 bool IgnoreSubsumingPositions = false);
3907
3908 /// See AbstractAttribute::requiresCallersForArgOrFunction
3909 static bool requiresCallersForArgOrFunction() { return true; }
3910
3911 /// Return true if we assume that the underlying value is alias.
3912 bool isAssumedNoAlias() const { return getAssumed(); }
3913
3914 /// Return true if we know that underlying value is noalias.
3915 bool isKnownNoAlias() const { return getKnown(); }
3916
3917 /// Create an abstract attribute view for the position \p IRP.
3919 Attributor &A);
3920
3921 /// See AbstractAttribute::getName()
3922 StringRef getName() const override { return "AANoAlias"; }
3923
3924 /// See AbstractAttribute::getIdAddr()
3925 const char *getIdAddr() const override { return &ID; }
3926
3927 /// This function should return true if the type of the \p AA is AANoAlias
3928 static bool classof(const AbstractAttribute *AA) {
3929 return (AA->getIdAddr() == &ID);
3930 }
3931
3932 /// Unique ID (due to the unique address)
3933 LLVM_ABI static const char ID;
3934};
3935
3936/// An AbstractAttribute for nofree.
3938 : public IRAttribute<Attribute::NoFree,
3939 StateWrapper<BooleanState, AbstractAttribute>,
3940 AANoFree> {
3942
3943 /// See IRAttribute::isImpliedByIR
3944 static bool isImpliedByIR(Attributor &A, const IRPosition &IRP,
3945 Attribute::AttrKind ImpliedAttributeKind,
3946 bool IgnoreSubsumingPositions = false) {
3947 // Note: This is also run for non-IPO amendable functions.
3948 assert(ImpliedAttributeKind == Attribute::NoFree);
3949 return A.hasAttr(
3950 IRP, {Attribute::ReadNone, Attribute::ReadOnly, Attribute::NoFree},
3951 IgnoreSubsumingPositions, Attribute::NoFree);
3952 }
3953
3954 /// See AbstractAttribute::isValidIRPositionForInit
3956 if (!IRP.isFunctionScope() &&
3958 return false;
3959 return IRAttribute::isValidIRPositionForInit(A, IRP);
3960 }
3961
3962 /// Return true if "nofree" is assumed.
3963 bool isAssumedNoFree() const { return getAssumed(); }
3964
3965 /// Return true if "nofree" is known.
3966 bool isKnownNoFree() const { return getKnown(); }
3967
3968 /// Create an abstract attribute view for the position \p IRP.
3970 Attributor &A);
3971
3972 /// See AbstractAttribute::getName()
3973 StringRef getName() const override { return "AANoFree"; }
3974
3975 /// See AbstractAttribute::getIdAddr()
3976 const char *getIdAddr() const override { return &ID; }
3977
3978 /// This function should return true if the type of the \p AA is AANoFree
3979 static bool classof(const AbstractAttribute *AA) {
3980 return (AA->getIdAddr() == &ID);
3981 }
3982
3983 /// Unique ID (due to the unique address)
3984 LLVM_ABI static const char ID;
3985};
3986
3987/// An AbstractAttribute for noreturn.
3989 : public IRAttribute<Attribute::NoReturn,
3990 StateWrapper<BooleanState, AbstractAttribute>,
3991 AANoReturn> {
3993
3994 /// Return true if the underlying object is assumed to never return.
3995 bool isAssumedNoReturn() const { return getAssumed(); }
3996
3997 /// Return true if the underlying object is known to never return.
3998 bool isKnownNoReturn() const { return getKnown(); }
3999
4000 /// Create an abstract attribute view for the position \p IRP.
4002 Attributor &A);
4003
4004 /// See AbstractAttribute::getName()
4005 StringRef getName() const override { return "AANoReturn"; }
4006
4007 /// See AbstractAttribute::getIdAddr()
4008 const char *getIdAddr() const override { return &ID; }
4009
4010 /// This function should return true if the type of the \p AA is AANoReturn
4011 static bool classof(const AbstractAttribute *AA) {
4012 return (AA->getIdAddr() == &ID);
4013 }
4014
4015 /// Unique ID (due to the unique address)
4016 LLVM_ABI static const char ID;
4017};
4018
4019/// An abstract interface for liveness abstract attribute.
4021 : public StateWrapper<BitIntegerState<uint8_t, 3, 0>, AbstractAttribute> {
4023 AAIsDead(const IRPosition &IRP, Attributor &A) : Base(IRP) {}
4024
4025 /// See AbstractAttribute::isValidIRPositionForInit
4028 return isa<Function>(IRP.getAnchorValue()) &&
4029 !cast<Function>(IRP.getAnchorValue()).isDeclaration();
4030 return true;
4031 }
4032
4033 /// State encoding bits. A set bit in the state means the property holds.
4034 enum {
4037
4039 };
4040 static_assert(IS_DEAD == getBestState(), "Unexpected BEST_STATE value");
4041
4042protected:
4043 /// The query functions are protected such that other attributes need to go
4044 /// through the Attributor interfaces: `Attributor::isAssumedDead(...)`
4045
4046 /// Returns true if the underlying value is assumed dead.
4047 virtual bool isAssumedDead() const = 0;
4048
4049 /// Returns true if the underlying value is known dead.
4050 virtual bool isKnownDead() const = 0;
4051
4052 /// Returns true if \p BB is known dead.
4053 virtual bool isKnownDead(const BasicBlock *BB) const = 0;
4054
4055 /// Returns true if \p I is assumed dead.
4056 virtual bool isAssumedDead(const Instruction *I) const = 0;
4057
4058 /// Returns true if \p I is known dead.
4059 virtual bool isKnownDead(const Instruction *I) const = 0;
4060
4061 /// Return true if the underlying value is a store that is known to be
4062 /// removable. This is different from dead stores as the removable store
4063 /// can have an effect on live values, especially loads, but that effect
4064 /// is propagated which allows us to remove the store in turn.
4065 virtual bool isRemovableStore() const { return false; }
4066
4067 /// This method is used to check if at least one instruction in a collection
4068 /// of instructions is live.
4069 template <typename T> bool isLiveInstSet(T begin, T end) const {
4070 for (const auto &I : llvm::make_range(begin, end)) {
4071 assert(I->getFunction() == getIRPosition().getAssociatedFunction() &&
4072 "Instruction must be in the same anchor scope function.");
4073
4074 if (!isAssumedDead(I))
4075 return true;
4076 }
4077
4078 return false;
4079 }
4080
4081public:
4082 /// Create an abstract attribute view for the position \p IRP.
4084 Attributor &A);
4085
4086 /// Determine if \p F might catch asynchronous exceptions.
4088 return F.hasPersonalityFn() && !canSimplifyInvokeNoUnwind(&F);
4089 }
4090
4091 /// Returns true if \p BB is assumed dead.
4092 virtual bool isAssumedDead(const BasicBlock *BB) const = 0;
4093
4094 /// Return if the edge from \p From BB to \p To BB is assumed dead.
4095 /// This is specifically useful in AAReachability.
4096 virtual bool isEdgeDead(const BasicBlock *From, const BasicBlock *To) const {
4097 return false;
4098 }
4099
4100 /// See AbstractAttribute::getName()
4101 StringRef getName() const override { return "AAIsDead"; }
4102
4103 /// See AbstractAttribute::getIdAddr()
4104 const char *getIdAddr() const override { return &ID; }
4105
4106 /// This function should return true if the type of the \p AA is AAIsDead
4107 static bool classof(const AbstractAttribute *AA) {
4108 return (AA->getIdAddr() == &ID);
4109 }
4110
4111 /// Unique ID (due to the unique address)
4112 LLVM_ABI static const char ID;
4113
4114 friend struct Attributor;
4115};
4116
4117/// State for dereferenceable attribute
4119
4120 static DerefState getBestState() { return DerefState(); }
4121 static DerefState getBestState(const DerefState &) { return getBestState(); }
4122
4123 /// Return the worst possible representable state.
4125 DerefState DS;
4127 return DS;
4128 }
4130 return getWorstState();
4131 }
4132
4133 /// State representing for dereferenceable bytes.
4135
4136 /// Map representing for accessed memory offsets and sizes.
4137 /// A key is Offset and a value is size.
4138 /// If there is a load/store instruction something like,
4139 /// p[offset] = v;
4140 /// (offset, sizeof(v)) will be inserted to this map.
4141 /// std::map is used because we want to iterate keys in ascending order.
4142 std::map<int64_t, uint64_t> AccessedBytesMap;
4143
4144 /// Helper function to calculate dereferenceable bytes from current known
4145 /// bytes and accessed bytes.
4146 ///
4147 /// int f(int *A){
4148 /// *A = 0;
4149 /// *(A+2) = 2;
4150 /// *(A+1) = 1;
4151 /// *(A+10) = 10;
4152 /// }
4153 /// ```
4154 /// In that case, AccessedBytesMap is `{0:4, 4:4, 8:4, 40:4}`.
4155 /// AccessedBytesMap is std::map so it is iterated in accending order on
4156 /// key(Offset). So KnownBytes will be updated like this:
4157 ///
4158 /// |Access | KnownBytes
4159 /// |(0, 4)| 0 -> 4
4160 /// |(4, 4)| 4 -> 8
4161 /// |(8, 4)| 8 -> 12
4162 /// |(40, 4) | 12 (break)
4163 void computeKnownDerefBytesFromAccessedMap() {
4164 int64_t KnownBytes = DerefBytesState.getKnown();
4165 for (auto &Access : AccessedBytesMap) {
4166 if (KnownBytes < Access.first)
4167 break;
4168 KnownBytes = std::max(KnownBytes, Access.first + (int64_t)Access.second);
4169 }
4170
4171 DerefBytesState.takeKnownMaximum(KnownBytes);
4172 }
4173
4174 /// State representing that whether the value is globaly dereferenceable.
4175 BooleanState GlobalState;
4176
4177 /// See AbstractState::isValidState()
4178 bool isValidState() const override { return DerefBytesState.isValidState(); }
4179
4180 /// See AbstractState::isAtFixpoint()
4181 bool isAtFixpoint() const override {
4182 return !isValidState() ||
4183 (DerefBytesState.isAtFixpoint() && GlobalState.isAtFixpoint());
4184 }
4185
4186 /// See AbstractState::indicateOptimisticFixpoint(...)
4188 DerefBytesState.indicateOptimisticFixpoint();
4189 GlobalState.indicateOptimisticFixpoint();
4191 }
4192
4193 /// See AbstractState::indicatePessimisticFixpoint(...)
4195 DerefBytesState.indicatePessimisticFixpoint();
4196 GlobalState.indicatePessimisticFixpoint();
4197 return ChangeStatus::CHANGED;
4198 }
4199
4200 /// Update known dereferenceable bytes.
4201 void takeKnownDerefBytesMaximum(uint64_t Bytes) {
4202 DerefBytesState.takeKnownMaximum(Bytes);
4203
4204 // Known bytes might increase.
4205 computeKnownDerefBytesFromAccessedMap();
4206 }
4207
4208 /// Update assumed dereferenceable bytes.
4209 void takeAssumedDerefBytesMinimum(uint64_t Bytes) {
4210 DerefBytesState.takeAssumedMinimum(Bytes);
4211 }
4212
4213 /// Add accessed bytes to the map.
4214 void addAccessedBytes(int64_t Offset, uint64_t Size) {
4215 uint64_t &AccessedBytes = AccessedBytesMap[Offset];
4216 AccessedBytes = std::max(AccessedBytes, Size);
4217
4218 // Known bytes might increase.
4219 computeKnownDerefBytesFromAccessedMap();
4220 }
4221
4222 /// Equality for DerefState.
4223 bool operator==(const DerefState &R) const {
4224 return this->DerefBytesState == R.DerefBytesState &&
4225 this->GlobalState == R.GlobalState;
4226 }
4227
4228 /// Inequality for DerefState.
4229 bool operator!=(const DerefState &R) const { return !(*this == R); }
4230
4231 /// See IntegerStateBase::operator^=
4232 DerefState operator^=(const DerefState &R) {
4233 DerefBytesState ^= R.DerefBytesState;
4234 GlobalState ^= R.GlobalState;
4235 return *this;
4236 }
4237
4238 /// See IntegerStateBase::operator+=
4239 DerefState operator+=(const DerefState &R) {
4240 DerefBytesState += R.DerefBytesState;
4241 GlobalState += R.GlobalState;
4242 return *this;
4243 }
4244
4245 /// See IntegerStateBase::operator&=
4246 DerefState operator&=(const DerefState &R) {
4247 DerefBytesState &= R.DerefBytesState;
4248 GlobalState &= R.GlobalState;
4249 return *this;
4250 }
4251
4252 /// See IntegerStateBase::operator|=
4253 DerefState operator|=(const DerefState &R) {
4254 DerefBytesState |= R.DerefBytesState;
4255 GlobalState |= R.GlobalState;
4256 return *this;
4257 }
4258};
4259
4260/// An abstract interface for all dereferenceable attribute.
4262 : public IRAttribute<Attribute::Dereferenceable,
4263 StateWrapper<DerefState, AbstractAttribute>,
4264 AADereferenceable> {
4266
4267 /// See AbstractAttribute::isValidIRPositionForInit
4269 if (!IRP.getAssociatedType()->isPointerTy())
4270 return false;
4271 return IRAttribute::isValidIRPositionForInit(A, IRP);
4272 }
4273
4274 /// Return true if we assume that underlying value is
4275 /// dereferenceable(_or_null) globally.
4276 bool isAssumedGlobal() const { return GlobalState.getAssumed(); }
4277
4278 /// Return true if we know that underlying value is
4279 /// dereferenceable(_or_null) globally.
4280 bool isKnownGlobal() const { return GlobalState.getKnown(); }
4281
4282 /// Return assumed dereferenceable bytes.
4284 return DerefBytesState.getAssumed();
4285 }
4286
4287 /// Return known dereferenceable bytes.
4289 return DerefBytesState.getKnown();
4290 }
4291
4292 /// Create an abstract attribute view for the position \p IRP.
4294 Attributor &A);
4295
4296 /// See AbstractAttribute::getName()
4297 StringRef getName() const override { return "AADereferenceable"; }
4298
4299 /// See AbstractAttribute::getIdAddr()
4300 const char *getIdAddr() const override { return &ID; }
4301
4302 /// This function should return true if the type of the \p AA is
4303 /// AADereferenceable
4304 static bool classof(const AbstractAttribute *AA) {
4305 return (AA->getIdAddr() == &ID);
4306 }
4307
4308 /// Unique ID (due to the unique address)
4309 LLVM_ABI static const char ID;
4310};
4311
4314/// An abstract interface for all align attributes.
4316 : public IRAttribute<Attribute::Alignment,
4317 StateWrapper<AAAlignmentStateType, AbstractAttribute>,
4318 AAAlign> {
4320
4321 /// See AbstractAttribute::isValidIRPositionForInit
4324 return false;
4325 return IRAttribute::isValidIRPositionForInit(A, IRP);
4326 }
4327
4328 /// Return assumed alignment.
4329 Align getAssumedAlign() const { return Align(getAssumed()); }
4330
4331 /// Return known alignment.
4332 Align getKnownAlign() const { return Align(getKnown()); }
4333
4334 /// See AbstractAttribute::getName()
4335 StringRef getName() const override { return "AAAlign"; }
4336
4337 /// See AbstractAttribute::getIdAddr()
4338 const char *getIdAddr() const override { return &ID; }
4339
4340 /// This function should return true if the type of the \p AA is AAAlign
4341 static bool classof(const AbstractAttribute *AA) {
4342 return (AA->getIdAddr() == &ID);
4343 }
4344
4345 /// Create an abstract attribute view for the position \p IRP.
4347 Attributor &A);
4348
4349 /// Unique ID (due to the unique address)
4350 LLVM_ABI static const char ID;
4351};
4352
4353/// An abstract interface to track if a value leaves it's defining function
4354/// instance.
4355/// TODO: We should make it a ternary AA tracking uniqueness, and uniqueness
4356/// wrt. the Attributor analysis separately.
4357struct AAInstanceInfo : public StateWrapper<BooleanState, AbstractAttribute> {
4360
4361 /// Return true if we know that the underlying value is unique in its scope
4362 /// wrt. the Attributor analysis. That means it might not be unique but we can
4363 /// still use pointer equality without risking to represent two instances with
4364 /// one `llvm::Value`.
4365 bool isKnownUniqueForAnalysis() const { return isKnown(); }
4366
4367 /// Return true if we assume that the underlying value is unique in its scope
4368 /// wrt. the Attributor analysis. That means it might not be unique but we can
4369 /// still use pointer equality without risking to represent two instances with
4370 /// one `llvm::Value`.
4371 bool isAssumedUniqueForAnalysis() const { return isAssumed(); }
4372
4373 /// Create an abstract attribute view for the position \p IRP.
4375 Attributor &A);
4376
4377 /// See AbstractAttribute::getName()
4378 StringRef getName() const override { return "AAInstanceInfo"; }
4379
4380 /// See AbstractAttribute::getIdAddr()
4381 const char *getIdAddr() const override { return &ID; }
4382
4383 /// This function should return true if the type of the \p AA is
4384 /// AAInstanceInfo
4385 static bool classof(const AbstractAttribute *AA) {
4386 return (AA->getIdAddr() == &ID);
4387 }
4388
4389 /// Unique ID (due to the unique address)
4390 LLVM_ABI static const char ID;
4391};
4392
4393/// An abstract interface for all nocapture attributes.
4395 : public IRAttribute<
4396 Attribute::Captures,
4397 StateWrapper<BitIntegerState<uint16_t, 7, 0>, AbstractAttribute>,
4398 AANoCapture> {
4400
4401 /// See IRAttribute::isImpliedByIR
4402 LLVM_ABI static bool isImpliedByIR(Attributor &A, const IRPosition &IRP,
4403 Attribute::AttrKind ImpliedAttributeKind,
4404 bool IgnoreSubsumingPositions = false);
4405
4406 /// Update \p State according to the capture capabilities of \p F for position
4407 /// \p IRP.
4408 LLVM_ABI static void
4410 BitIntegerState &State);
4411
4412 /// See AbstractAttribute::isValidIRPositionForInit
4414 if (!IRP.getAssociatedType()->isPointerTy())
4415 return false;
4416 return IRAttribute::isValidIRPositionForInit(A, IRP);
4417 }
4418
4419 /// State encoding bits. A set bit in the state means the property holds.
4420 /// NO_CAPTURE is the best possible state, 0 the worst possible state.
4421 enum {
4425
4426 /// If we do not capture the value in memory or through integers we can only
4427 /// communicate it back as a derived pointer.
4429
4430 /// If we do not capture the value in memory, through integers, or as a
4431 /// derived pointer we know it is not captured.
4434 };
4435
4436 /// Return true if we know that the underlying value is not captured in its
4437 /// respective scope.
4438 bool isKnownNoCapture() const { return isKnown(NO_CAPTURE); }
4439
4440 /// Return true if we assume that the underlying value is not captured in its
4441 /// respective scope.
4442 bool isAssumedNoCapture() const { return isAssumed(NO_CAPTURE); }
4443
4444 /// Return true if we know that the underlying value is not captured in its
4445 /// respective scope but we allow it to escape through a "return".
4449
4450 /// Return true if we assume that the underlying value is not captured in its
4451 /// respective scope but we allow it to escape through a "return".
4455
4456 /// Create an abstract attribute view for the position \p IRP.
4458 Attributor &A);
4459
4460 /// See AbstractAttribute::getName()
4461 StringRef getName() const override { return "AANoCapture"; }
4462
4463 /// See AbstractAttribute::getIdAddr()
4464 const char *getIdAddr() const override { return &ID; }
4465
4466 /// This function should return true if the type of the \p AA is AANoCapture
4467 static bool classof(const AbstractAttribute *AA) {
4468 return (AA->getIdAddr() == &ID);
4469 }
4470
4471 /// Unique ID (due to the unique address)
4472 LLVM_ABI static const char ID;
4473};
4474
4476
4478
4483 return getBestState(VS.Ty);
4484 }
4485
4486 /// Return the worst possible representable state.
4489 DS.indicatePessimisticFixpoint();
4490 return DS;
4491 }
4494 return getWorstState(VS.Ty);
4495 }
4496
4497 /// See AbstractState::isValidState(...)
4498 bool isValidState() const override { return BS.isValidState(); }
4499
4500 /// See AbstractState::isAtFixpoint(...)
4501 bool isAtFixpoint() const override { return BS.isAtFixpoint(); }
4502
4503 /// Return the assumed state encoding.
4505 const ValueSimplifyStateType &getAssumed() const { return *this; }
4506
4507 /// See AbstractState::indicatePessimisticFixpoint(...)
4509 return BS.indicatePessimisticFixpoint();
4510 }
4511
4512 /// See AbstractState::indicateOptimisticFixpoint(...)
4514 return BS.indicateOptimisticFixpoint();
4515 }
4516
4517 /// "Clamp" this state with \p PVS.
4519 BS ^= VS.BS;
4520 unionAssumed(VS.SimplifiedAssociatedValue);
4521 return *this;
4522 }
4523
4525 if (isValidState() != RHS.isValidState())
4526 return false;
4527 if (!isValidState() && !RHS.isValidState())
4528 return true;
4529 return SimplifiedAssociatedValue == RHS.SimplifiedAssociatedValue;
4530 }
4531
4532protected:
4533 /// The type of the original value.
4535
4536 /// Merge \p Other into the currently assumed simplified value
4537 LLVM_ABI bool unionAssumed(std::optional<Value *> Other);
4538
4539 /// Helper to track validity and fixpoint
4541
4542 /// An assumed simplified value. Initially, it is set to std::nullopt, which
4543 /// means that the value is not clear under current assumption. If in the
4544 /// pessimistic state, getAssumedSimplifiedValue doesn't return this value but
4545 /// returns orignal associated value.
4546 std::optional<Value *> SimplifiedAssociatedValue;
4547};
4548
4549/// An abstract interface for value simplify abstract attribute.
4551 : public StateWrapper<ValueSimplifyStateType, AbstractAttribute, Type *> {
4554 : Base(IRP, IRP.getAssociatedType()) {}
4555
4556 /// Create an abstract attribute view for the position \p IRP.
4558 Attributor &A);
4559
4560 /// See AbstractAttribute::getName()
4561 StringRef getName() const override { return "AAValueSimplify"; }
4562
4563 /// See AbstractAttribute::getIdAddr()
4564 const char *getIdAddr() const override { return &ID; }
4565
4566 /// This function should return true if the type of the \p AA is
4567 /// AAValueSimplify
4568 static bool classof(const AbstractAttribute *AA) {
4569 return (AA->getIdAddr() == &ID);
4570 }
4571
4572 /// Unique ID (due to the unique address)
4573 LLVM_ABI static const char ID;
4574
4575private:
4576 /// Return an assumed simplified value if a single candidate is found. If
4577 /// there cannot be one, return original value. If it is not clear yet, return
4578 /// std::nullopt.
4579 ///
4580 /// Use `Attributor::getAssumedSimplified` for value simplification.
4581 virtual std::optional<Value *>
4582 getAssumedSimplifiedValue(Attributor &A) const = 0;
4583
4584 friend struct Attributor;
4585};
4586
4587struct AAHeapToStack : public StateWrapper<BooleanState, AbstractAttribute> {
4589 AAHeapToStack(const IRPosition &IRP, Attributor &A) : Base(IRP) {}
4590
4591 /// Returns true if HeapToStack conversion is assumed to be possible.
4592 virtual bool isAssumedHeapToStack(const CallBase &CB) const = 0;
4593
4594 /// Returns true if HeapToStack conversion is assumed and the CB is a
4595 /// callsite to a free operation to be removed.
4596 virtual bool isAssumedHeapToStackRemovedFree(CallBase &CB) const = 0;
4597
4598 /// Create an abstract attribute view for the position \p IRP.
4600 Attributor &A);
4601
4602 /// See AbstractAttribute::getName()
4603 StringRef getName() const override { return "AAHeapToStack"; }
4604
4605 /// See AbstractAttribute::getIdAddr()
4606 const char *getIdAddr() const override { return &ID; }
4607
4608 /// This function should return true if the type of the \p AA is AAHeapToStack
4609 static bool classof(const AbstractAttribute *AA) {
4610 return (AA->getIdAddr() == &ID);
4611 }
4612
4613 /// Unique ID (due to the unique address)
4614 LLVM_ABI static const char ID;
4615};
4616
4617/// An abstract interface for privatizability.
4618///
4619/// A pointer is privatizable if it can be replaced by a new, private one.
4620/// Privatizing pointer reduces the use count, interaction between unrelated
4621/// code parts.
4622///
4623/// In order for a pointer to be privatizable its value cannot be observed
4624/// (=nocapture), it is (for now) not written (=readonly & noalias), we know
4625/// what values are necessary to make the private copy look like the original
4626/// one, and the values we need can be loaded (=dereferenceable).
4628 : public StateWrapper<BooleanState, AbstractAttribute> {
4631
4632 /// See AbstractAttribute::isValidIRPositionForInit
4635 return false;
4637 }
4638
4639 /// Returns true if pointer privatization is assumed to be possible.
4640 bool isAssumedPrivatizablePtr() const { return getAssumed(); }
4641
4642 /// Returns true if pointer privatization is known to be possible.
4643 bool isKnownPrivatizablePtr() const { return getKnown(); }
4644
4645 /// See AbstractAttribute::requiresCallersForArgOrFunction
4646 static bool requiresCallersForArgOrFunction() { return true; }
4647
4648 /// Return the type we can choose for a private copy of the underlying
4649 /// value. std::nullopt means it is not clear yet, nullptr means there is
4650 /// none.
4651 virtual std::optional<Type *> getPrivatizableType() const = 0;
4652
4653 /// Create an abstract attribute view for the position \p IRP.
4655 Attributor &A);
4656
4657 /// See AbstractAttribute::getName()
4658 StringRef getName() const override { return "AAPrivatizablePtr"; }
4659
4660 /// See AbstractAttribute::getIdAddr()
4661 const char *getIdAddr() const override { return &ID; }
4662
4663 /// This function should return true if the type of the \p AA is
4664 /// AAPricatizablePtr
4665 static bool classof(const AbstractAttribute *AA) {
4666 return (AA->getIdAddr() == &ID);
4667 }
4668
4669 /// Unique ID (due to the unique address)
4670 LLVM_ABI static const char ID;
4671};
4672
4673/// An abstract interface for memory access kind related attributes
4674/// (readnone/readonly/writeonly).
4676 : public IRAttribute<
4677 Attribute::None,
4678 StateWrapper<BitIntegerState<uint8_t, 3>, AbstractAttribute>,
4679 AAMemoryBehavior> {
4681
4682 /// See AbstractAttribute::hasTrivialInitializer.
4683 static bool hasTrivialInitializer() { return false; }
4684
4685 /// See AbstractAttribute::isValidIRPositionForInit
4687 if (!IRP.isFunctionScope() && !IRP.getAssociatedType()->isPointerTy())
4688 return false;
4689 return IRAttribute::isValidIRPositionForInit(A, IRP);
4690 }
4691
4692 /// State encoding bits. A set bit in the state means the property holds.
4693 /// BEST_STATE is the best possible state, 0 the worst possible state.
4694 enum {
4695 NO_READS = 1 << 0,
4696 NO_WRITES = 1 << 1,
4698
4700 };
4701 static_assert(BEST_STATE == getBestState(), "Unexpected BEST_STATE value");
4702
4703 /// Return true if we know that the underlying value is not read or accessed
4704 /// in its respective scope.
4705 bool isKnownReadNone() const { return isKnown(NO_ACCESSES); }
4706
4707 /// Return true if we assume that the underlying value is not read or accessed
4708 /// in its respective scope.
4709 bool isAssumedReadNone() const { return isAssumed(NO_ACCESSES); }
4710
4711 /// Return true if we know that the underlying value is not accessed
4712 /// (=written) in its respective scope.
4713 bool isKnownReadOnly() const { return isKnown(NO_WRITES); }
4714
4715 /// Return true if we assume that the underlying value is not accessed
4716 /// (=written) in its respective scope.
4717 bool isAssumedReadOnly() const { return isAssumed(NO_WRITES); }
4718
4719 /// Return true if we know that the underlying value is not read in its
4720 /// respective scope.
4721 bool isKnownWriteOnly() const { return isKnown(NO_READS); }
4722
4723 /// Return true if we assume that the underlying value is not read in its
4724 /// respective scope.
4725 bool isAssumedWriteOnly() const { return isAssumed(NO_READS); }
4726
4727 /// Create an abstract attribute view for the position \p IRP.
4729 Attributor &A);
4730
4731 /// See AbstractAttribute::getName()
4732 StringRef getName() const override { return "AAMemoryBehavior"; }
4733
4734 /// See AbstractAttribute::getIdAddr()
4735 const char *getIdAddr() const override { return &ID; }
4736
4737 /// This function should return true if the type of the \p AA is
4738 /// AAMemoryBehavior
4739 static bool classof(const AbstractAttribute *AA) {
4740 return (AA->getIdAddr() == &ID);
4741 }
4742
4743 /// Unique ID (due to the unique address)
4744 LLVM_ABI static const char ID;
4745};
4746
4747/// An abstract interface for all memory location attributes
4748/// (readnone/argmemonly/inaccessiblememonly/inaccessibleorargmemonly).
4750 : public IRAttribute<
4751 Attribute::None,
4752 StateWrapper<BitIntegerState<uint32_t, 511>, AbstractAttribute>,
4753 AAMemoryLocation> {
4754 using MemoryLocationsKind = StateType::base_t;
4755
4757
4758 /// See AbstractAttribute::requiresCalleeForCallBase.
4759 static bool requiresCalleeForCallBase() { return true; }
4760
4761 /// See AbstractAttribute::hasTrivialInitializer.
4762 static bool hasTrivialInitializer() { return false; }
4763
4764 /// See AbstractAttribute::isValidIRPositionForInit
4766 if (!IRP.isFunctionScope() &&
4768 return false;
4769 return IRAttribute::isValidIRPositionForInit(A, IRP);
4770 }
4771
4772 /// Encoding of different locations that could be accessed by a memory
4773 /// access.
4774 enum {
4788
4789 // Helper bit to track if we gave up or not.
4791
4793 };
4794 static_assert(BEST_STATE == getBestState(), "Unexpected BEST_STATE value");
4795
4796 /// Return true if we know that the associated functions has no observable
4797 /// accesses.
4798 bool isKnownReadNone() const { return isKnown(NO_LOCATIONS); }
4799
4800 /// Return true if we assume that the associated functions has no observable
4801 /// accesses.
4802 bool isAssumedReadNone() const {
4804 }
4805
4806 /// Return true if we know that the associated functions has at most
4807 /// local/stack accesses.
4808 bool isKnowStackOnly() const {
4809 return isKnown(inverseLocation(NO_LOCAL_MEM, true, true));
4810 }
4811
4812 /// Return true if we assume that the associated functions has at most
4813 /// local/stack accesses.
4814 bool isAssumedStackOnly() const {
4815 return isAssumed(inverseLocation(NO_LOCAL_MEM, true, true));
4816 }
4817
4818 /// Return true if we know that the underlying value will only access
4819 /// inaccesible memory only (see Attribute::InaccessibleMemOnly).
4821 return isKnown(inverseLocation(NO_INACCESSIBLE_MEM, true, true));
4822 }
4823
4824 /// Return true if we assume that the underlying value will only access
4825 /// inaccesible memory only (see Attribute::InaccessibleMemOnly).
4827 return isAssumed(inverseLocation(NO_INACCESSIBLE_MEM, true, true));
4828 }
4829
4830 /// Return true if we know that the underlying value will only access
4831 /// argument pointees (see Attribute::ArgMemOnly).
4832 bool isKnownArgMemOnly() const {
4833 return isKnown(inverseLocation(NO_ARGUMENT_MEM, true, true));
4834 }
4835
4836 /// Return true if we assume that the underlying value will only access
4837 /// argument pointees (see Attribute::ArgMemOnly).
4838 bool isAssumedArgMemOnly() const {
4839 return isAssumed(inverseLocation(NO_ARGUMENT_MEM, true, true));
4840 }
4841
4842 /// Return true if we know that the underlying value will only access
4843 /// inaccesible memory or argument pointees (see
4844 /// Attribute::InaccessibleOrArgMemOnly).
4846 return isKnown(
4848 }
4849
4850 /// Return true if we assume that the underlying value will only access
4851 /// inaccesible memory or argument pointees (see
4852 /// Attribute::InaccessibleOrArgMemOnly).
4857
4858 /// Return true if the underlying value may access memory through arguement
4859 /// pointers of the associated function, if any.
4860 bool mayAccessArgMem() const { return !isAssumed(NO_ARGUMENT_MEM); }
4861
4862 /// Return true if only the memory locations specififed by \p MLK are assumed
4863 /// to be accessed by the associated function.
4865 return isAssumed(MLK);
4866 }
4867
4868 /// Return the locations that are assumed to be not accessed by the associated
4869 /// function, if any.
4873
4874 /// Return the inverse of location \p Loc, thus for NO_XXX the return
4875 /// describes ONLY_XXX. The flags \p AndLocalMem and \p AndConstMem determine
4876 /// if local (=stack) and constant memory are allowed as well. Most of the
4877 /// time we do want them to be included, e.g., argmemonly allows accesses via
4878 /// argument pointers or local or constant memory accesses.
4879 static MemoryLocationsKind
4880 inverseLocation(MemoryLocationsKind Loc, bool AndLocalMem, bool AndConstMem) {
4881 return NO_LOCATIONS & ~(Loc | (AndLocalMem ? NO_LOCAL_MEM : 0) |
4882 (AndConstMem ? NO_CONST_MEM : 0));
4883 };
4884
4885 /// Return the locations encoded by \p MLK as a readable string.
4887
4888 /// Simple enum to distinguish read/write/read-write accesses.
4890 NONE = 0,
4891 READ = 1 << 0,
4892 WRITE = 1 << 1,
4894 };
4895
4896 /// Check \p Pred on all accesses to the memory kinds specified by \p MLK.
4897 ///
4898 /// This method will evaluate \p Pred on all accesses (access instruction +
4899 /// underlying accessed memory pointer) and it will return true if \p Pred
4900 /// holds every time.
4902 function_ref<bool(const Instruction *, const Value *, AccessKind,
4904 Pred,
4905 MemoryLocationsKind MLK) const = 0;
4906
4907 /// Create an abstract attribute view for the position \p IRP.
4909 Attributor &A);
4910
4911 /// See AbstractState::getAsStr(Attributor).
4912 const std::string getAsStr(Attributor *A) const override {
4914 }
4915
4916 /// See AbstractAttribute::getName()
4917 StringRef getName() const override { return "AAMemoryLocation"; }
4918
4919 /// See AbstractAttribute::getIdAddr()
4920 const char *getIdAddr() const override { return &ID; }
4921
4922 /// This function should return true if the type of the \p AA is
4923 /// AAMemoryLocation
4924 static bool classof(const AbstractAttribute *AA) {
4925 return (AA->getIdAddr() == &ID);
4926 }
4927
4928 /// Unique ID (due to the unique address)
4929 LLVM_ABI static const char ID;
4930};
4931
4932/// An abstract interface for range value analysis.
4934 : public StateWrapper<IntegerRangeState, AbstractAttribute, uint32_t> {
4937 : Base(IRP, IRP.getAssociatedType()->getIntegerBitWidth()) {}
4938
4939 /// See AbstractAttribute::isValidIRPositionForInit
4941 if (!IRP.getAssociatedType()->isIntegerTy())
4942 return false;
4944 }
4945
4946 /// See AbstractAttribute::requiresCallersForArgOrFunction
4947 static bool requiresCallersForArgOrFunction() { return true; }
4948
4949 /// See AbstractAttribute::getState(...).
4950 IntegerRangeState &getState() override { return *this; }
4951 const IntegerRangeState &getState() const override { return *this; }
4952
4953 /// Create an abstract attribute view for the position \p IRP.
4955 Attributor &A);
4956
4957 /// Return an assumed range for the associated value a program point \p CtxI.
4958 /// If \p I is nullptr, simply return an assumed range.
4959 virtual ConstantRange
4961 const Instruction *CtxI = nullptr) const = 0;
4962
4963 /// Return a known range for the associated value at a program point \p CtxI.
4964 /// If \p I is nullptr, simply return a known range.
4965 virtual ConstantRange
4967 const Instruction *CtxI = nullptr) const = 0;
4968
4969 /// Return an assumed constant for the associated value a program point \p
4970 /// CtxI.
4971 std::optional<Constant *>
4972 getAssumedConstant(Attributor &A, const Instruction *CtxI = nullptr) const {
4973 ConstantRange RangeV = getAssumedConstantRange(A, CtxI);
4974 if (auto *C = RangeV.getSingleElement()) {
4977 AA::getWithType(*ConstantInt::get(Ty->getContext(), *C), *Ty));
4978 }
4979 if (RangeV.isEmptySet())
4980 return std::nullopt;
4981 return nullptr;
4982 }
4983
4984 /// See AbstractAttribute::getName()
4985 StringRef getName() const override { return "AAValueConstantRange"; }
4986
4987 /// See AbstractAttribute::getIdAddr()
4988 const char *getIdAddr() const override { return &ID; }
4989
4990 /// This function should return true if the type of the \p AA is
4991 /// AAValueConstantRange
4992 static bool classof(const AbstractAttribute *AA) {
4993 return (AA->getIdAddr() == &ID);
4994 }
4995
4996 /// Unique ID (due to the unique address)
4997 LLVM_ABI static const char ID;
4998};
4999
5000/// A class for a set state.
5001/// The assumed boolean state indicates whether the corresponding set is full
5002/// set or not. If the assumed state is false, this is the worst state. The
5003/// worst state (invalid state) of set of potential values is when the set
5004/// contains every possible value (i.e. we cannot in any way limit the value
5005/// that the target position can take). That never happens naturally, we only
5006/// force it. As for the conditions under which we force it, see
5007/// AAPotentialConstantValues.
5008template <typename MemberTy> struct PotentialValuesState : AbstractState {
5010
5011 PotentialValuesState() : IsValidState(true), UndefIsContained(false) {}
5012
5014 : IsValidState(IsValid), UndefIsContained(false) {}
5015
5016 /// See AbstractState::isValidState(...)
5017 bool isValidState() const override { return IsValidState.isValidState(); }
5018
5019 /// See AbstractState::isAtFixpoint(...)
5020 bool isAtFixpoint() const override { return IsValidState.isAtFixpoint(); }
5021
5022 /// See AbstractState::indicatePessimisticFixpoint(...)
5024 return IsValidState.indicatePessimisticFixpoint();
5025 }
5026
5027 /// See AbstractState::indicateOptimisticFixpoint(...)
5029 return IsValidState.indicateOptimisticFixpoint();
5030 }
5031
5032 /// Return the assumed state
5034 const PotentialValuesState &getAssumed() const { return *this; }
5035
5036 /// Return this set. We should check whether this set is valid or not by
5037 /// isValidState() before calling this function.
5038 const SetTy &getAssumedSet() const {
5039 assert(isValidState() && "This set shoud not be used when it is invalid!");
5040 return Set;
5041 }
5042
5043 /// Returns whether this state contains an undef value or not.
5044 bool undefIsContained() const {
5045 assert(isValidState() && "This flag shoud not be used when it is invalid!");
5046 return UndefIsContained;
5047 }
5048
5050 if (isValidState() != RHS.isValidState())
5051 return false;
5052 if (!isValidState() && !RHS.isValidState())
5053 return true;
5054 if (undefIsContained() != RHS.undefIsContained())
5055 return false;
5056 return Set == RHS.getAssumedSet();
5057 }
5058
5059 /// Maximum number of potential values to be tracked.
5060 /// This is set by -attributor-max-potential-values command line option
5061 static unsigned MaxPotentialValues;
5062
5063 /// Return empty set as the best state of potential values.
5065 return PotentialValuesState(true);
5066 }
5067
5069 return getBestState();
5070 }
5071
5072 /// Return full set as the worst state of potential values.
5074 return PotentialValuesState(false);
5075 }
5076
5077 /// Union assumed set with the passed value.
5078 void unionAssumed(const MemberTy &C) { insert(C); }
5079
5080 /// Union assumed set with assumed set of the passed state \p PVS.
5081 void unionAssumed(const PotentialValuesState &PVS) { unionWith(PVS); }
5082
5083 /// Union assumed set with an undef value.
5084 void unionAssumedWithUndef() { unionWithUndef(); }
5085
5086 /// "Clamp" this state with \p PVS.
5088 IsValidState ^= PVS.IsValidState;
5089 unionAssumed(PVS);
5090 return *this;
5091 }
5092
5094 IsValidState &= PVS.IsValidState;
5095 unionAssumed(PVS);
5096 return *this;
5097 }
5098
5099 bool contains(const MemberTy &V) const {
5100 return !isValidState() ? true : Set.contains(V);
5101 }
5102
5103protected:
5105 assert(isValidState() && "This set shoud not be used when it is invalid!");
5106 return Set;
5107 }
5108
5109private:
5110 /// Check the size of this set, and invalidate when the size is no
5111 /// less than \p MaxPotentialValues threshold.
5112 void checkAndInvalidate() {
5113 if (Set.size() >= MaxPotentialValues)
5115 else
5116 reduceUndefValue();
5117 }
5118
5119 /// If this state contains both undef and not undef, we can reduce
5120 /// undef to the not undef value.
5121 void reduceUndefValue() { UndefIsContained = UndefIsContained & Set.empty(); }
5122
5123 /// Insert an element into this set.
5124 void insert(const MemberTy &C) {
5125 if (!isValidState())
5126 return;
5127 Set.insert(C);
5128 checkAndInvalidate();
5129 }
5130
5131 /// Take union with R.
5132 void unionWith(const PotentialValuesState &R) {
5133 /// If this is a full set, do nothing.
5134 if (!isValidState())
5135 return;
5136 /// If R is full set, change L to a full set.
5137 if (!R.isValidState()) {
5139 return;
5140 }
5141 Set.insert_range(R.Set);
5142 UndefIsContained |= R.undefIsContained();
5143 checkAndInvalidate();
5144 }
5145
5146 /// Take union with an undef value.
5147 void unionWithUndef() {
5148 UndefIsContained = true;
5149 reduceUndefValue();
5150 }
5151
5152 /// Take intersection with R.
5153 void intersectWith(const PotentialValuesState &R) {
5154 /// If R is a full set, do nothing.
5155 if (!R.isValidState())
5156 return;
5157 /// If this is a full set, change this to R.
5158 if (!isValidState()) {
5159 *this = R;
5160 return;
5161 }
5162 SetTy IntersectSet;
5163 for (const MemberTy &C : Set) {
5164 if (R.Set.count(C))
5165 IntersectSet.insert(C);
5166 }
5167 Set = IntersectSet;
5168 UndefIsContained &= R.undefIsContained();
5169 reduceUndefValue();
5170 }
5171
5172 /// A helper state which indicate whether this state is valid or not.
5173 BooleanState IsValidState;
5174
5175 /// Container for potential values
5176 SetTy Set;
5177
5178 /// Flag for undef value
5179 bool UndefIsContained;
5180};
5181
5186
5187 bool operator==(const DenormalState Other) const {
5188 return Mode == Other.Mode && ModeF32 == Other.ModeF32;
5189 }
5190
5191 bool operator!=(const DenormalState Other) const {
5192 return Mode != Other.Mode || ModeF32 != Other.ModeF32;
5193 }
5194
5195 bool isValid() const { return Mode.isValid() && ModeF32.isValid(); }
5196
5200 if (Caller == Callee)
5201 return Caller;
5202 if (Callee == DenormalMode::Dynamic)
5203 return Caller;
5204 if (Caller == DenormalMode::Dynamic)
5205 return Callee;
5206 return DenormalMode::Invalid;
5207 }
5208
5210 return DenormalMode{unionDenormalKind(Callee.Output, Caller.Output),
5211 unionDenormalKind(Callee.Input, Caller.Input)};
5212 }
5213
5215 DenormalState Callee(*this);
5216 Callee.Mode = unionAssumed(Callee.Mode, Caller.Mode);
5217 Callee.ModeF32 = unionAssumed(Callee.ModeF32, Caller.ModeF32);
5218 return Callee;
5219 }
5220 };
5221
5223
5224 /// Explicitly track whether we've hit a fixed point.
5225 bool IsAtFixedpoint = false;
5226
5228
5229 DenormalState getKnown() const { return Known; }
5230
5231 // There's only really known or unknown, there's no speculatively assumable
5232 // state.
5233 DenormalState getAssumed() const { return Known; }
5234
5235 bool isValidState() const override { return Known.isValid(); }
5236
5237 /// Return true if there are no dynamic components to the denormal mode worth
5238 /// specializing.
5239 bool isModeFixed() const {
5240 return Known.Mode.Input != DenormalMode::Dynamic &&
5241 Known.Mode.Output != DenormalMode::Dynamic &&
5242 Known.ModeF32.Input != DenormalMode::Dynamic &&
5243 Known.ModeF32.Output != DenormalMode::Dynamic;
5244 }
5245
5246 bool isAtFixpoint() const override { return IsAtFixedpoint; }
5247
5253
5257
5261
5263 Known = Known.unionWith(Caller.getKnown());
5264 return *this;
5265 }
5266};
5267
5271
5275 const PotentialLLVMValuesState &R);
5276
5277/// An abstract interface for potential values analysis.
5278///
5279/// This AA collects potential values for each IR position.
5280/// An assumed set of potential values is initialized with the empty set (the
5281/// best state) and it will grow monotonically as we find more potential values
5282/// for this position.
5283/// The set might be forced to the worst state, that is, to contain every
5284/// possible value for this position in 2 cases.
5285/// 1. We surpassed the \p MaxPotentialValues threshold. This includes the
5286/// case that this position is affected (e.g. because of an operation) by a
5287/// Value that is in the worst state.
5288/// 2. We tried to initialize on a Value that we cannot handle (e.g. an
5289/// operator we do not currently handle).
5290///
5291/// For non constant integers see AAPotentialValues.
5293 : public StateWrapper<PotentialConstantIntValuesState, AbstractAttribute> {
5296
5297 /// See AbstractAttribute::isValidIRPositionForInit
5299 if (!IRP.getAssociatedType()->isIntegerTy())
5300 return false;
5302 }
5303
5304 /// See AbstractAttribute::requiresCallersForArgOrFunction
5305 static bool requiresCallersForArgOrFunction() { return true; }
5306
5307 /// See AbstractAttribute::getState(...).
5308 PotentialConstantIntValuesState &getState() override { return *this; }
5310 return *this;
5311 }
5312
5313 /// Create an abstract attribute view for the position \p IRP.
5316
5317 /// Return assumed constant for the associated value
5318 std::optional<Constant *>
5319 getAssumedConstant(Attributor &A, const Instruction *CtxI = nullptr) const {
5320 if (!isValidState())
5321 return nullptr;
5322 if (getAssumedSet().size() == 1) {
5325 *ConstantInt::get(Ty->getContext(), *(getAssumedSet().begin())),
5326 *Ty));
5327 }
5328 if (getAssumedSet().size() == 0) {
5329 if (undefIsContained())
5331 return std::nullopt;
5332 }
5333
5334 return nullptr;
5335 }
5336
5337 /// Return the minimum trailing zeros of potential constants
5339 if (!isValidState() || getAssumedSet().empty())
5340 return 0;
5341 unsigned TrailingZeros = getAssumedSet().begin()->getBitWidth() + 1;
5342 for (const APInt &It : getAssumedSet()) {
5343 if (It.countTrailingZeros() < TrailingZeros)
5344 TrailingZeros = It.countTrailingZeros();
5345 }
5346 if (TrailingZeros > getAssumedSet().begin()->getBitWidth())
5347 return 0;
5348 return TrailingZeros;
5349 }
5350 /// See AbstractAttribute::getName()
5351 StringRef getName() const override { return "AAPotentialConstantValues"; }
5352
5353 /// See AbstractAttribute::getIdAddr()
5354 const char *getIdAddr() const override { return &ID; }
5355
5356 /// This function should return true if the type of the \p AA is
5357 /// AAPotentialConstantValues
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
5367 : public StateWrapper<PotentialLLVMValuesState, AbstractAttribute> {
5370
5371 /// See AbstractAttribute::requiresCallersForArgOrFunction
5372 static bool requiresCallersForArgOrFunction() { return true; }
5373
5374 /// See AbstractAttribute::getState(...).
5375 PotentialLLVMValuesState &getState() override { return *this; }
5376 const PotentialLLVMValuesState &getState() const override { return *this; }
5377
5378 /// Create an abstract attribute view for the position \p IRP.
5380 Attributor &A);
5381
5382 /// Extract the single value in \p Values if any.
5383 LLVM_ABI static Value *
5385 const IRPosition &IRP,
5387
5388 /// See AbstractAttribute::getName()
5389 StringRef getName() const override { return "AAPotentialValues"; }
5390
5391 /// See AbstractAttribute::getIdAddr()
5392 const char *getIdAddr() const override { return &ID; }
5393
5394 /// This function should return true if the type of the \p AA is
5395 /// AAPotentialValues
5396 static bool classof(const AbstractAttribute *AA) {
5397 return (AA->getIdAddr() == &ID);
5398 }
5399
5400 /// Unique ID (due to the unique address)
5401 LLVM_ABI static const char ID;
5402
5403private:
5404 virtual bool getAssumedSimplifiedValues(
5406 AA::ValueScope, bool RecurseForSelectAndPHI = false) const = 0;
5407
5408 friend struct Attributor;
5409};
5410
5411/// An abstract interface for all noundef attributes.
5413 : public IRAttribute<Attribute::NoUndef,
5414 StateWrapper<BooleanState, AbstractAttribute>,
5415 AANoUndef> {
5417
5418 /// See IRAttribute::isImpliedByUndef
5419 static bool isImpliedByUndef() { return false; }
5420
5421 /// See IRAttribute::isImpliedByPoison
5422 static bool isImpliedByPoison() { return false; }
5423
5424 /// See IRAttribute::isImpliedByIR
5425 LLVM_ABI static bool isImpliedByIR(Attributor &A, const IRPosition &IRP,
5426 Attribute::AttrKind ImpliedAttributeKind,
5427 bool IgnoreSubsumingPositions = false);
5428
5429 /// Return true if we assume that the underlying value is noundef.
5430 bool isAssumedNoUndef() const { return getAssumed(); }
5431
5432 /// Return true if we know that underlying value is noundef.
5433 bool isKnownNoUndef() const { return getKnown(); }
5434
5435 /// Create an abstract attribute view for the position \p IRP.
5437 Attributor &A);
5438
5439 /// See AbstractAttribute::getName()
5440 StringRef getName() const override { return "AANoUndef"; }
5441
5442 /// See AbstractAttribute::getIdAddr()
5443 const char *getIdAddr() const override { return &ID; }
5444
5445 /// This function should return true if the type of the \p AA is AANoUndef
5446 static bool classof(const AbstractAttribute *AA) {
5447 return (AA->getIdAddr() == &ID);
5448 }
5449
5450 /// Unique ID (due to the unique address)
5451 LLVM_ABI static const char ID;
5452};
5453
5455 : public IRAttribute<
5456 Attribute::NoFPClass,
5457 StateWrapper<BitIntegerState<uint32_t, fcAllFlags, fcNone>,
5458 AbstractAttribute>,
5459 AANoFPClass> {
5462
5464
5465 /// See AbstractAttribute::isValidIRPositionForInit
5467 return AttributeFuncs::isNoFPClassCompatibleType(IRP.getAssociatedType());
5468 }
5469
5470 /// Return the underlying assumed nofpclass.
5472 return static_cast<FPClassTest>(getAssumed());
5473 }
5474 /// Return the underlying known nofpclass.
5476 return static_cast<FPClassTest>(getKnown());
5477 }
5478
5479 /// Create an abstract attribute view for the position \p IRP.
5481 Attributor &A);
5482
5483 /// See AbstractAttribute::getName()
5484 StringRef getName() const override { return "AANoFPClass"; }
5485
5486 /// See AbstractAttribute::getIdAddr()
5487 const char *getIdAddr() const override { return &ID; }
5488
5489 /// This function should return true if the type of the \p AA is AANoFPClass
5490 static bool classof(const AbstractAttribute *AA) {
5491 return (AA->getIdAddr() == &ID);
5492 }
5493
5494 /// Unique ID (due to the unique address)
5495 LLVM_ABI static const char ID;
5496};
5497
5498struct AACallGraphNode;
5499struct AACallEdges;
5500
5501/// An Iterator for call edges, creates AACallEdges attributes in a lazy way.
5502/// This iterator becomes invalid if the underlying edge list changes.
5503/// So This shouldn't outlive a iteration of Attributor.
5504class AACallEdgeIterator
5505 : public iterator_adaptor_base<AACallEdgeIterator,
5506 SetVector<Function *>::iterator> {
5507 AACallEdgeIterator(Attributor &A, SetVector<Function *>::iterator Begin)
5508 : iterator_adaptor_base(Begin), A(A) {}
5509
5510public:
5512
5513private:
5514 Attributor &A;
5515 friend AACallEdges;
5516 friend AttributorCallGraph;
5517};
5518
5521 virtual ~AACallGraphNode() = default;
5522
5525
5526 /// Iterator range for exploring the call graph.
5531
5532protected:
5533 /// Reference to Attributor needed for GraphTraits implementation.
5535};
5536
5537/// An abstract state for querying live call edges.
5538/// This interface uses the Attributor's optimistic liveness
5539/// information to compute the edges that are alive.
5540struct AACallEdges : public StateWrapper<BooleanState, AbstractAttribute>,
5543
5545 : Base(IRP), AACallGraphNode(A) {}
5546
5547 /// See AbstractAttribute::requiresNonAsmForCallBase.
5548 static bool requiresNonAsmForCallBase() { return false; }
5549
5550 /// Get the optimistic edges.
5551 virtual const SetVector<Function *> &getOptimisticEdges() const = 0;
5552
5553 /// Is there any call with a unknown callee.
5554 virtual bool hasUnknownCallee() const = 0;
5555
5556 /// Is there any call with a unknown callee, excluding any inline asm.
5557 virtual bool hasNonAsmUnknownCallee() const = 0;
5558
5559 /// Iterator for exploring the call graph.
5563
5564 /// Iterator for exploring the call graph.
5568
5569 /// Create an abstract attribute view for the position \p IRP.
5571 Attributor &A);
5572
5573 /// See AbstractAttribute::getName()
5574 StringRef getName() const override { return "AACallEdges"; }
5575
5576 /// See AbstractAttribute::getIdAddr()
5577 const char *getIdAddr() const override { return &ID; }
5578
5579 /// This function should return true if the type of the \p AA is AACallEdges.
5580 static bool classof(const AbstractAttribute *AA) {
5581 return (AA->getIdAddr() == &ID);
5582 }
5583
5584 /// Unique ID (due to the unique address)
5585 LLVM_ABI static const char ID;
5586};
5587
5588// Synthetic root node for the Attributor's internal call graph.
5591 ~AttributorCallGraph() override = default;
5592
5594 return AACallEdgeIterator(A, A.Functions.begin());
5595 }
5596
5598 return AACallEdgeIterator(A, A.Functions.end());
5599 }
5600
5601 /// Force populate the entire call graph.
5602 void populateAll() const {
5603 for (const AACallGraphNode *AA : optimisticEdgesRange()) {
5604 // Nothing else to do here.
5605 (void)AA;
5606 }
5607 }
5608
5609 LLVM_ABI void print();
5610};
5611
5612template <> struct GraphTraits<AACallGraphNode *> {
5615
5617 return Node->optimisticEdgesBegin();
5618 }
5619
5621 return Node->optimisticEdgesEnd();
5622 }
5623};
5624
5625template <>
5629
5631 return static_cast<AACallGraphNode *>(G);
5632 }
5633
5635 return G->optimisticEdgesBegin();
5636 }
5637
5639 return G->optimisticEdgesEnd();
5640 }
5641};
5642
5643template <>
5646
5648 const AttributorCallGraph *Graph) {
5649 const AACallEdges *AACE = static_cast<const AACallEdges *>(Node);
5650 return AACE->getAssociatedFunction()->getName().str();
5651 }
5652
5654 const AttributorCallGraph *Graph) {
5655 // Hide the synth root.
5656 return static_cast<const AACallGraphNode *>(Graph) == Node;
5657 }
5658};
5659
5661 : public StateWrapper<BooleanState, AbstractAttribute> {
5664
5665 /// Summary about the execution domain of a block or instruction.
5690
5691 /// Create an abstract attribute view for the position \p IRP.
5693 Attributor &A);
5694
5695 /// See AbstractAttribute::getName().
5696 StringRef getName() const override { return "AAExecutionDomain"; }
5697
5698 /// See AbstractAttribute::getIdAddr().
5699 const char *getIdAddr() const override { return &ID; }
5700
5701 /// Check if an instruction is executed only by the initial thread.
5703 return isExecutedByInitialThreadOnly(*I.getParent());
5704 }
5705
5706 /// Check if a basic block is executed only by the initial thread.
5707 virtual bool isExecutedByInitialThreadOnly(const BasicBlock &) const = 0;
5708
5709 /// Check if the instruction \p I is executed in an aligned region, that is,
5710 /// the synchronizing effects before and after \p I are both aligned barriers.
5711 /// This effectively means all threads execute \p I together.
5713 const Instruction &I) const = 0;
5714
5716 /// Return the execution domain with which the call \p CB is entered and the
5717 /// one with which it is left.
5718 virtual std::pair<ExecutionDomainTy, ExecutionDomainTy>
5719 getExecutionDomain(const CallBase &CB) const = 0;
5721
5722 /// Helper function to determine if \p FI is a no-op given the information
5723 /// about its execution from \p ExecDomainAA.
5724 virtual bool isNoOpFence(const FenceInst &FI) const = 0;
5725
5726 /// This function should return true if the type of the \p AA is
5727 /// AAExecutionDomain.
5728 static bool classof(const AbstractAttribute *AA) {
5729 return (AA->getIdAddr() == &ID);
5730 }
5731
5732 /// Unique ID (due to the unique address)
5733 LLVM_ABI static const char ID;
5734};
5735
5736/// An abstract Attribute for computing reachability between functions.
5738 : public StateWrapper<BooleanState, AbstractAttribute> {
5740
5742
5743 /// If the function represented by this possition can reach \p Fn.
5744 bool canReach(Attributor &A, const Function &Fn) const {
5745 Function *Scope = getAnchorScope();
5746 if (!Scope || Scope->isDeclaration())
5747 return true;
5748 return instructionCanReach(A, Scope->getEntryBlock().front(), Fn);
5749 }
5750
5751 /// Can \p Inst reach \p Fn.
5752 /// See also AA::isPotentiallyReachable.
5754 Attributor &A, const Instruction &Inst, const Function &Fn,
5755 const AA::InstExclusionSetTy *ExclusionSet = nullptr) const = 0;
5756
5757 /// Create an abstract attribute view for the position \p IRP.
5760
5761 /// See AbstractAttribute::getName()
5762 StringRef getName() const override { return "AAInterFnReachability"; }
5763
5764 /// See AbstractAttribute::getIdAddr()
5765 const char *getIdAddr() const override { return &ID; }
5766
5767 /// This function should return true if the type of the \p AA is AACallEdges.
5768 static bool classof(const AbstractAttribute *AA) {
5769 return (AA->getIdAddr() == &ID);
5770 }
5771
5772 /// Unique ID (due to the unique address)
5773 LLVM_ABI static const char ID;
5774};
5775
5776/// An abstract Attribute for determining the necessity of the convergent
5777/// attribute.
5778struct AANonConvergent : public StateWrapper<BooleanState, AbstractAttribute> {
5780
5782
5783 /// Create an abstract attribute view for the position \p IRP.
5785 Attributor &A);
5786
5787 /// Return true if "non-convergent" is assumed.
5788 bool isAssumedNotConvergent() const { return getAssumed(); }
5789
5790 /// Return true if "non-convergent" is known.
5791 bool isKnownNotConvergent() const { return getKnown(); }
5792
5793 /// See AbstractAttribute::getName()
5794 StringRef getName() const override { return "AANonConvergent"; }
5795
5796 /// See AbstractAttribute::getIdAddr()
5797 const char *getIdAddr() const override { return &ID; }
5798
5799 /// This function should return true if the type of the \p AA is
5800 /// AANonConvergent.
5801 static bool classof(const AbstractAttribute *AA) {
5802 return (AA->getIdAddr() == &ID);
5803 }
5804
5805 /// Unique ID (due to the unique address)
5806 LLVM_ABI static const char ID;
5807};
5808
5809/// An abstract interface for struct information.
5812
5813 /// See AbstractAttribute::isValidIRPositionForInit
5816 return false;
5818 }
5819
5821 // First two bits to distinguish may and must accesses.
5822 AK_MUST = 1 << 0,
5823 AK_MAY = 1 << 1,
5824
5825 // Then two bits for read and write. These are not exclusive.
5826 AK_R = 1 << 2,
5827 AK_W = 1 << 3,
5829
5830 // One special case for assumptions about memory content. These
5831 // are neither reads nor writes. They are however always modeled
5832 // as read to avoid using them for write removal.
5834
5835 // Helper for easy access.
5842 };
5843
5844 /// A helper containing a list of offsets computed for a Use. Ideally this
5845 /// list should be strictly ascending, but we ensure that only when we
5846 /// actually translate the list of offsets to a RangeList.
5847 struct OffsetInfo {
5851
5852 const_iterator begin() const { return Offsets.begin(); }
5853 const_iterator end() const { return Offsets.end(); }
5854
5855 bool operator==(const OffsetInfo &RHS) const {
5856 return Offsets == RHS.Offsets;
5857 }
5858
5859 bool operator!=(const OffsetInfo &RHS) const { return !(*this == RHS); }
5860
5861 bool insert(int64_t Offset) { return Offsets.insert(Offset).second; }
5862 bool isUnassigned() const { return Offsets.size() == 0; }
5863
5864 bool isUnknown() const {
5865 if (isUnassigned())
5866 return false;
5867 if (Offsets.size() == 1)
5868 return *Offsets.begin() == AA::RangeTy::Unknown;
5869 return false;
5870 }
5871
5872 void setUnknown() {
5873 Offsets.clear();
5875 }
5876
5877 void addToAll(int64_t Inc) {
5878 VecTy NewOffsets;
5879 for (auto &Offset : Offsets)
5880 NewOffsets.insert(Offset + Inc);
5881 Offsets = std::move(NewOffsets);
5882 }
5883
5884 /// Copy offsets from \p R into the current list.
5885 ///
5886 /// Ideally all lists should be strictly ascending, but we defer that to the
5887 /// actual use of the list. So we just blindly append here.
5888 bool merge(const OffsetInfo &R) { return set_union(Offsets, R.Offsets); }
5889 };
5890
5891 /// A container for a list of ranges.
5892 struct RangeList {
5893 // The set of ranges rarely contains more than one element, and is unlikely
5894 // to contain more than say four elements. So we find the middle-ground with
5895 // a sorted vector. This avoids hard-coding a rarely used number like "four"
5896 // into every instance of a SmallSet.
5902
5903 RangeList(const RangeTy &R) { Ranges.push_back(R); }
5905 Ranges.reserve(Offsets.size());
5906 for (unsigned i = 0, e = Offsets.size(); i != e; ++i) {
5907 assert(((i + 1 == e) || Offsets[i] < Offsets[i + 1]) &&
5908 "Expected strictly ascending offsets.");
5909 Ranges.emplace_back(Offsets[i], Size);
5910 }
5911 }
5912 RangeList() = default;
5913
5914 iterator begin() { return Ranges.begin(); }
5915 iterator end() { return Ranges.end(); }
5916 const_iterator begin() const { return Ranges.begin(); }
5917 const_iterator end() const { return Ranges.end(); }
5918
5919 // Helpers required for std::set_difference
5921 void push_back(const RangeTy &R) {
5922 assert((Ranges.empty() || RangeTy::LessThan(Ranges.back(), R)) &&
5923 "Ensure the last element is the greatest.");
5924 Ranges.push_back(R);
5925 }
5926
5927 /// Copy ranges from \p L that are not in \p R, into \p D.
5928 static void set_difference(const RangeList &L, const RangeList &R,
5929 RangeList &D) {
5930 std::set_difference(L.begin(), L.end(), R.begin(), R.end(),
5931 std::back_inserter(D), RangeTy::LessThan);
5932 }
5933
5934 unsigned size() const { return Ranges.size(); }
5935
5936 bool operator==(const RangeList &OI) const { return Ranges == OI.Ranges; }
5937
5938 /// Merge the ranges in \p RHS into the current ranges.
5939 /// - Merging a list of unknown ranges makes the current list unknown.
5940 /// - Ranges with the same offset are merged according to RangeTy::operator&
5941 /// \return true if the current RangeList changed.
5942 bool merge(const RangeList &RHS) {
5943 if (isUnknown())
5944 return false;
5945 if (RHS.isUnknown()) {
5946 setUnknown();
5947 return true;
5948 }
5949
5950 if (Ranges.empty()) {
5951 Ranges = RHS.Ranges;
5952 return true;
5953 }
5954
5955 bool Changed = false;
5956 auto LPos = Ranges.begin();
5957 for (auto &R : RHS.Ranges) {
5958 auto Result = insert(LPos, R);
5959 if (isUnknown())
5960 return true;
5961 LPos = Result.first;
5962 Changed |= Result.second;
5963 }
5964 return Changed;
5965 }
5966
5967 /// Insert \p R at the given iterator \p Pos, and merge if necessary.
5968 ///
5969 /// This assumes that all ranges before \p Pos are LessThan \p R, and
5970 /// then maintains the sorted order for the suffix list.
5971 ///
5972 /// \return The place of insertion and true iff anything changed.
5973 std::pair<iterator, bool> insert(iterator Pos, const RangeTy &R) {
5974 if (isUnknown())
5975 return std::make_pair(Ranges.begin(), false);
5976 if (R.offsetOrSizeAreUnknown()) {
5977 return std::make_pair(setUnknown(), true);
5978 }
5979
5980 // Maintain this as a sorted vector of unique entries.
5981 auto LB = std::lower_bound(Pos, Ranges.end(), R, RangeTy::LessThan);
5982 if (LB == Ranges.end() || LB->Offset != R.Offset)
5983 return std::make_pair(Ranges.insert(LB, R), true);
5984 bool Changed = *LB != R;
5985 *LB &= R;
5986 if (LB->offsetOrSizeAreUnknown())
5987 return std::make_pair(setUnknown(), true);
5988 return std::make_pair(LB, Changed);
5989 }
5990
5991 /// Insert the given range \p R, maintaining sorted order.
5992 ///
5993 /// \return The place of insertion and true iff anything changed.
5994 std::pair<iterator, bool> insert(const RangeTy &R) {
5995 return insert(Ranges.begin(), R);
5996 }
5997
5998 /// Add the increment \p Inc to the offset of every range.
5999 void addToAllOffsets(int64_t Inc) {
6000 assert(!isUnassigned() &&
6001 "Cannot increment if the offset is not yet computed!");
6002 if (isUnknown())
6003 return;
6004 for (auto &R : Ranges) {
6005 R.Offset += Inc;
6006 }
6007 }
6008
6009 /// Return true iff there is exactly one range and it is known.
6010 bool isUnique() const {
6011 return Ranges.size() == 1 && !Ranges.front().offsetOrSizeAreUnknown();
6012 }
6013
6014 /// Return the unique range, assuming it exists.
6015 const RangeTy &getUnique() const {
6016 assert(isUnique() && "No unique range to return!");
6017 return Ranges.front();
6018 }
6019
6020 /// Return true iff the list contains an unknown range.
6021 bool isUnknown() const {
6022 if (isUnassigned())
6023 return false;
6024 if (Ranges.front().offsetOrSizeAreUnknown()) {
6025 assert(Ranges.size() == 1 && "Unknown is a singleton range.");
6026 return true;
6027 }
6028 return false;
6029 }
6030
6031 /// Discard all ranges and insert a single unknown range.
6033 Ranges.clear();
6034 Ranges.push_back(RangeTy::getUnknown());
6035 return Ranges.begin();
6036 }
6037
6038 /// Return true if no ranges have been inserted.
6039 bool isUnassigned() const { return Ranges.size() == 0; }
6040 };
6041
6042 /// An access description.
6043 struct Access {
6044 Access(Instruction *I, int64_t Offset, int64_t Size,
6045 std::optional<Value *> Content, AccessKind Kind, Type *Ty)
6046 : LocalI(I), RemoteI(I), Content(Content), Ranges(Offset, Size),
6047 Kind(Kind), Ty(Ty) {
6048 verify();
6049 }
6050 Access(Instruction *LocalI, Instruction *RemoteI, const RangeList &Ranges,
6051 std::optional<Value *> Content, AccessKind K, Type *Ty)
6052 : LocalI(LocalI), RemoteI(RemoteI), Content(Content), Ranges(Ranges),
6053 Kind(K), Ty(Ty) {
6054 if (Ranges.size() > 1) {
6055 Kind = AccessKind(Kind | AK_MAY);
6056 Kind = AccessKind(Kind & ~AK_MUST);
6057 }
6058 verify();
6059 }
6060 Access(Instruction *LocalI, Instruction *RemoteI, int64_t Offset,
6061 int64_t Size, std::optional<Value *> Content, AccessKind Kind,
6062 Type *Ty)
6063 : LocalI(LocalI), RemoteI(RemoteI), Content(Content),
6064 Ranges(Offset, Size), Kind(Kind), Ty(Ty) {
6065 verify();
6066 }
6067 Access(const Access &Other) = default;
6068
6069 Access &operator=(const Access &Other) = default;
6070 bool operator==(const Access &R) const {
6071 return LocalI == R.LocalI && RemoteI == R.RemoteI && Ranges == R.Ranges &&
6072 Content == R.Content && Kind == R.Kind;
6073 }
6074 bool operator!=(const Access &R) const { return !(*this == R); }
6075
6077 assert(RemoteI == R.RemoteI && "Expected same instruction!");
6078 assert(LocalI == R.LocalI && "Expected same instruction!");
6079
6080 // Note that every Access object corresponds to a unique Value, and only
6081 // accesses to the same Value are merged. Hence we assume that all ranges
6082 // are the same size. If ranges can be different size, then the contents
6083 // must be dropped.
6084 Ranges.merge(R.Ranges);
6085 Content =
6086 AA::combineOptionalValuesInAAValueLatice(Content, R.Content, Ty);
6087
6088 // Combine the access kind, which results in a bitwise union.
6089 // If there is more than one range, then this must be a MAY.
6090 // If we combine a may and a must access we clear the must bit.
6091 Kind = AccessKind(Kind | R.Kind);
6092 if ((Kind & AK_MAY) || Ranges.size() > 1) {
6093 Kind = AccessKind(Kind | AK_MAY);
6094 Kind = AccessKind(Kind & ~AK_MUST);
6095 }
6096 verify();
6097 return *this;
6098 }
6099
6100 void verify() {
6101 assert(isMustAccess() + isMayAccess() == 1 &&
6102 "Expect must or may access, not both.");
6103 assert(isAssumption() + isWrite() <= 1 &&
6104 "Expect assumption access or write access, never both.");
6105 assert((isMayAccess() || Ranges.size() == 1) &&
6106 "Cannot be a must access if there are multiple ranges.");
6107 }
6108
6109 /// Return the access kind.
6110 AccessKind getKind() const { return Kind; }
6111
6112 /// Return true if this is a read access.
6113 bool isRead() const { return Kind & AK_R; }
6114
6115 /// Return true if this is a write access.
6116 bool isWrite() const { return Kind & AK_W; }
6117
6118 /// Return true if this is a write access.
6119 bool isWriteOrAssumption() const { return isWrite() || isAssumption(); }
6120
6121 /// Return true if this is an assumption access.
6122 bool isAssumption() const { return Kind == AK_ASSUMPTION; }
6123
6124 bool isMustAccess() const {
6125 bool MustAccess = Kind & AK_MUST;
6126 assert((!MustAccess || Ranges.size() < 2) &&
6127 "Cannot be a must access if there are multiple ranges.");
6128 return MustAccess;
6129 }
6130
6131 bool isMayAccess() const {
6132 bool MayAccess = Kind & AK_MAY;
6133 assert((MayAccess || Ranges.size() < 2) &&
6134 "Cannot be a must access if there are multiple ranges.");
6135 return MayAccess;
6136 }
6137
6138 /// Return the instruction that causes the access with respect to the local
6139 /// scope of the associated attribute.
6140 Instruction *getLocalInst() const { return LocalI; }
6141
6142 /// Return the actual instruction that causes the access.
6143 Instruction *getRemoteInst() const { return RemoteI; }
6144
6145 /// Return true if the value written is not known yet.
6146 bool isWrittenValueYetUndetermined() const { return !Content; }
6147
6148 /// Return true if the value written cannot be determined at all.
6150 return Content.has_value() && !*Content;
6151 }
6152
6153 /// Set the value written to nullptr, i.e., unknown.
6154 void setWrittenValueUnknown() { Content = nullptr; }
6155
6156 /// Return the type associated with the access, if known.
6157 Type *getType() const { return Ty; }
6158
6159 /// Return the value writen, if any.
6162 "Value needs to be determined before accessing it.");
6163 return *Content;
6164 }
6165
6166 /// Return the written value which can be `llvm::null` if it is not yet
6167 /// determined.
6168 std::optional<Value *> getContent() const { return Content; }
6169
6170 bool hasUniqueRange() const { return Ranges.isUnique(); }
6171 const AA::RangeTy &getUniqueRange() const { return Ranges.getUnique(); }
6172
6173 /// Add a range accessed by this Access.
6174 ///
6175 /// If there are multiple ranges, then this is a "may access".
6176 void addRange(int64_t Offset, int64_t Size) {
6177 Ranges.insert({Offset, Size});
6178 if (!hasUniqueRange()) {
6179 Kind = AccessKind(Kind | AK_MAY);
6180 Kind = AccessKind(Kind & ~AK_MUST);
6181 }
6182 }
6183
6184 const RangeList &getRanges() const { return Ranges; }
6185
6187 const_iterator begin() const { return Ranges.begin(); }
6188 const_iterator end() const { return Ranges.end(); }
6189
6190 private:
6191 /// The instruction responsible for the access with respect to the local
6192 /// scope of the associated attribute.
6193 Instruction *LocalI;
6194
6195 /// The instruction responsible for the access.
6196 Instruction *RemoteI;
6197
6198 /// The value written, if any. `std::nullopt` means "not known yet",
6199 /// `nullptr` cannot be determined.
6200 std::optional<Value *> Content;
6201
6202 /// Set of potential ranges accessed from the base pointer.
6203 RangeList Ranges;
6204
6205 /// The access kind, e.g., READ, as bitset (could be more than one).
6207
6208 /// The type of the content, thus the type read/written, can be null if not
6209 /// available.
6210 Type *Ty;
6211 };
6212
6213 /// Create an abstract attribute view for the position \p IRP.
6215 Attributor &A);
6216
6217 /// See AbstractAttribute::getName()
6218 StringRef getName() const override { return "AAPointerInfo"; }
6219
6220 /// See AbstractAttribute::getIdAddr()
6221 const char *getIdAddr() const override { return &ID; }
6222
6224 using const_bin_iterator = OffsetBinsTy::const_iterator;
6225 virtual const_bin_iterator begin() const = 0;
6226 virtual const_bin_iterator end() const = 0;
6227 virtual int64_t numOffsetBins() const = 0;
6228 virtual bool reachesReturn() const = 0;
6229 virtual void addReturnedOffsetsTo(OffsetInfo &) const = 0;
6230
6231 /// Call \p CB on all accesses that might interfere with \p Range and return
6232 /// true if all such accesses were known and the callback returned true for
6233 /// all of them, false otherwise. An access interferes with an offset-size
6234 /// pair if it might read or write that memory region.
6236 AA::RangeTy Range, function_ref<bool(const Access &, bool)> CB) const = 0;
6237
6238 /// Call \p CB on all accesses that might interfere with \p I and
6239 /// return true if all such accesses were known and the callback returned true
6240 /// for all of them, false otherwise. In contrast to forallInterferingAccesses
6241 /// this function will perform reasoning to exclude write accesses that cannot
6242 /// affect the load even if they on the surface look as if they would. The
6243 /// flag \p HasBeenWrittenTo will be set to true if we know that \p I does not
6244 /// read the initial value of the underlying memory. If \p SkipCB is given and
6245 /// returns false for a potentially interfering access, that access is not
6246 /// checked for actual interference.
6248 Attributor &A, const AbstractAttribute &QueryingAA, Instruction &I,
6249 bool FindInterferingWrites, bool FindInterferingReads,
6250 function_ref<bool(const Access &, bool)> CB, bool &HasBeenWrittenTo,
6252 function_ref<bool(const Access &)> SkipCB = nullptr) const = 0;
6253
6254 /// This function should return true if the type of the \p AA is AAPointerInfo
6255 static bool classof(const AbstractAttribute *AA) {
6256 return (AA->getIdAddr() == &ID);
6257 }
6258
6259 /// Unique ID (due to the unique address)
6260 LLVM_ABI static const char ID;
6261};
6262
6264
6265/// An abstract attribute for getting assumption information.
6267 : public StateWrapper<SetState<StringRef>, AbstractAttribute,
6268 DenseSet<StringRef>> {
6269 using Base =
6271
6273 const DenseSet<StringRef> &Known)
6274 : Base(IRP, Known) {}
6275
6276 /// Returns true if the assumption set contains the assumption \p Assumption.
6277 virtual bool hasAssumption(const StringRef Assumption) const = 0;
6278
6279 /// Create an abstract attribute view for the position \p IRP.
6281 Attributor &A);
6282
6283 /// See AbstractAttribute::getName()
6284 StringRef getName() const override { return "AAAssumptionInfo"; }
6285
6286 /// See AbstractAttribute::getIdAddr()
6287 const char *getIdAddr() const override { return &ID; }
6288
6289 /// This function should return true if the type of the \p AA is
6290 /// AAAssumptionInfo
6291 static bool classof(const AbstractAttribute *AA) {
6292 return (AA->getIdAddr() == &ID);
6293 }
6294
6295 /// Unique ID (due to the unique address)
6296 LLVM_ABI static const char ID;
6297};
6298
6299/// An abstract attribute for getting all assumption underlying objects.
6302
6303 /// See AbstractAttribute::isValidIRPositionForInit
6306 return false;
6308 }
6309
6310 /// See AbstractAttribute::requiresCallersForArgOrFunction
6311 static bool requiresCallersForArgOrFunction() { return true; }
6312
6313 /// Create an abstract attribute biew for the position \p IRP.
6315 Attributor &A);
6316
6317 /// See AbstractAttribute::getName()
6318 StringRef getName() const override { return "AAUnderlyingObjects"; }
6319
6320 /// See AbstractAttribute::getIdAddr()
6321 const char *getIdAddr() const override { return &ID; }
6322
6323 /// This function should return true if the type of the \p AA is
6324 /// AAUnderlyingObjects.
6325 static bool classof(const AbstractAttribute *AA) {
6326 return (AA->getIdAddr() == &ID);
6327 }
6328
6329 /// Unique ID (due to the unique address)
6330 LLVM_ABI static const char ID;
6331
6332 /// Check \p Pred on all underlying objects in \p Scope collected so far.
6333 ///
6334 /// This method will evaluate \p Pred on all underlying objects in \p Scope
6335 /// collected so far and return true if \p Pred holds on all of them.
6336 virtual bool
6338 AA::ValueScope Scope = AA::Interprocedural) const = 0;
6339};
6340
6341/// An abstract interface for identifying pointers from which loads can be
6342/// marked invariant.
6345
6346 /// See AbstractAttribute::isValidIRPositionForInit
6348 if (!IRP.getAssociatedType()->isPointerTy())
6349 return false;
6350
6352 }
6353
6354 /// Create an abstract attribute view for the position \p IRP.
6357
6358 /// Return true if the pointer's contents are known to remain invariant.
6359 virtual bool isKnownInvariant() const = 0;
6360 virtual bool isKnownLocallyInvariant() const = 0;
6361
6362 /// Return true if the pointer's contents are assumed to remain invariant.
6363 virtual bool isAssumedInvariant() const = 0;
6364 virtual bool isAssumedLocallyInvariant() const = 0;
6365
6366 /// See AbstractAttribute::getName().
6367 StringRef getName() const override { return "AAInvariantLoadPointer"; }
6368
6369 /// See AbstractAttribute::getIdAddr().
6370 const char *getIdAddr() const override { return &ID; }
6371
6372 /// This function should return true if the type of the \p AA is
6373 /// AAInvariantLoadPointer
6374 static bool classof(const AbstractAttribute *AA) {
6375 return (AA->getIdAddr() == &ID);
6376 }
6377
6378 /// Unique ID (due to the unique address).
6379 LLVM_ABI static const char ID;
6380};
6381
6382/// An abstract interface for address space information.
6383struct AAAddressSpace : public StateWrapper<BooleanState, AbstractAttribute> {
6386
6387 /// See AbstractAttribute::isValidIRPositionForInit
6390 return false;
6392 }
6393
6394 /// See AbstractAttribute::requiresCallersForArgOrFunction
6395 static bool requiresCallersForArgOrFunction() { return true; }
6396
6397 /// Return the address space of the associated value. \p NoAddressSpace is
6398 /// returned if the associated value is dead. This functions is not supposed
6399 /// to be called if the AA is invalid.
6400 virtual uint32_t getAddressSpace() const = 0;
6401
6402 /// Create an abstract attribute view for the position \p IRP.
6404 Attributor &A);
6405
6406 /// See AbstractAttribute::getName()
6407 StringRef getName() const override { return "AAAddressSpace"; }
6408
6409 /// See AbstractAttribute::getIdAddr()
6410 const char *getIdAddr() const override { return &ID; }
6411
6412 /// This function should return true if the type of the \p AA is
6413 /// AAAssumptionInfo
6414 static bool classof(const AbstractAttribute *AA) {
6415 return (AA->getIdAddr() == &ID);
6416 }
6417
6418 /// Unique ID (due to the unique address)
6419 LLVM_ABI static const char ID;
6420
6421protected:
6422 // Invalid address space which indicates the associated value is dead.
6423 static const uint32_t InvalidAddressSpace = ~0U;
6424};
6425
6426/// An abstract interface for potential address space information.
6428 : public StateWrapper<BooleanState, AbstractAttribute> {
6433
6434 /// See AbstractAttribute::isValidIRPositionForInit
6437 return false;
6439 }
6440
6441 /// See AbstractAttribute::requiresCallersForArgOrFunction
6442 static bool requiresCallersForArgOrFunction() { return true; }
6443
6444 /// Create an abstract attribute view for the position \p IRP.
6446 Attributor &A);
6447 /// See AbstractAttribute::getName()
6448 StringRef getName() const override { return "AANoAliasAddrSpace"; }
6449
6450 /// See AbstractAttribute::getIdAddr()
6451 const char *getIdAddr() const override { return &ID; }
6452
6453 /// This function should return true if the type of the \p AA is
6454 /// AAAssumptionInfo
6455 static bool classof(const AbstractAttribute *AA) {
6456 return (AA->getIdAddr() == &ID);
6457 }
6458
6459 /// Unique ID (due to the unique address)
6460 LLVM_ABI static const char ID;
6461
6462protected:
6465};
6466
6467struct AAAllocationInfo : public StateWrapper<BooleanState, AbstractAttribute> {
6470
6471 /// See AbstractAttribute::isValidIRPositionForInit
6474 return false;
6476 }
6477
6478 /// Create an abstract attribute view for the position \p IRP.
6480 Attributor &A);
6481
6482 virtual std::optional<TypeSize> getAllocatedSize() const = 0;
6483
6484 /// See AbstractAttribute::getName()
6485 StringRef getName() const override { return "AAAllocationInfo"; }
6486
6487 /// See AbstractAttribute::getIdAddr()
6488 const char *getIdAddr() const override { return &ID; }
6489
6490 /// This function should return true if the type of the \p AA is
6491 /// AAAllocationInfo
6492 static bool classof(const AbstractAttribute *AA) {
6493 return (AA->getIdAddr() == &ID);
6494 }
6495
6496 constexpr static const std::optional<TypeSize> HasNoAllocationSize =
6497 std::make_optional<TypeSize>(-1, true);
6498
6499 LLVM_ABI static const char ID;
6500};
6501
6502/// An abstract interface for llvm::GlobalValue information interference.
6504 : public StateWrapper<BooleanState, AbstractAttribute> {
6507
6508 /// See AbstractAttribute::isValidIRPositionForInit
6511 return false;
6512 auto *GV = dyn_cast<GlobalValue>(&IRP.getAnchorValue());
6513 if (!GV)
6514 return false;
6515 return GV->hasLocalLinkage();
6516 }
6517
6518 /// Create an abstract attribute view for the position \p IRP.
6520 Attributor &A);
6521
6522 /// Return true iff \p U is a potential use of the associated global value.
6523 virtual bool isPotentialUse(const Use &U) const = 0;
6524
6525 /// See AbstractAttribute::getName()
6526 StringRef getName() const override { return "AAGlobalValueInfo"; }
6527
6528 /// See AbstractAttribute::getIdAddr()
6529 const char *getIdAddr() const override { return &ID; }
6530
6531 /// This function should return true if the type of the \p AA is
6532 /// AAGlobalValueInfo
6533 static bool classof(const AbstractAttribute *AA) {
6534 return (AA->getIdAddr() == &ID);
6535 }
6536
6537 /// Unique ID (due to the unique address)
6538 LLVM_ABI static const char ID;
6539};
6540
6541/// An abstract interface for indirect call information interference.
6543 : public StateWrapper<BooleanState, AbstractAttribute> {
6546
6547 /// See AbstractAttribute::isValidIRPositionForInit
6550 return false;
6551 auto *CB = cast<CallBase>(IRP.getCtxI());
6552 return CB->getOpcode() == Instruction::Call && CB->isIndirectCall() &&
6553 !CB->isMustTailCall();
6554 }
6555
6556 /// Create an abstract attribute view for the position \p IRP.
6558 Attributor &A);
6559
6560 /// Call \CB on each potential callee value and return true if all were known
6561 /// and \p CB returned true on all of them. Otherwise, return false.
6562 virtual bool foreachCallee(function_ref<bool(Function *)> CB) const = 0;
6563
6564 /// See AbstractAttribute::getName()
6565 StringRef getName() const override { return "AAIndirectCallInfo"; }
6566
6567 /// See AbstractAttribute::getIdAddr()
6568 const char *getIdAddr() const override { return &ID; }
6569
6570 /// This function should return true if the type of the \p AA is
6571 /// AAIndirectCallInfo
6572 /// This function should return true if the type of the \p AA is
6573 /// AADenormalFPMath.
6574 static bool classof(const AbstractAttribute *AA) {
6575 return (AA->getIdAddr() == &ID);
6576 }
6577
6578 /// Unique ID (due to the unique address)
6579 LLVM_ABI static const char ID;
6580};
6581
6582/// An abstract Attribute for specializing "dynamic" components of
6583/// denormal_fpenv to a known denormal mode.
6585 : public StateWrapper<DenormalFPMathState, AbstractAttribute> {
6587
6589
6590 /// Create an abstract attribute view for the position \p IRP.
6592 Attributor &A);
6593
6594 /// See AbstractAttribute::getName()
6595 StringRef getName() const override { return "AADenormalFPMath"; }
6596
6597 /// See AbstractAttribute::getIdAddr()
6598 const char *getIdAddr() const override { return &ID; }
6599
6600 /// This function should return true if the type of the \p AA is
6601 /// AADenormalFPMath.
6602 static bool classof(const AbstractAttribute *AA) {
6603 return (AA->getIdAddr() == &ID);
6604 }
6605
6606 /// Unique ID (due to the unique address)
6607 LLVM_ABI static const char ID;
6608};
6609
6610/// Run options, used by the pass manager.
6621
6622namespace AA {
6623/// Helper to avoid creating an AA for IR Attributes that might already be set.
6624template <Attribute::AttrKind AK, typename AAType = AbstractAttribute>
6626 const IRPosition &IRP, DepClassTy DepClass, bool &IsKnown,
6627 bool IgnoreSubsumingPositions = false,
6628 const AAType **AAPtr = nullptr) {
6629 IsKnown = false;
6630 switch (AK) {
6631#define CASE(ATTRNAME, AANAME, ...) \
6632 case Attribute::ATTRNAME: { \
6633 if (AANAME::isImpliedByIR(A, IRP, AK, IgnoreSubsumingPositions)) \
6634 return IsKnown = true; \
6635 if (!QueryingAA) \
6636 return false; \
6637 const auto *AA = A.getAAFor<AANAME>(*QueryingAA, IRP, DepClass); \
6638 if (AAPtr) \
6639 *AAPtr = reinterpret_cast<const AAType *>(AA); \
6640 if (!AA || !AA->isAssumed(__VA_ARGS__)) \
6641 return false; \
6642 IsKnown = AA->isKnown(__VA_ARGS__); \
6643 return true; \
6644 }
6645 CASE(NoUnwind, AANoUnwind, );
6646 CASE(WillReturn, AAWillReturn, );
6647 CASE(NoFree, AANoFree, );
6648 CASE(Captures, AANoCapture, );
6649 CASE(NoRecurse, AANoRecurse, );
6650 CASE(NoReturn, AANoReturn, );
6651 CASE(NoSync, AANoSync, );
6652 CASE(NoAlias, AANoAlias, );
6653 CASE(NonNull, AANonNull, );
6654 CASE(MustProgress, AAMustProgress, );
6655 CASE(NoUndef, AANoUndef, );
6659#undef CASE
6660 default:
6661 llvm_unreachable("hasAssumedIRAttr not available for this attribute kind");
6662 };
6663}
6664} // namespace AA
6665
6666} // end namespace llvm
6667
6668#endif // LLVM_TRANSFORMS_IPO_ATTRIBUTOR_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
aarch64 promote const
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< 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:213
This file contains the declarations for the subclasses of Constant, which represent the different fla...
DXIL Resource Access
This file provides an implementation of debug counters.
#define DEBUG_COUNTER(VARNAME, COUNTERNAME, DESC)
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
Machine Check Debug Module
This file implements a map that provides insertion order iteration.
This file provides utility analysis objects describing memory locations.
#define T
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
Basic Register Allocator
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
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:407
Functions, function parameters, and return types can have attributes to indicate how they should be t...
Definition Attributes.h:105
static LLVM_ABI Attribute get(LLVMContext &Context, AttrKind Kind, uint64_t Val=0)
Return a uniquified Attribute object.
AttrKind
This enumeration lists the attributes that can be associated with parameters, function results,...
Definition Attributes.h:124
@ None
No attributes have been set.
Definition Attributes.h:126
static bool isEnumAttrKind(AttrKind Kind)
Definition Attributes.h:137
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:43
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
static bool shouldExecute(CounterInfo &Counter)
Implements a dense probed hash-table based set.
Definition DenseSet.h:289
Analysis pass which computes a DominatorTree.
Definition Dominators.h:274
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:354
void setAttributes(AttributeList Attrs)
Set the attribute list for this Function.
Definition Function.h:357
size_t arg_size() const
Definition Function.h:901
Type * getReturnType() const
Returns the type of the ret val.
Definition Function.h:216
Argument * getArg(unsigned i) const
Definition Function.h:886
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition Function.cpp:728
bool hasLocalLinkage() const
typename Sizer::Allocator Allocator
Invoke instruction.
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:68
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:587
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:67
The optimization diagnostic interface.
Pass interface - Implemented by all 'passes'.
Definition Pass.h:99
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:106
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:339
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 TimeTraceScope is a helper class to call the begin and end functions of the time trace profiler.
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:282
bool isPtrOrPtrVectorTy() const
Return true if this is a pointer type or a vector of pointer types.
Definition Type.h:285
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:257
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:255
LLVMContext & getContext() const
All values hold a context through their type.
Definition Value.h:258
LLVM_ABI const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
Definition Value.cpp:712
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:318
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
Changed
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Abstract Attribute helper functions.
Definition Attributor.h:165
LLVM_ABI bool isAssumedReadNone(Attributor &A, const IRPosition &IRP, const AbstractAttribute &QueryingAA, bool &IsKnown)
Return true if IRP is readnone.
LLVM_ABI bool isAssumedReadOnly(Attributor &A, const IRPosition &IRP, const AbstractAttribute &QueryingAA, bool &IsKnown)
Return true if IRP is readonly.
raw_ostream & operator<<(raw_ostream &OS, const RangeTy &R)
Definition Attributor.h:335
LLVM_ABI std::optional< Value * > combineOptionalValuesInAAValueLatice(const std::optional< Value * > &A, const std::optional< Value * > &B, Type *Ty)
Return the combination of A and B such that the result is a possible value of both.
LLVM_ABI bool isValidAtPosition(const ValueAndContext &VAC, InformationCache &InfoCache)
Return true if the value of VAC is a valid at the position of VAC, that is a constant,...
LLVM_ABI bool isAssumedThreadLocalObject(Attributor &A, Value &Obj, const AbstractAttribute &QueryingAA)
Return true if Obj is assumed to be a thread local object.
LLVM_ABI bool isGPUConstantAddressSpace(const Module &M, unsigned AS)
Check if the given address space AS corresponds to a GPU constant address space for the target triple...
LLVM_ABI bool isGPUGenericAddressSpace(const Module &M, unsigned AS)
Check if the given address space AS corresponds to a GPU generic 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:344
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:340
ValueScope
Flags to distinguish intra-procedural queries from potentially inter-procedural queries.
Definition Attributor.h:194
@ Intraprocedural
Definition Attributor.h:195
@ Interprocedural
Definition Attributor.h:196
LLVM_ABI bool isValidInScope(const Value &V, const Function *Scope)
Return true if V is a valid value in Scope, that is a constant or an instruction/argument of Scope.
LLVM_ABI bool isGPUGlobalAddressSpace(const Module &M, unsigned AS)
Check if the given address space AS corresponds to a GPU global address space for the target triple i...
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.
E & operator^=(E &LHS, E RHS)
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
NodeAddr< UseNode * > Use
Definition RDFGraph.h:385
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:558
FunctionAddr VTableAddr Value
Definition InstrProf.h:137
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:1668
LLVM_ABI unsigned MaxInitializationChainLength
The value passed to the line option that defines the maximal initialization chain length.
APInt operator&(APInt a, const APInt &b)
Definition APInt.h:2152
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:2142
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
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
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
AnalysisManager< LazyCallGraph::SCC, LazyCallGraph & > CGSCCAnalysisManager
The CGSCC analysis manager.
LLVM_ABI bool canSimplifyInvokeNoUnwind(const Function *F)
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.
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.
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:1916
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
iterator_range< pointer_iterator< WrappedIteratorT > > make_pointer_range(RangeT &&Range)
Definition iterator.h:368
ChangeStatus
{
Definition Attributor.h:497
bool operator|=(SparseBitVector< ElementSize > &LHS, const SparseBitVector< ElementSize > *RHS)
@ OPTIONAL
The target may be valid if the source is not.
Definition Attributor.h:509
@ NONE
Do not track a dependence between source and target.
Definition Attributor.h:510
@ REQUIRED
The target cannot be valid if the source is not.
Definition Attributor.h:508
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
APInt operator|(APInt a, const APInt &b)
Definition APInt.h:2172
BumpPtrAllocatorImpl<> BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
Definition Allocator.h:383
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:861
static LLVM_ABI AAAddressSpace & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
static bool requiresCallersForArgOrFunction()
See AbstractAttribute::requiresCallersForArgOrFunction.
StringRef getName() const override
See AbstractAttribute::getName()
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)
See AbstractAttribute::isValidIRPositionForInit.
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
See AbstractAttribute::getIdAddr()
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
See AbstractAttribute::isValidIRPositionForInit.
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
See AbstractAttribute::getName()
static LLVM_ABI const char ID
virtual std::optional< TypeSize > getAllocatedSize() const =0
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
See AbstractAttribute::isValidIRPositionForInit.
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
static LLVM_ABI AAAllocationInfo & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
StringRef getName() const override
See AbstractAttribute::getName()
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
See AbstractAttribute::getName()
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
See AbstractAttribute::getIdAddr()
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()
See AbstractAttribute::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
See AbstractAttribute::getName()
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
See AbstractAttribute::getIdAddr()
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
See AbstractAttribute::getIdAddr()
StringRef getName() const override
See AbstractAttribute::getName()
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:527
friend struct Attributor
Definition Attributor.h:549
mapped_iterator< DepSetTy::iterator, decltype(&DepGetVal)> iterator
Definition Attributor.h:534
mapped_iterator< DepSetTy::iterator, decltype(&DepGetValAA)> aaiterator
Definition Attributor.h:535
virtual ~AADepGraphNode()=default
SmallSetVector< DepTy, 2 > DepSetTy
Definition Attributor.h:519
static AADepGraphNode * DepGetVal(const DepTy &DT)
Definition Attributor.h:526
DepSetTy & getDeps()
Definition Attributor.h:547
iterator child_begin()
Definition Attributor.h:540
DepSetTy Deps
Set of dependency graph nodes which should be updated if this one is updated.
Definition Attributor.h:524
friend struct AADepGraph
Definition Attributor.h:550
virtual void print(Attributor *, raw_ostream &OS) const
Definition Attributor.h:544
aaiterator begin()
Definition Attributor.h:538
PointerIntPair< AADepGraphNode *, 1 > DepTy
Definition Attributor.h:518
void print(raw_ostream &OS) const
Definition Attributor.h:543
The data structure for the dependency graph.
Definition Attributor.h:558
~AADepGraph()=default
iterator begin()
Definition Attributor.h:573
mapped_iterator< AADepGraphNode::DepSetTy::iterator, decltype(&DepGetVal)> iterator
Definition Attributor.h:564
LLVM_ABI void viewGraph()
AADepGraphNode SyntheticRoot
There is no root node for the dependency graph.
Definition Attributor.h:570
LLVM_ABI void print()
Print dependency graph.
static AADepGraphNode * DepGetVal(const DepTy &DT)
Definition Attributor.h:563
iterator end()
Definition Attributor.h:574
LLVM_ABI void dumpGraph()
Dump graph to file.
AADepGraphNode * GetEntryNode()
Definition Attributor.h:571
AADepGraph()=default
AADepGraphNode::DepTy DepTy
Definition Attributor.h:562
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
See AbstractAttribute::getName()
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
See AbstractAttribute::getIdAddr()
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
See AbstractAttribute::isValidIRPositionForInit.
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
See AbstractAttribute::getIdAddr().
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
See AbstractAttribute::getName().
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
See AbstractAttribute::getName()
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)
See AbstractAttribute::isValidIRPositionForInit.
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
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
See AbstractAttribute::getName()
StateWrapper< BooleanState, AbstractAttribute > Base
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
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
See AbstractAttribute::getName()
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
See AbstractAttribute::getIdAddr()
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)
See AbstractAttribute::isValidIRPositionForInit.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
bool isKnownUniqueForAnalysis() const
Return true if we know that the underlying value is unique in its scope wrt.
StringRef getName() const override
See AbstractAttribute::getName()
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
See AbstractAttribute::getIdAddr()
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
See AbstractAttribute::getIdAddr()
bool canReach(Attributor &A, const Function &Fn) const
If the function represented by this possition can reach Fn.
StringRef getName() const override
See AbstractAttribute::getName()
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
See AbstractAttribute::getName()
static LLVM_ABI const char ID
Unique ID (due to the unique address)
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
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
See AbstractAttribute::getIdAddr().
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
See AbstractAttribute::isValidIRPositionForInit.
StringRef getName() const override
See AbstractAttribute::getName().
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)
bool isLiveInstSet(T begin, T end) const
This method is used to check if at least one instruction in a collection of instructions is live.
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)
See AbstractAttribute::isValidIRPositionForInit.
StringRef getName() const override
See AbstractAttribute::getName()
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
See AbstractAttribute::getIdAddr()
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
See AbstractAttribute::getName()
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()
See AbstractAttribute::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)
See AbstractAttribute::isValidIRPositionForInit.
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
See AbstractAttribute::getIdAddr()
bool isKnownReadOnly() const
Return true if we know that the underlying value is not accessed (=written) in its respective scope.
StringRef getName() const override
See AbstractAttribute::getName()
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
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()
See AbstractAttribute::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()
See AbstractAttribute::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)
See AbstractAttribute::isValidIRPositionForInit.
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
See AbstractState::getAsStr(Attributor).
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
See AbstractAttribute::getName()
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
See AbstractAttribute::getIdAddr()
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()
See AbstractAttribute::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)
See AbstractAttribute::isValidIRPositionForInit.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
AANoAliasAddrSpace(const IRPosition &IRP, Attributor &A)
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
StateWrapper< BooleanState, AbstractAttribute > Base
RangeMap::Allocator Allocator
StringRef getName() const override
See AbstractAttribute::getName()
An abstract interface for all noalias attributes.
static LLVM_ABI bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
See IRAttribute::isImpliedByIR.
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AANoAlias.
StringRef getName() const override
See AbstractAttribute::getName()
static bool requiresCallersForArgOrFunction()
See AbstractAttribute::requiresCallersForArgOrFunction.
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
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)
See AbstractAttribute::isValidIRPositionForInit.
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)
See AbstractAttribute::isValidIRPositionForInit.
@ 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
See AbstractAttribute::getIdAddr()
AANoCapture(const IRPosition &IRP, Attributor &A)
StringRef getName() const override
See AbstractAttribute::getName()
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)
See IRAttribute::isImpliedByIR.
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)
See AbstractAttribute::isValidIRPositionForInit.
AANoFPClass(const IRPosition &IRP, Attributor &A)
StringRef getName() const override
See AbstractAttribute::getName()
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
See AbstractAttribute::getIdAddr()
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)
See IRAttribute::isImpliedByIR.
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)
See AbstractAttribute::isValidIRPositionForInit.
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AANoFree.
StringRef getName() const override
See AbstractAttribute::getName()
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
An abstract attribute for norecurse.
StringRef getName() const override
See AbstractAttribute::getName()
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
See AbstractAttribute::getIdAddr()
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
See AbstractAttribute::getName()
AANoReturn(const IRPosition &IRP, Attributor &A)
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
bool isKnownNoReturn() const
Return true if the underlying object is known to never return.
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
See AbstractAttribute::isValidIRPositionForInit.
AANoSync(const IRPosition &IRP, Attributor &A)
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
StringRef getName() const override
See AbstractAttribute::getName()
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()
See IRAttribute::isImpliedByUndef.
StringRef getName() const override
See AbstractAttribute::getName()
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
See AbstractAttribute::getIdAddr()
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()
See IRAttribute::isImpliedByPoison.
static LLVM_ABI bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
See IRAttribute::isImpliedByIR.
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
See AbstractAttribute::getName()
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
See AbstractAttribute::getIdAddr()
static LLVM_ABI const char ID
Unique ID (due to the unique address)
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
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
See AbstractAttribute::getName()
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()
See IRAttribute::isImpliedByUndef.
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
See AbstractAttribute::isValidIRPositionForInit.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
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
See AbstractAttribute::getName()
static LLVM_ABI bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
See AbstractAttribute::isImpliedByIR(...).
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()
See AbstractAttribute::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.
void setWrittenValueUnknown()
Set the value written to nullptr, i.e., unknown.
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
void addRange(int64_t Offset, int64_t Size)
Add a range accessed by this Access.
RangeList::const_iterator const_iterator
Instruction * getRemoteInst() const
Return the actual instruction that causes the access.
const AA::RangeTy & getUniqueRange() const
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)
bool isUnique() const
Return true iff there is exactly one range and it is known.
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.
const RangeTy & getUnique() const
Return the unique range, assuming it exists.
bool merge(const RangeList &RHS)
Merge the ranges in RHS into the current ranges.
std::pair< iterator, bool > insert(const RangeTy &R)
Insert the given range R, maintaining sorted order.
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)
See AbstractAttribute::isValidIRPositionForInit.
virtual bool reachesReturn() const =0
StringRef getName() const override
See AbstractAttribute::getName()
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
See AbstractAttribute::getIdAddr()
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
See AbstractAttribute::getState(...).
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()
See AbstractAttribute::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
See AbstractAttribute::getIdAddr()
StringRef getName() const override
See AbstractAttribute::getName()
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
See AbstractAttribute::isValidIRPositionForInit.
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
See AbstractAttribute::getState(...).
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()
See AbstractAttribute::requiresCallersForArgOrFunction.
StateWrapper< PotentialLLVMValuesState, AbstractAttribute > Base
const PotentialLLVMValuesState & getState() const override
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
static LLVM_ABI const char ID
Unique ID (due to the unique address)
StringRef getName() const override
See AbstractAttribute::getName()
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)
See AbstractAttribute::isValidIRPositionForInit.
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
See AbstractAttribute::getName()
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAPricatizablePtr.
static bool requiresCallersForArgOrFunction()
See AbstractAttribute::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
See AbstractAttribute::getIdAddr()
bool isKnownPrivatizablePtr() const
Returns true if pointer privatization is known to be possible.
StateWrapper< BooleanState, AbstractAttribute > Base
static LLVM_ABI AAUndefinedBehavior & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
bool isKnownToCauseUB() const
Return true if "undefined behavior" is known.
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
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.
bool isAssumedToCauseUB() const
Return true if "undefined behavior" is assumed.
StringRef getName() const override
See AbstractAttribute::getName()
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)
See AbstractAttribute::isValidIRPositionForInit.
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
See AbstractAttribute::getIdAddr()
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()
See AbstractAttribute::requiresCallersForArgOrFunction.
StringRef getName() const override
See AbstractAttribute::getName()
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
See AbstractAttribute::isValidIRPositionForInit.
StringRef getName() const override
See AbstractAttribute::getName()
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()
See AbstractAttribute::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
See AbstractAttribute::getIdAddr()
IntegerRangeState & getState() override
See AbstractAttribute::getState(...).
const IntegerRangeState & getState() const override
virtual ConstantRange getKnownConstantRange(Attributor &A, const Instruction *CtxI=nullptr) const =0
Return a known range for the associated value at a program point CtxI.
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
See AbstractAttribute::getName()
StateWrapper< ValueSimplifyStateType, AbstractAttribute, Type * > Base
static LLVM_ABI const char ID
Unique ID (due to the unique address)
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
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
See AbstractAttribute::getIdAddr()
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
See AbstractAttribute::getName()
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:253
bool offsetAndSizeAreUnknown() const
Return true if offset and size are unknown, thus this is the default unknown object.
Definition Attributor.h:268
static constexpr int64_t Unknown
Definition Attributor.h:332
bool offsetOrSizeAreUnknown() const
Return true if offset or size are unknown.
Definition Attributor.h:262
static constexpr int64_t Unassigned
Constants used to represent special offsets or sizes.
Definition Attributor.h:331
RangeTy & operator&=(const RangeTy &R)
Definition Attributor.h:291
static RangeTy getUnknown()
Definition Attributor.h:259
bool isUnassigned() const
Return true if the offset and size are unassigned.
Definition Attributor.h:273
static bool LessThan(const RangeTy &L, const RangeTy &R)
Comparison for sorting ranges.
Definition Attributor.h:317
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:281
RangeTy(int64_t Offset, int64_t Size)
Definition Attributor.h:257
Value * getValue() const
Definition Attributor.h:206
std::pair< Value *, const Instruction * > Base
Definition Attributor.h:201
ValueAndContext(Value &V, const Instruction *CtxI)
Definition Attributor.h:203
const Instruction * getCtxI() const
Definition Attributor.h:207
ValueAndContext(Value &V, const Instruction &CtxI)
Definition Attributor.h:204
ValueAndContext(const Base &B)
Definition Attributor.h:202
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...
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.
DenseSet< const char * > * Allowed
If not null, a set limiting the attribute opportunities.
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.
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 SmallVectorImpl< Type * > & getReplacementTypes() const
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()
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
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)
void setAssumed(bool Value)
Set the assumed value to Value but never below the known one.
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:441
static AA::ValueAndContext getEmptyKey()
Definition Attributor.h:434
static unsigned getHashValue(const AA::ValueAndContext &VAC)
Definition Attributor.h:437
DenseMapInfo< AA::ValueAndContext::Base > Base
Definition Attributor.h:433
static AA::ValueScope getEmptyKey()
Definition Attributor.h:450
static bool isEqual(const AA::ValueScope &LHS, const AA::ValueScope &RHS)
Definition Attributor.h:457
DenseMapInfo< unsigned char > Base
Definition Attributor.h:449
static unsigned getHashValue(const AA::ValueScope &S)
Definition Attributor.h:453
static IRPosition getEmptyKey()
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
See AbstractAttribute::manifest(...).
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:594
Function * getAssociatedFunction() const
Return the associated function, if any.
Definition Attributor.h:725
void setAttrList(const AttributeList &AttrList) const
Update the attributes associated with this function or call site scope.
Definition Attributor.h:861
unsigned getAttrIdx() const
Return the index in the attribute list for this position.
Definition Attributor.h:826
bool hasCallBaseContext() const
Check if the position has any call base context.
Definition Attributor.h:943
static const IRPosition callsite_returned(const CallBase &CB)
Create a position describing the returned value of CB.
Definition Attributor.h:662
static const IRPosition returned(const Function &F, const CallBaseContext *CBContext=nullptr)
Create a position describing the returned value of F.
Definition Attributor.h:644
LLVM_ABI Argument * getAssociatedArgument() const
Return the associated argument, if any.
bool isAnyCallSitePosition() const
Definition Attributor.h:910
bool operator!=(const IRPosition &RHS) const
Definition Attributor.h:703
static const IRPosition value(const Value &V, const CallBaseContext *CBContext=nullptr)
Create a position describing the value of V.
Definition Attributor.h:618
CallBase CallBaseContext
Definition Attributor.h:597
AttributeList getAttrList() const
Return the attributes associated with this function or call site scope.
Definition Attributor.h:854
int getCalleeArgNo() const
Return the callee argument number of the associated value if it is an argument or call site argument,...
Definition Attributor.h:812
static const IRPosition inst(const Instruction &I, const CallBaseContext *CBContext=nullptr)
Create a position describing the instruction I.
Definition Attributor.h:630
static const IRPosition callsite_argument(const CallBase &CB, unsigned ArgNo)
Create a position describing the argument of CB at position ArgNo.
Definition Attributor.h:667
Kind
The positions we distinguish in the IR.
Definition Attributor.h:600
@ IRP_ARGUMENT
An attribute for a function argument.
Definition Attributor.h:608
@ IRP_RETURNED
An attribute for the function return value.
Definition Attributor.h:604
@ IRP_CALL_SITE
An attribute for a call site (function scope).
Definition Attributor.h:607
@ IRP_CALL_SITE_RETURNED
An attribute for a call site return value.
Definition Attributor.h:605
@ IRP_FUNCTION
An attribute for a function (scope).
Definition Attributor.h:606
@ IRP_FLOAT
A position that is not associated with a spot suitable for attributes.
Definition Attributor.h:602
@ IRP_CALL_SITE_ARGUMENT
An attribute for a call site argument.
Definition Attributor.h:609
@ IRP_INVALID
An invalid position.
Definition Attributor.h:601
Instruction * getCtxI() const
Return the context instruction, if any.
Definition Attributor.h:778
static const IRPosition argument(const Argument &Arg, const CallBaseContext *CBContext=nullptr)
Create a position describing the argument Arg.
Definition Attributor.h:651
Type * getAssociatedType() const
Return the type this abstract attribute is associated with.
Definition Attributor.h:801
static LLVM_ABI const IRPosition EmptyKey
Special DenseMap key values.
Definition Attributor.h:948
bool isFunctionScope() const
Return true if this is a function or call site position.
Definition Attributor.h:755
bool operator==(const IRPosition &RHS) const
Definition Attributor.h:700
static const IRPosition callsite_argument(AbstractCallSite ACS, unsigned ArgNo)
Create a position describing the argument of ACS at position ArgNo.
Definition Attributor.h:674
static const IRPosition function(const Function &F, const CallBaseContext *CBContext=nullptr)
Create a position describing the function scope of F.
Definition Attributor.h:637
const CallBaseContext * getCallBaseContext() const
Get the call base context from the position.
Definition Attributor.h:940
Value & getAssociatedValue() const
Return the value this abstract attribute is associated with.
Definition Attributor.h:792
Value * getArg(unsigned ArgNo) const
Return theargument ArgNo associated with this function or call site scope.
Definition Attributor.h:880
Value & getAnchorValue() const
Return the value this abstract attribute is anchored with.
Definition Attributor.h:711
Value * getAttrListAnchor() const
Return the value attributes are attached to.
Definition Attributor.h:847
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:821
bool isFnInterfaceKind() const
Return true if the position refers to a function interface, that is the function scope,...
Definition Attributor.h:743
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:690
IRPosition stripCallBaseContext() const
Return the same position without the call base context.
Definition Attributor.h:933
unsigned getNumArgs() const
Return the number of arguments associated with this function or call site scope.
Definition Attributor.h:869
Kind getPositionKind() const
Return the associated position kind.
Definition Attributor.h:890
bool isArgumentPosition() const
Return true if the position is an argument or call site argument.
Definition Attributor.h:922
static const IRPosition callsite_function(const CallBase &CB)
Create a position describing the function scope of CB.
Definition Attributor.h:657
IRPosition()
Default constructor available to create invalid positions implicitly.
Definition Attributor.h:615
Function * getAnchorScope() const
Return the Function surrounding the anchor value.
Definition Attributor.h:766
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.
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.
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.
DenseMap< unsigned, InstructionVectorTy * > OpcodeInstMapTy
A map type from opcodes to instructions with this opcode.
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 isOnlyUsedByAssume(const Instruction &I) const
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
See AbstractState::isAtFixpoint()
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
See AbstractState::isValidState()
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
See AbstractState::indicatePessimisticFixpoint(...)
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
See AbstractState::indicateOptimisticFixpoint(...)
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
See AbstractState::isValidState() NOTE: For now we simply pretend that the worst possible state is in...
virtual void handleNewAssumedValue(base_t Value)=0
Handle a new assumed value Value. Subtype dependent.
bool isAtFixpoint() const override
See AbstractState::isAtFixpoint()
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
See AbstractState::indicateOptimisticFixpoint(...)
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
See AbstractState::indicatePessimisticFixpoint(...)
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 contains(const MemberTy &V) const
bool isAtFixpoint() const override
See AbstractState::isAtFixpoint(...)
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
See AbstractState::indicatePessimisticFixpoint(...)
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
See AbstractState::isValidState(...)
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
See AbstractState::indicateOptimisticFixpoint(...)
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
See AbstractState::isValidState()
bool isAtFixpoint() const override
See AbstractState::isAtFixpoint()
const SetContents & getAssumed() const
Return the assumed state encoding.
const SetContents & getKnown() const
Return the known state encoding.
ChangeStatus indicateOptimisticFixpoint() override
See AbstractState::indicateOptimisticFixpoint(...)
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
See AbstractState::indicatePessimisticFixpoint(...)
Helper to tie a abstract state implementation to an abstract attribute.
StateType & getState() override
See AbstractAttribute::getState(...).
StateTy StateType
Provide static access to the type of the state.
StateWrapper(const IRPosition &IRP, Ts... Args)
const StateType & getState() const override
See AbstractAttribute::getState(...).
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
See AbstractState::indicateOptimisticFixpoint(...)
ValueSimplifyStateType operator^=(const ValueSimplifyStateType &VS)
"Clamp" this state with PVS.
ChangeStatus indicatePessimisticFixpoint() override
See AbstractState::indicatePessimisticFixpoint(...)
static ValueSimplifyStateType getBestState(Type *Ty)
bool isAtFixpoint() const override
See AbstractState::isAtFixpoint(...)
bool isValidState() const override
See AbstractState::isValidState(...)
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