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) and TombstoneKey (INT64_MIN).
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 }
438 return Base::getTombstoneKey();
439 }
440 static unsigned getHashValue(const AA::ValueAndContext &VAC) {
441 return Base::getHashValue(VAC);
442 }
443
444 static bool isEqual(const AA::ValueAndContext &LHS,
445 const AA::ValueAndContext &RHS) {
446 return Base::isEqual(LHS, RHS);
447 }
448};
449
450template <>
451struct DenseMapInfo<AA::ValueScope> : public DenseMapInfo<unsigned char> {
453 static inline AA::ValueScope getEmptyKey() {
454 return AA::ValueScope(Base::getEmptyKey());
455 }
457 return AA::ValueScope(Base::getTombstoneKey());
458 }
459 static unsigned getHashValue(const AA::ValueScope &S) {
460 return Base::getHashValue(S);
461 }
462
463 static bool isEqual(const AA::ValueScope &LHS, const AA::ValueScope &RHS) {
464 return Base::isEqual(LHS, RHS);
465 }
466};
467
468template <>
469struct DenseMapInfo<const AA::InstExclusionSetTy *>
470 : public DenseMapInfo<void *> {
471 using super = DenseMapInfo<void *>;
472 static inline const AA::InstExclusionSetTy *getEmptyKey() {
473 return static_cast<const AA::InstExclusionSetTy *>(super::getEmptyKey());
474 }
475 static inline const AA::InstExclusionSetTy *getTombstoneKey() {
476 return static_cast<const AA::InstExclusionSetTy *>(
477 super::getTombstoneKey());
478 }
479 static unsigned getHashValue(const AA::InstExclusionSetTy *BES) {
480 unsigned H = 0;
481 if (BES)
482 for (const auto *II : *BES)
483 H += DenseMapInfo<const Instruction *>::getHashValue(II);
484 return H;
485 }
486 static bool isEqual(const AA::InstExclusionSetTy *LHS,
488 if (LHS == RHS)
489 return true;
490 if (LHS == getEmptyKey() || RHS == getEmptyKey() ||
491 LHS == getTombstoneKey() || RHS == getTombstoneKey())
492 return false;
493 auto SizeLHS = LHS ? LHS->size() : 0;
494 auto SizeRHS = RHS ? RHS->size() : 0;
495 if (SizeLHS != SizeRHS)
496 return false;
497 if (SizeRHS == 0)
498 return true;
499 return llvm::set_is_subset(*LHS, *RHS);
500 }
501};
502
503/// The value passed to the line option that defines the maximal initialization
504/// chain length.
506
507///{
512
517
518enum class DepClassTy {
519 REQUIRED, ///< The target cannot be valid if the source is not.
520 OPTIONAL, ///< The target may be valid if the source is not.
521 NONE, ///< Do not track a dependence between source and target.
522};
523///}
524
525/// The data structure for the nodes of a dependency graph
527public:
528 virtual ~AADepGraphNode() = default;
531
532protected:
533 /// Set of dependency graph nodes which should be updated if this one
534 /// is updated. The bit encodes if it is optional.
536
537 static AADepGraphNode *DepGetVal(const DepTy &DT) { return DT.getPointer(); }
540 }
541
542 operator AbstractAttribute *() { return cast<AbstractAttribute>(this); }
543
544public:
548
549 aaiterator begin() { return aaiterator(Deps.begin(), &DepGetValAA); }
550 aaiterator end() { return aaiterator(Deps.end(), &DepGetValAA); }
551 iterator child_begin() { return iterator(Deps.begin(), &DepGetVal); }
552 iterator child_end() { return iterator(Deps.end(), &DepGetVal); }
553
554 void print(raw_ostream &OS) const { print(nullptr, OS); }
555 virtual void print(Attributor *, raw_ostream &OS) const {
556 OS << "AADepNode Impl\n";
557 }
558 DepSetTy &getDeps() { return Deps; }
559
560 friend struct Attributor;
561 friend struct AADepGraph;
562};
563
564/// The data structure for the dependency graph
565///
566/// Note that in this graph if there is an edge from A to B (A -> B),
567/// then it means that B depends on A, and when the state of A is
568/// updated, node B should also be updated
570 AADepGraph() = default;
571 ~AADepGraph() = default;
572
574 static AADepGraphNode *DepGetVal(const DepTy &DT) { return DT.getPointer(); }
575 using iterator =
577
578 /// There is no root node for the dependency graph. But the SCCIterator
579 /// requires a single entry point, so we maintain a fake("synthetic") root
580 /// node that depends on every node.
583
584 iterator begin() { return SyntheticRoot.child_begin(); }
585 iterator end() { return SyntheticRoot.child_end(); }
586
587 LLVM_ABI void viewGraph();
588
589 /// Dump graph to file
590 LLVM_ABI void dumpGraph();
591
592 /// Print dependency graph
593 LLVM_ABI void print();
594};
595
596/// Helper to describe and deal with positions in the LLVM-IR.
597///
598/// A position in the IR is described by an anchor value and an "offset" that
599/// could be the argument number, for call sites and arguments, or an indicator
600/// of the "position kind". The kinds, specified in the Kind enum below, include
601/// the locations in the attribute list, i.a., function scope and return value,
602/// as well as a distinction between call sites and functions. Finally, there
603/// are floating values that do not have a corresponding attribute list
604/// position.
606 // NOTE: In the future this definition can be changed to support recursive
607 // functions.
609
610 /// The positions we distinguish in the IR.
611 enum Kind : char {
612 IRP_INVALID, ///< An invalid position.
613 IRP_FLOAT, ///< A position that is not associated with a spot suitable
614 ///< for attributes. This could be any value or instruction.
615 IRP_RETURNED, ///< An attribute for the function return value.
616 IRP_CALL_SITE_RETURNED, ///< An attribute for a call site return value.
617 IRP_FUNCTION, ///< An attribute for a function (scope).
618 IRP_CALL_SITE, ///< An attribute for a call site (function scope).
619 IRP_ARGUMENT, ///< An attribute for a function argument.
620 IRP_CALL_SITE_ARGUMENT, ///< An attribute for a call site argument.
621 };
622
623 /// Default constructor available to create invalid positions implicitly. All
624 /// other positions need to be created explicitly through the appropriate
625 /// static member function.
626 IRPosition() : Enc(nullptr, ENC_VALUE) { verify(); }
627
628 /// Create a position describing the value of \p V.
629 static const IRPosition value(const Value &V,
630 const CallBaseContext *CBContext = nullptr) {
631 if (auto *Arg = dyn_cast<Argument>(&V))
632 return IRPosition::argument(*Arg, CBContext);
633 if (auto *CB = dyn_cast<CallBase>(&V))
635 return IRPosition(const_cast<Value &>(V), IRP_FLOAT, CBContext);
636 }
637
638 /// Create a position describing the instruction \p I. This is different from
639 /// the value version because call sites are treated as intrusctions rather
640 /// than their return value in this function.
641 static const IRPosition inst(const Instruction &I,
642 const CallBaseContext *CBContext = nullptr) {
643 return IRPosition(const_cast<Instruction &>(I), IRP_FLOAT, CBContext);
644 }
645
646 /// Create a position describing the function scope of \p F.
647 /// \p CBContext is used for call base specific analysis.
648 static const IRPosition function(const Function &F,
649 const CallBaseContext *CBContext = nullptr) {
650 return IRPosition(const_cast<Function &>(F), IRP_FUNCTION, CBContext);
651 }
652
653 /// Create a position describing the returned value of \p F.
654 /// \p CBContext is used for call base specific analysis.
655 static const IRPosition returned(const Function &F,
656 const CallBaseContext *CBContext = nullptr) {
657 return IRPosition(const_cast<Function &>(F), IRP_RETURNED, CBContext);
658 }
659
660 /// Create a position describing the argument \p Arg.
661 /// \p CBContext is used for call base specific analysis.
662 static const IRPosition argument(const Argument &Arg,
663 const CallBaseContext *CBContext = nullptr) {
664 return IRPosition(const_cast<Argument &>(Arg), IRP_ARGUMENT, CBContext);
665 }
666
667 /// Create a position describing the function scope of \p CB.
668 static const IRPosition callsite_function(const CallBase &CB) {
669 return IRPosition(const_cast<CallBase &>(CB), IRP_CALL_SITE);
670 }
671
672 /// Create a position describing the returned value of \p CB.
673 static const IRPosition callsite_returned(const CallBase &CB) {
674 return IRPosition(const_cast<CallBase &>(CB), IRP_CALL_SITE_RETURNED);
675 }
676
677 /// Create a position describing the argument of \p CB at position \p ArgNo.
678 static const IRPosition callsite_argument(const CallBase &CB,
679 unsigned ArgNo) {
680 return IRPosition(const_cast<Use &>(CB.getArgOperandUse(ArgNo)),
682 }
683
684 /// Create a position describing the argument of \p ACS at position \p ArgNo.
686 unsigned ArgNo) {
687 if (ACS.getNumArgOperands() <= ArgNo)
688 return IRPosition();
689 int CSArgNo = ACS.getCallArgOperandNo(ArgNo);
690 if (CSArgNo >= 0)
692 cast<CallBase>(*ACS.getInstruction()), CSArgNo);
693 return IRPosition();
694 }
695
696 /// Create a position with function scope matching the "context" of \p IRP.
697 /// If \p IRP is a call site (see isAnyCallSitePosition()) then the result
698 /// will be a call site position, otherwise the function position of the
699 /// associated function.
700 static const IRPosition
702 const CallBaseContext *CBContext = nullptr) {
703 if (IRP.isAnyCallSitePosition()) {
706 }
708 return IRPosition::function(*IRP.getAssociatedFunction(), CBContext);
709 }
710
711 bool operator==(const IRPosition &RHS) const {
712 return Enc == RHS.Enc && RHS.CBContext == CBContext;
713 }
714 bool operator!=(const IRPosition &RHS) const { return !(*this == RHS); }
715
716 /// Return the value this abstract attribute is anchored with.
717 ///
718 /// The anchor value might not be the associated value if the latter is not
719 /// sufficient to determine where arguments will be manifested. This is, so
720 /// far, only the case for call site arguments as the value is not sufficient
721 /// to pinpoint them. Instead, we can use the call site as an anchor.
723 switch (getEncodingBits()) {
724 case ENC_VALUE:
725 case ENC_RETURNED_VALUE:
726 case ENC_FLOATING_FUNCTION:
727 return *getAsValuePtr();
728 case ENC_CALL_SITE_ARGUMENT_USE:
729 return *(getAsUsePtr()->getUser());
730 default:
731 llvm_unreachable("Unkown encoding!");
732 };
733 }
734
735 /// Return the associated function, if any.
737 if (auto *CB = dyn_cast<CallBase>(&getAnchorValue())) {
738 // We reuse the logic that associates callback calles to arguments of a
739 // call site here to identify the callback callee as the associated
740 // function.
741 if (Argument *Arg = getAssociatedArgument())
742 return Arg->getParent();
744 CB->getCalledOperand()->stripPointerCasts());
745 }
746 return getAnchorScope();
747 }
748
749 /// Return the associated argument, if any.
751
752 /// Return true if the position refers to a function interface, that is the
753 /// function scope, the function return, or an argument.
754 bool isFnInterfaceKind() const {
755 switch (getPositionKind()) {
759 return true;
760 default:
761 return false;
762 }
763 }
764
765 /// Return true if this is a function or call site position.
766 bool isFunctionScope() const {
767 switch (getPositionKind()) {
770 return true;
771 default:
772 return false;
773 };
774 }
775
776 /// Return the Function surrounding the anchor value.
778 Value &V = getAnchorValue();
779 if (isa<Function>(V))
780 return &cast<Function>(V);
781 if (isa<Argument>(V))
782 return cast<Argument>(V).getParent();
783 if (isa<Instruction>(V))
784 return cast<Instruction>(V).getFunction();
785 return nullptr;
786 }
787
788 /// Return the context instruction, if any.
790 Value &V = getAnchorValue();
791 if (auto *I = dyn_cast<Instruction>(&V))
792 return I;
793 if (auto *Arg = dyn_cast<Argument>(&V))
794 if (!Arg->getParent()->isDeclaration())
795 return &Arg->getParent()->getEntryBlock().front();
796 if (auto *F = dyn_cast<Function>(&V))
797 if (!F->isDeclaration())
798 return &(F->getEntryBlock().front());
799 return nullptr;
800 }
801
802 /// Return the value this abstract attribute is associated with.
805 return getAnchorValue();
806 assert(isa<CallBase>(&getAnchorValue()) && "Expected a call base!");
808 ->getArgOperand(getCallSiteArgNo());
809 }
810
811 /// Return the type this abstract attribute is associated with.
817
818 /// Return the callee argument number of the associated value if it is an
819 /// argument or call site argument, otherwise a negative value. In contrast to
820 /// `getCallSiteArgNo` this method will always return the "argument number"
821 /// from the perspective of the callee. This may not the same as the call site
822 /// if this is a callback call.
823 int getCalleeArgNo() const {
824 return getArgNo(/* CallbackCalleeArgIfApplicable */ true);
825 }
826
827 /// Return the call site argument number of the associated value if it is an
828 /// argument or call site argument, otherwise a negative value. In contrast to
829 /// `getCalleArgNo` this method will always return the "operand number" from
830 /// the perspective of the call site. This may not the same as the callee
831 /// perspective if this is a callback call.
832 int getCallSiteArgNo() const {
833 return getArgNo(/* CallbackCalleeArgIfApplicable */ false);
834 }
835
836 /// Return the index in the attribute list for this position.
837 unsigned getAttrIdx() const {
838 switch (getPositionKind()) {
841 break;
844 return AttributeList::FunctionIndex;
847 return AttributeList::ReturnIndex;
849 return getCalleeArgNo() + AttributeList::FirstArgIndex;
851 return getCallSiteArgNo() + AttributeList::FirstArgIndex;
852 }
854 "There is no attribute index for a floating or invalid position!");
855 }
856
857 /// Return the value attributes are attached to.
859 if (auto *CB = dyn_cast<CallBase>(&getAnchorValue()))
860 return CB;
861 return getAssociatedFunction();
862 }
863
864 /// Return the attributes associated with this function or call site scope.
865 AttributeList getAttrList() const {
866 if (auto *CB = dyn_cast<CallBase>(&getAnchorValue()))
867 return CB->getAttributes();
869 }
870
871 /// Update the attributes associated with this function or call site scope.
872 void setAttrList(const AttributeList &AttrList) const {
873 if (auto *CB = dyn_cast<CallBase>(&getAnchorValue()))
874 return CB->setAttributes(AttrList);
875 return getAssociatedFunction()->setAttributes(AttrList);
876 }
877
878 /// Return the number of arguments associated with this function or call site
879 /// scope.
880 unsigned getNumArgs() const {
883 "Only valid for function/call site positions!");
884 if (auto *CB = dyn_cast<CallBase>(&getAnchorValue()))
885 return CB->arg_size();
887 }
888
889 /// Return theargument \p ArgNo associated with this function or call site
890 /// scope.
891 Value *getArg(unsigned ArgNo) const {
894 "Only valid for function/call site positions!");
895 if (auto *CB = dyn_cast<CallBase>(&getAnchorValue()))
896 return CB->getArgOperand(ArgNo);
897 return getAssociatedFunction()->getArg(ArgNo);
898 }
899
900 /// Return the associated position kind.
902 char EncodingBits = getEncodingBits();
903 if (EncodingBits == ENC_CALL_SITE_ARGUMENT_USE)
905 if (EncodingBits == ENC_FLOATING_FUNCTION)
906 return IRP_FLOAT;
907
908 Value *V = getAsValuePtr();
909 if (!V)
910 return IRP_INVALID;
911 if (isa<Argument>(V))
912 return IRP_ARGUMENT;
913 if (isa<Function>(V))
914 return isReturnPosition(EncodingBits) ? IRP_RETURNED : IRP_FUNCTION;
915 if (isa<CallBase>(V))
916 return isReturnPosition(EncodingBits) ? IRP_CALL_SITE_RETURNED
918 return IRP_FLOAT;
919 }
920
922 switch (getPositionKind()) {
926 return true;
927 default:
928 return false;
929 }
930 }
931
932 /// Return true if the position is an argument or call site argument.
933 bool isArgumentPosition() const {
934 switch (getPositionKind()) {
937 return true;
938 default:
939 return false;
940 }
941 }
942
943 /// Return the same position without the call base context.
945 IRPosition Result = *this;
946 Result.CBContext = nullptr;
947 return Result;
948 }
949
950 /// Get the call base context from the position.
951 const CallBaseContext *getCallBaseContext() const { return CBContext; }
952
953 /// Check if the position has any call base context.
954 bool hasCallBaseContext() const { return CBContext != nullptr; }
955
956 /// Special DenseMap key values.
957 ///
958 ///{
961 ///}
962
963 /// Conversion into a void * to allow reuse of pointer hashing.
964 operator void *() const { return Enc.getOpaqueValue(); }
965
966private:
967 /// Private constructor for special values only!
968 explicit IRPosition(void *Ptr, const CallBaseContext *CBContext = nullptr)
969 : CBContext(CBContext) {
970 Enc.setFromOpaqueValue(Ptr);
971 }
972
973 /// IRPosition anchored at \p AnchorVal with kind/argument numbet \p PK.
974 explicit IRPosition(Value &AnchorVal, Kind PK,
975 const CallBaseContext *CBContext = nullptr)
976 : CBContext(CBContext) {
977 switch (PK) {
979 llvm_unreachable("Cannot create invalid IRP with an anchor value!");
980 break;
982 // Special case for floating functions.
983 if (isa<Function>(AnchorVal) || isa<CallBase>(AnchorVal))
984 Enc = {&AnchorVal, ENC_FLOATING_FUNCTION};
985 else
986 Enc = {&AnchorVal, ENC_VALUE};
987 break;
990 Enc = {&AnchorVal, ENC_VALUE};
991 break;
994 Enc = {&AnchorVal, ENC_RETURNED_VALUE};
995 break;
997 Enc = {&AnchorVal, ENC_VALUE};
998 break;
1001 "Cannot create call site argument IRP with an anchor value!");
1002 break;
1003 }
1004 verify();
1005 }
1006
1007 /// Return the callee argument number of the associated value if it is an
1008 /// argument or call site argument. See also `getCalleeArgNo` and
1009 /// `getCallSiteArgNo`.
1010 int getArgNo(bool CallbackCalleeArgIfApplicable) const {
1011 if (CallbackCalleeArgIfApplicable)
1012 if (Argument *Arg = getAssociatedArgument())
1013 return Arg->getArgNo();
1014 switch (getPositionKind()) {
1016 return cast<Argument>(getAsValuePtr())->getArgNo();
1018 Use &U = *getAsUsePtr();
1019 return cast<CallBase>(U.getUser())->getArgOperandNo(&U);
1020 }
1021 default:
1022 return -1;
1023 }
1024 }
1025
1026 /// IRPosition for the use \p U. The position kind \p PK needs to be
1027 /// IRP_CALL_SITE_ARGUMENT, the anchor value is the user, the associated value
1028 /// the used value.
1029 explicit IRPosition(Use &U, Kind PK) {
1031 "Use constructor is for call site arguments only!");
1032 Enc = {&U, ENC_CALL_SITE_ARGUMENT_USE};
1033 verify();
1034 }
1035
1036 /// Verify internal invariants.
1037 LLVM_ABI void verify();
1038
1039 /// Return the underlying pointer as Value *, valid for all positions but
1040 /// IRP_CALL_SITE_ARGUMENT.
1041 Value *getAsValuePtr() const {
1042 assert(getEncodingBits() != ENC_CALL_SITE_ARGUMENT_USE &&
1043 "Not a value pointer!");
1044 return reinterpret_cast<Value *>(Enc.getPointer());
1045 }
1046
1047 /// Return the underlying pointer as Use *, valid only for
1048 /// IRP_CALL_SITE_ARGUMENT positions.
1049 Use *getAsUsePtr() const {
1050 assert(getEncodingBits() == ENC_CALL_SITE_ARGUMENT_USE &&
1051 "Not a value pointer!");
1052 return reinterpret_cast<Use *>(Enc.getPointer());
1053 }
1054
1055 /// Return true if \p EncodingBits describe a returned or call site returned
1056 /// position.
1057 static bool isReturnPosition(char EncodingBits) {
1058 return EncodingBits == ENC_RETURNED_VALUE;
1059 }
1060
1061 /// Return true if the encoding bits describe a returned or call site returned
1062 /// position.
1063 bool isReturnPosition() const { return isReturnPosition(getEncodingBits()); }
1064
1065 /// The encoding of the IRPosition is a combination of a pointer and two
1066 /// encoding bits. The values of the encoding bits are defined in the enum
1067 /// below. The pointer is either a Value* (for the first three encoding bit
1068 /// combinations) or Use* (for ENC_CALL_SITE_ARGUMENT_USE).
1069 ///
1070 ///{
1071 enum {
1072 ENC_VALUE = 0b00,
1073 ENC_RETURNED_VALUE = 0b01,
1074 ENC_FLOATING_FUNCTION = 0b10,
1075 ENC_CALL_SITE_ARGUMENT_USE = 0b11,
1076 };
1077
1078 // Reserve the maximal amount of bits so there is no need to mask out the
1079 // remaining ones. We will not encode anything else in the pointer anyway.
1080 static constexpr int NumEncodingBits =
1082 static_assert(NumEncodingBits >= 2, "At least two bits are required!");
1083
1084 /// The pointer with the encoding bits.
1085 PointerIntPair<void *, NumEncodingBits, char> Enc;
1086 ///}
1087
1088 /// Call base context. Used for callsite specific analysis.
1089 const CallBaseContext *CBContext = nullptr;
1090
1091 /// Return the encoding bits.
1092 char getEncodingBits() const { return Enc.getInt(); }
1093};
1094
1095/// Helper that allows IRPosition as a key in a DenseMap.
1096template <> struct DenseMapInfo<IRPosition> {
1097 static inline IRPosition getEmptyKey() { return IRPosition::EmptyKey; }
1098 static inline IRPosition getTombstoneKey() {
1100 }
1101 static unsigned getHashValue(const IRPosition &IRP) {
1102 return (DenseMapInfo<void *>::getHashValue(IRP) << 4) ^
1104 }
1105
1106 static bool isEqual(const IRPosition &a, const IRPosition &b) {
1107 return a == b;
1108 }
1109};
1110
1111/// A visitor class for IR positions.
1112///
1113/// Given a position P, the SubsumingPositionIterator allows to visit "subsuming
1114/// positions" wrt. attributes/information. Thus, if a piece of information
1115/// holds for a subsuming position, it also holds for the position P.
1116///
1117/// The subsuming positions always include the initial position and then,
1118/// depending on the position kind, additionally the following ones:
1119/// - for IRP_RETURNED:
1120/// - the function (IRP_FUNCTION)
1121/// - for IRP_ARGUMENT:
1122/// - the function (IRP_FUNCTION)
1123/// - for IRP_CALL_SITE:
1124/// - the callee (IRP_FUNCTION), if known
1125/// - for IRP_CALL_SITE_RETURNED:
1126/// - the callee (IRP_RETURNED), if known
1127/// - the call site (IRP_FUNCTION)
1128/// - the callee (IRP_FUNCTION), if known
1129/// - for IRP_CALL_SITE_ARGUMENT:
1130/// - the argument of the callee (IRP_ARGUMENT), if known
1131/// - the callee (IRP_FUNCTION), if known
1132/// - the position the call site argument is associated with if it is not
1133/// anchored to the call site, e.g., if it is an argument then the argument
1134/// (IRP_ARGUMENT)
1136 SmallVector<IRPosition, 4> IRPositions;
1137 using iterator = decltype(IRPositions)::iterator;
1138
1139public:
1141 iterator begin() { return IRPositions.begin(); }
1142 iterator end() { return IRPositions.end(); }
1143};
1144
1145/// Wrapper for FunctionAnalysisManager.
1147 // The client may be running the old pass manager, in which case, we need to
1148 // map the requested Analysis to its equivalent wrapper in the old pass
1149 // manager. The scheme implemented here does not require every Analysis to be
1150 // updated. Only those new analyses that the client cares about in the old
1151 // pass manager need to expose a LegacyWrapper type, and that wrapper should
1152 // support a getResult() method that matches the new Analysis.
1153 //
1154 // We need SFINAE to check for the LegacyWrapper, but function templates don't
1155 // allow partial specialization, which is needed in this case. So instead, we
1156 // use a constexpr bool to perform the SFINAE, and then use this information
1157 // inside the function template.
1158 template <typename, typename = void>
1159 static constexpr bool HasLegacyWrapper = false;
1160
1161 template <typename Analysis>
1162 typename Analysis::Result *getAnalysis(const Function &F,
1163 bool RequestCachedOnly = false) {
1164 if (!LegacyPass && !FAM)
1165 return nullptr;
1166 if (FAM) {
1167 if (CachedOnly || RequestCachedOnly)
1168 return FAM->getCachedResult<Analysis>(const_cast<Function &>(F));
1169 return &FAM->getResult<Analysis>(const_cast<Function &>(F));
1170 }
1171 if constexpr (HasLegacyWrapper<Analysis>) {
1172 if (!CachedOnly && !RequestCachedOnly)
1173 return &LegacyPass
1174 ->getAnalysis<typename Analysis::LegacyWrapper>(
1175 const_cast<Function &>(F))
1176 .getResult();
1177 if (auto *P =
1178 LegacyPass
1179 ->getAnalysisIfAvailable<typename Analysis::LegacyWrapper>())
1180 return &P->getResult();
1181 }
1182 return nullptr;
1183 }
1184
1185 /// Invalidates the analyses. Valid only when using the new pass manager.
1187 assert(FAM && "Can only be used from the new PM!");
1188 FAM->clear();
1189 }
1190
1191 AnalysisGetter(FunctionAnalysisManager &FAM, bool CachedOnly = false)
1192 : FAM(&FAM), CachedOnly(CachedOnly) {}
1193 AnalysisGetter(Pass *P, bool CachedOnly = false)
1194 : LegacyPass(P), CachedOnly(CachedOnly) {}
1195 AnalysisGetter() = default;
1196
1197private:
1198 FunctionAnalysisManager *FAM = nullptr;
1199 Pass *LegacyPass = nullptr;
1200
1201 /// If \p CachedOnly is true, no pass is created, just existing results are
1202 /// used. Also available per request.
1203 bool CachedOnly = false;
1204};
1205
1206template <typename Analysis>
1208 Analysis, std::void_t<typename Analysis::LegacyWrapper>> = true;
1209
1210/// Data structure to hold cached (LLVM-IR) information.
1211///
1212/// All attributes are given an InformationCache object at creation time to
1213/// avoid inspection of the IR by all of them individually. This default
1214/// InformationCache will hold information required by 'default' attributes,
1215/// thus the ones deduced when Attributor::identifyDefaultAbstractAttributes(..)
1216/// is called.
1217///
1218/// If custom abstract attributes, registered manually through
1219/// Attributor::registerAA(...), need more information, especially if it is not
1220/// reusable, it is advised to inherit from the InformationCache and cast the
1221/// instance down in the abstract attributes.
1225 bool UseExplorer = true)
1226 : CGSCC(CGSCC), M(M), Allocator(Allocator), AG(AG) {
1227 if (UseExplorer)
1228 Explorer = new (Allocator) MustBeExecutedContextExplorer(
1229 /* ExploreInterBlock */
1230 true, /* ExploreCFGForward */ true,
1231 /* ExploreCFGBackward */ true,
1232 /* LIGetter */
1233 [&](const Function &F) { return AG.getAnalysis<LoopAnalysis>(F); },
1234 /* DTGetter */
1235 [&](const Function &F) {
1236 return AG.getAnalysis<DominatorTreeAnalysis>(F);
1237 },
1238 /* PDTGetter */
1239 [&](const Function &F) {
1240 return AG.getAnalysis<PostDominatorTreeAnalysis>(F);
1241 });
1242 }
1243
1245 // The FunctionInfo objects are allocated via a BumpPtrAllocator, we call
1246 // the destructor manually.
1247 for (auto &It : FuncInfoMap)
1248 It.getSecond()->~FunctionInfo();
1249 // Same is true for the instruction exclusions sets.
1251 for (auto *BES : BESets)
1252 BES->~InstExclusionSetTy();
1253 if (Explorer)
1254 Explorer->~MustBeExecutedContextExplorer();
1255 }
1256
1257 /// Apply \p CB to all uses of \p F. If \p LookThroughConstantExprUses is
1258 /// true, constant expression users are not given to \p CB but their uses are
1259 /// traversed transitively.
1260 template <typename CBTy>
1261 static void foreachUse(Function &F, CBTy CB,
1262 bool LookThroughConstantExprUses = true) {
1263 SmallVector<Use *, 8> Worklist(make_pointer_range(F.uses()));
1264
1265 for (unsigned Idx = 0; Idx < Worklist.size(); ++Idx) {
1266 Use &U = *Worklist[Idx];
1267
1268 // Allow use in constant bitcasts and simply look through them.
1269 if (LookThroughConstantExprUses && isa<ConstantExpr>(U.getUser())) {
1270 for (Use &CEU : cast<ConstantExpr>(U.getUser())->uses())
1271 Worklist.push_back(&CEU);
1272 continue;
1273 }
1274
1275 CB(U);
1276 }
1277 }
1278
1279 /// The CG-SCC the pass is run on, or nullptr if it is a module pass.
1280 const SetVector<Function *> *const CGSCC = nullptr;
1281
1282 /// A vector type to hold instructions.
1284
1285 /// A map type from opcodes to instructions with this opcode.
1287
1288 /// Return the map that relates "interesting" opcodes with all instructions
1289 /// with that opcode in \p F.
1291 return getFunctionInfo(F).OpcodeInstMap;
1292 }
1293
1294 /// Return the instructions in \p F that may read or write memory.
1296 return getFunctionInfo(F).RWInsts;
1297 }
1298
1299 /// Return MustBeExecutedContextExplorer
1303
1304 /// Return TargetLibraryInfo for function \p F.
1308
1309 /// Return true if \p F has the "kernel" function attribute
1310 bool isKernel(const Function &F) {
1311 FunctionInfo &FI = getFunctionInfo(F);
1312 return FI.IsKernel;
1313 }
1314
1315 /// Return true if \p Arg is involved in a must-tail call, thus the argument
1316 /// of the caller or callee.
1318 FunctionInfo &FI = getFunctionInfo(*Arg.getParent());
1319 return FI.CalledViaMustTail || FI.ContainsMustTailCall;
1320 }
1321
1322 bool isOnlyUsedByAssume(const Instruction &I) const {
1323 return AssumeOnlyValues.contains(&I);
1324 }
1325
1326 /// Invalidates the cached analyses. Valid only when using the new pass
1327 /// manager.
1328 void invalidateAnalyses() { AG.invalidateAnalyses(); }
1329
1330 /// Return the analysis result from a pass \p AP for function \p F.
1331 template <typename AP>
1332 typename AP::Result *getAnalysisResultForFunction(const Function &F,
1333 bool CachedOnly = false) {
1334 return AG.getAnalysis<AP>(F, CachedOnly);
1335 }
1336
1337 const Module &getModule() const { return M; }
1338
1339 /// Return datalayout used in the module.
1340 const DataLayout &getDL() const { return M.getDataLayout(); }
1341
1342 /// Return the map conaining all the knowledge we have from `llvm.assume`s.
1343 const RetainedKnowledgeMap &getKnowledgeMap() const { return KnowledgeMap; }
1344
1345 /// Given \p BES, return a uniqued version.
1348 auto It = BESets.find(BES);
1349 if (It != BESets.end())
1350 return *It;
1351 auto *UniqueBES = new (Allocator) AA::InstExclusionSetTy(*BES);
1352 bool Success = BESets.insert(UniqueBES).second;
1353 (void)Success;
1354 assert(Success && "Expected only new entries to be added");
1355 return UniqueBES;
1356 }
1357
1358 /// Return true if the stack (llvm::Alloca) can be accessed by other threads.
1360
1361 /// Return true if the target is a GPU.
1362 bool IsTargetGPU() const { return M.getTargetTriple().isGPU(); }
1363
1364 /// Return all functions that might be called indirectly, only valid for
1365 /// closed world modules (see isClosedWorldModule).
1368
1369 /// Return the flat address space if the associated target has.
1370 LLVM_ABI std::optional<unsigned> getFlatAddressSpace() const;
1371
1372 virtual unsigned getMaxAddrSpace() const { return ~0U; }
1373
1374private:
1375 struct FunctionInfo {
1376 LLVM_ABI ~FunctionInfo();
1377
1378 /// A nested map that remembers all instructions in a function with a
1379 /// certain instruction opcode (Instruction::getOpcode()).
1380 OpcodeInstMapTy OpcodeInstMap;
1381
1382 /// A map from functions to their instructions that may read or write
1383 /// memory.
1384 InstructionVectorTy RWInsts;
1385
1386 /// Function is called by a `musttail` call.
1387 bool CalledViaMustTail;
1388
1389 /// Function contains a `musttail` call.
1390 bool ContainsMustTailCall;
1391
1392 /// Function has the `"kernel"` attribute
1393 bool IsKernel;
1394 };
1395
1396 /// A map type from functions to informatio about it.
1397 DenseMap<const Function *, FunctionInfo *> FuncInfoMap;
1398
1399 /// Return information about the function \p F, potentially by creating it.
1400 FunctionInfo &getFunctionInfo(const Function &F) {
1401 FunctionInfo *&FI = FuncInfoMap[&F];
1402 if (!FI) {
1403 FI = new (Allocator) FunctionInfo();
1404 initializeInformationCache(F, *FI);
1405 }
1406 return *FI;
1407 }
1408
1409 /// Vector of functions that might be callable indirectly, i.a., via a
1410 /// function pointer.
1411 SmallVector<Function *> IndirectlyCallableFunctions;
1412
1413 /// Initialize the function information cache \p FI for the function \p F.
1414 ///
1415 /// This method needs to be called for all function that might be looked at
1416 /// through the information cache interface *prior* to looking at them.
1417 LLVM_ABI void initializeInformationCache(const Function &F, FunctionInfo &FI);
1418
1419 /// The module.
1420 const Module &M;
1421
1422 /// The allocator used to allocate memory, e.g. for `FunctionInfo`s.
1423 BumpPtrAllocator &Allocator;
1424
1425 /// MustBeExecutedContextExplorer
1426 MustBeExecutedContextExplorer *Explorer = nullptr;
1427
1428 /// A map with knowledge retained in `llvm.assume` instructions.
1429 RetainedKnowledgeMap KnowledgeMap;
1430
1431 /// A container for all instructions that are only used by `llvm.assume`.
1432 SetVector<const Instruction *> AssumeOnlyValues;
1433
1434 /// Cache for block sets to allow reuse.
1435 DenseSet<const AA::InstExclusionSetTy *> BESets;
1436
1437 /// Getters for analysis.
1438 AnalysisGetter &AG;
1439
1440 /// Set of inlineable functions
1441 SmallPtrSet<const Function *, 8> InlineableFunctions;
1442
1443 /// Give the Attributor access to the members so
1444 /// Attributor::identifyDefaultAbstractAttributes(...) can initialize them.
1445 friend struct Attributor;
1446};
1447
1448/// Configuration for the Attributor.
1450
1452
1453 /// Is the user of the Attributor a module pass or not. This determines what
1454 /// IR we can look at and modify. If it is a module pass we might deduce facts
1455 /// outside the initial function set and modify functions outside that set,
1456 /// but only as part of the optimization of the functions in the initial
1457 /// function set. For CGSCC passes we can look at the IR of the module slice
1458 /// but never run any deduction, or perform any modification, outside the
1459 /// initial function set (which we assume is the SCC).
1460 bool IsModulePass = true;
1461
1462 /// Flag to determine if we can delete functions or keep dead ones around.
1463 bool DeleteFns = true;
1464
1465 /// Flag to determine if we rewrite function signatures.
1467
1468 /// Flag to determine if we want to initialize all default AAs for an internal
1469 /// function marked live. See also: InitializationCallback>
1471
1472 /// Flag to determine if we should skip all liveness checks early on.
1473 bool UseLiveness = true;
1474
1475 /// Flag to indicate if the entire world is contained in this module, that
1476 /// is, no outside functions exist.
1478
1479 /// Callback function to be invoked on internal functions marked live.
1480 std::function<void(Attributor &A, const Function &F)> InitializationCallback =
1481 nullptr;
1482
1483 /// Callback function to determine if an indirect call targets should be made
1484 /// direct call targets (with an if-cascade).
1485 std::function<bool(Attributor &A, const AbstractAttribute &AA, CallBase &CB,
1486 Function &AssumedCallee, unsigned NumAssumedCallees)>
1488
1489 /// Helper to update an underlying call graph and to delete functions.
1491
1492 /// If not null, a set limiting the attribute opportunities.
1494
1495 /// Maximum number of iterations to run until fixpoint.
1496 std::optional<unsigned> MaxFixpointIterations;
1497
1498 /// A callback function that returns an ORE object from a Function pointer.
1499 ///{
1503 ///}
1504
1505 /// The name of the pass running the attributor, used to emit remarks.
1506 const char *PassName = nullptr;
1507
1508 using IPOAmendableCBTy = std::function<bool(const Function &F)>;
1510};
1511
1512/// A debug counter to limit the number of AAs created.
1513DEBUG_COUNTER(NumAbstractAttributes, "num-abstract-attributes",
1514 "How many AAs should be initialized");
1515
1516/// The fixpoint analysis framework that orchestrates the attribute deduction.
1517///
1518/// The Attributor provides a general abstract analysis framework (guided
1519/// fixpoint iteration) as well as helper functions for the deduction of
1520/// (LLVM-IR) attributes. However, also other code properties can be deduced,
1521/// propagated, and ultimately manifested through the Attributor framework. This
1522/// is particularly useful if these properties interact with attributes and a
1523/// co-scheduled deduction allows to improve the solution. Even if not, thus if
1524/// attributes/properties are completely isolated, they should use the
1525/// Attributor framework to reduce the number of fixpoint iteration frameworks
1526/// in the code base. Note that the Attributor design makes sure that isolated
1527/// attributes are not impacted, in any way, by others derived at the same time
1528/// if there is no cross-reasoning performed.
1529///
1530/// The public facing interface of the Attributor is kept simple and basically
1531/// allows abstract attributes to one thing, query abstract attributes
1532/// in-flight. There are two reasons to do this:
1533/// a) The optimistic state of one abstract attribute can justify an
1534/// optimistic state of another, allowing to framework to end up with an
1535/// optimistic (=best possible) fixpoint instead of one based solely on
1536/// information in the IR.
1537/// b) This avoids reimplementing various kinds of lookups, e.g., to check
1538/// for existing IR attributes, in favor of a single lookups interface
1539/// provided by an abstract attribute subclass.
1540///
1541/// NOTE: The mechanics of adding a new "concrete" abstract attribute are
1542/// described in the file comment.
1544
1545 /// Constructor
1546 ///
1547 /// \param Functions The set of functions we are deriving attributes for.
1548 /// \param InfoCache Cache to hold various information accessible for
1549 /// the abstract attributes.
1550 /// \param Configuration The Attributor configuration which determines what
1551 /// generic features to use.
1553 InformationCache &InfoCache,
1554 AttributorConfig Configuration);
1555
1557
1558 /// Run the analyses until a fixpoint is reached or enforced (timeout).
1559 ///
1560 /// The attributes registered with this Attributor can be used after as long
1561 /// as the Attributor is not destroyed (it owns the attributes now).
1562 ///
1563 /// \Returns CHANGED if the IR was changed, otherwise UNCHANGED.
1565
1566 /// Lookup an abstract attribute of type \p AAType at position \p IRP. While
1567 /// no abstract attribute is found equivalent positions are checked, see
1568 /// SubsumingPositionIterator. Thus, the returned abstract attribute
1569 /// might be anchored at a different position, e.g., the callee if \p IRP is a
1570 /// call base.
1571 ///
1572 /// This method is the only (supported) way an abstract attribute can retrieve
1573 /// information from another abstract attribute. As an example, take an
1574 /// abstract attribute that determines the memory access behavior for a
1575 /// argument (readnone, readonly, ...). It should use `getAAFor` to get the
1576 /// most optimistic information for other abstract attributes in-flight, e.g.
1577 /// the one reasoning about the "captured" state for the argument or the one
1578 /// reasoning on the memory access behavior of the function as a whole.
1579 ///
1580 /// If the DepClass enum is set to `DepClassTy::None` the dependence from
1581 /// \p QueryingAA to the return abstract attribute is not automatically
1582 /// recorded. This should only be used if the caller will record the
1583 /// dependence explicitly if necessary, thus if it the returned abstract
1584 /// attribute is used for reasoning. To record the dependences explicitly use
1585 /// the `Attributor::recordDependence` method.
1586 template <typename AAType>
1587 const AAType *getAAFor(const AbstractAttribute &QueryingAA,
1588 const IRPosition &IRP, DepClassTy DepClass) {
1589 return getOrCreateAAFor<AAType>(IRP, &QueryingAA, DepClass,
1590 /* ForceUpdate */ false);
1591 }
1592
1593 /// The version of getAAFor that allows to omit a querying abstract
1594 /// attribute. Using this after Attributor started running is restricted to
1595 /// only the Attributor itself. Initial seeding of AAs can be done via this
1596 /// function.
1597 /// NOTE: ForceUpdate is ignored in any stage other than the update stage.
1598 template <typename AAType>
1599 const AAType *getOrCreateAAFor(IRPosition IRP,
1600 const AbstractAttribute *QueryingAA,
1601 DepClassTy DepClass, bool ForceUpdate = false,
1602 bool UpdateAfterInit = true) {
1603 if (!shouldPropagateCallBaseContext(IRP))
1604 IRP = IRP.stripCallBaseContext();
1605
1606 if (AAType *AAPtr = lookupAAFor<AAType>(IRP, QueryingAA, DepClass,
1607 /* AllowInvalidState */ true)) {
1608 if (ForceUpdate && Phase == AttributorPhase::UPDATE)
1609 updateAA(*AAPtr);
1610 return AAPtr;
1611 }
1612
1613 bool ShouldUpdateAA;
1614 if (!shouldInitialize<AAType>(IRP, ShouldUpdateAA))
1615 return nullptr;
1616
1617 if (!DebugCounter::shouldExecute(NumAbstractAttributes))
1618 return nullptr;
1619
1620 // No matching attribute found, create one.
1621 // Use the static create method.
1622 auto &AA = AAType::createForPosition(IRP, *this);
1623
1624 // Always register a new attribute to make sure we clean up the allocated
1625 // memory properly.
1626 registerAA(AA);
1627
1628 // If we are currenty seeding attributes, enforce seeding rules.
1629 if (Phase == AttributorPhase::SEEDING && !shouldSeedAttribute(AA)) {
1630 AA.getState().indicatePessimisticFixpoint();
1631 return &AA;
1632 }
1633
1634 // Bootstrap the new attribute with an initial update to propagate
1635 // information, e.g., function -> call site.
1636 {
1637 TimeTraceScope TimeScope("initialize", [&]() {
1638 return AA.getName().str() +
1639 std::to_string(AA.getIRPosition().getPositionKind());
1640 });
1641 ++InitializationChainLength;
1642 AA.initialize(*this);
1643 --InitializationChainLength;
1644 }
1645
1646 if (!ShouldUpdateAA) {
1647 AA.getState().indicatePessimisticFixpoint();
1648 return &AA;
1649 }
1650
1651 // Allow seeded attributes to declare dependencies.
1652 // Remember the seeding state.
1653 if (UpdateAfterInit) {
1654 AttributorPhase OldPhase = Phase;
1655 Phase = AttributorPhase::UPDATE;
1656
1657 updateAA(AA);
1658
1659 Phase = OldPhase;
1660 }
1661
1662 if (QueryingAA && AA.getState().isValidState())
1663 recordDependence(AA, const_cast<AbstractAttribute &>(*QueryingAA),
1664 DepClass);
1665 return &AA;
1666 }
1667
1668 template <typename AAType>
1669 const AAType *getOrCreateAAFor(const IRPosition &IRP) {
1670 return getOrCreateAAFor<AAType>(IRP, /* QueryingAA */ nullptr,
1672 }
1673
1674 /// Return the attribute of \p AAType for \p IRP if existing and valid. This
1675 /// also allows non-AA users lookup.
1676 template <typename AAType>
1677 AAType *lookupAAFor(const IRPosition &IRP,
1678 const AbstractAttribute *QueryingAA = nullptr,
1680 bool AllowInvalidState = false) {
1681 static_assert(std::is_base_of<AbstractAttribute, AAType>::value,
1682 "Cannot query an attribute with a type not derived from "
1683 "'AbstractAttribute'!");
1684 // Lookup the abstract attribute of type AAType. If found, return it after
1685 // registering a dependence of QueryingAA on the one returned attribute.
1686 AbstractAttribute *AAPtr = AAMap.lookup({&AAType::ID, IRP});
1687 if (!AAPtr)
1688 return nullptr;
1689
1690 AAType *AA = static_cast<AAType *>(AAPtr);
1691
1692 // Do not register a dependence on an attribute with an invalid state.
1693 if (DepClass != DepClassTy::NONE && QueryingAA &&
1694 AA->getState().isValidState())
1695 recordDependence(*AA, const_cast<AbstractAttribute &>(*QueryingAA),
1696 DepClass);
1697
1698 // Return nullptr if this attribute has an invalid state.
1699 if (!AllowInvalidState && !AA->getState().isValidState())
1700 return nullptr;
1701 return AA;
1702 }
1703
1704 /// Allows a query AA to request an update if a new query was received.
1706
1707 /// Explicitly record a dependence from \p FromAA to \p ToAA, that is if
1708 /// \p FromAA changes \p ToAA should be updated as well.
1709 ///
1710 /// This method should be used in conjunction with the `getAAFor` method and
1711 /// with the DepClass enum passed to the method set to None. This can
1712 /// be beneficial to avoid false dependences but it requires the users of
1713 /// `getAAFor` to explicitly record true dependences through this method.
1714 /// The \p DepClass flag indicates if the dependence is striclty necessary.
1715 /// That means for required dependences, if \p FromAA changes to an invalid
1716 /// state, \p ToAA can be moved to a pessimistic fixpoint because it required
1717 /// information from \p FromAA but none are available anymore.
1718 LLVM_ABI void recordDependence(const AbstractAttribute &FromAA,
1719 const AbstractAttribute &ToAA,
1720 DepClassTy DepClass);
1721
1722 /// Introduce a new abstract attribute into the fixpoint analysis.
1723 ///
1724 /// Note that ownership of the attribute is given to the Attributor. It will
1725 /// invoke delete for the Attributor on destruction of the Attributor.
1726 ///
1727 /// Attributes are identified by their IR position (AAType::getIRPosition())
1728 /// and the address of their static member (see AAType::ID).
1729 template <typename AAType> AAType &registerAA(AAType &AA) {
1730 static_assert(std::is_base_of<AbstractAttribute, AAType>::value,
1731 "Cannot register an attribute with a type not derived from "
1732 "'AbstractAttribute'!");
1733 // Put the attribute in the lookup map structure and the container we use to
1734 // keep track of all attributes.
1735 const IRPosition &IRP = AA.getIRPosition();
1736 AbstractAttribute *&AAPtr = AAMap[{&AAType::ID, IRP}];
1737
1738 assert(!AAPtr && "Attribute already in map!");
1739 AAPtr = &AA;
1740
1741 // Register AA with the synthetic root only before the manifest stage.
1742 if (Phase == AttributorPhase::SEEDING || Phase == AttributorPhase::UPDATE)
1743 DG.SyntheticRoot.Deps.insert(
1745
1746 return AA;
1747 }
1748
1749 /// Return the internal information cache.
1750 InformationCache &getInfoCache() { return InfoCache; }
1751
1752 /// Return the module.
1753 const Module &getModule() { return InfoCache.getModule(); }
1754
1755 /// Return true if this is a module pass, false otherwise.
1756 bool isModulePass() const { return Configuration.IsModulePass; }
1757
1758 /// Return true if we should specialize the call site \b CB for the potential
1759 /// callee \p Fn.
1761 CallBase &CB, Function &Callee,
1762 unsigned NumAssumedCallees) {
1763 return Configuration.IndirectCalleeSpecializationCallback
1764 ? Configuration.IndirectCalleeSpecializationCallback(
1765 *this, AA, CB, Callee, NumAssumedCallees)
1766 : true;
1767 }
1768
1769 /// Return true if the module contains the whole world, thus, no outside
1770 /// functions exist.
1771 LLVM_ABI bool isClosedWorldModule() const;
1772
1773 /// Return true if we derive attributes for \p Fn
1774 bool isRunOn(Function &Fn) const { return isRunOn(&Fn); }
1775 bool isRunOn(Function *Fn) const {
1776 return Functions.empty() || Functions.count(Fn);
1777 }
1778
1779 template <typename AAType> bool shouldUpdateAA(const IRPosition &IRP) {
1780 // If this is queried in the manifest stage, we force the AA to indicate
1781 // pessimistic fixpoint immediately.
1782 if (Phase == AttributorPhase::MANIFEST || Phase == AttributorPhase::CLEANUP)
1783 return false;
1784
1785 Function *AssociatedFn = IRP.getAssociatedFunction();
1786
1787 if (IRP.isAnyCallSitePosition()) {
1788 // Check if we require a callee but there is none.
1789 if (!AssociatedFn && AAType::requiresCalleeForCallBase())
1790 return false;
1791
1792 // Check if we require non-asm but it is inline asm.
1793 if (AAType::requiresNonAsmForCallBase() &&
1794 cast<CallBase>(IRP.getAnchorValue()).isInlineAsm())
1795 return false;
1796 }
1797
1798 // Check if we require a calles but we can't see all.
1799 if (AAType::requiresCallersForArgOrFunction())
1802 if (!AssociatedFn->hasLocalLinkage())
1803 return false;
1804
1805 if (!AAType::isValidIRPositionForUpdate(*this, IRP))
1806 return false;
1807
1808 // We update only AAs associated with functions in the Functions set or
1809 // call sites of them.
1810 return (!AssociatedFn || isModulePass() || isRunOn(AssociatedFn) ||
1811 isRunOn(IRP.getAnchorScope()));
1812 }
1813
1814 template <typename AAType>
1815 bool shouldInitialize(const IRPosition &IRP, bool &ShouldUpdateAA) {
1816 if (!AAType::isValidIRPositionForInit(*this, IRP))
1817 return false;
1818
1819 if (Configuration.Allowed && !Configuration.Allowed->count(&AAType::ID))
1820 return false;
1821
1822 // For now we skip anything in naked and optnone functions.
1823 const Function *AnchorFn = IRP.getAnchorScope();
1824 if (AnchorFn && (AnchorFn->hasFnAttribute(Attribute::Naked) ||
1825 AnchorFn->hasFnAttribute(Attribute::OptimizeNone)))
1826 return false;
1827
1828 // Avoid too many nested initializations to prevent a stack overflow.
1829 if (InitializationChainLength > MaxInitializationChainLength)
1830 return false;
1831
1832 ShouldUpdateAA = shouldUpdateAA<AAType>(IRP);
1833
1834 return !AAType::hasTrivialInitializer() || ShouldUpdateAA;
1835 }
1836
1837 /// Determine opportunities to derive 'default' attributes in \p F and create
1838 /// abstract attribute objects for them.
1839 ///
1840 /// \param F The function that is checked for attribute opportunities.
1841 ///
1842 /// Note that abstract attribute instances are generally created even if the
1843 /// IR already contains the information they would deduce. The most important
1844 /// reason for this is the single interface, the one of the abstract attribute
1845 /// instance, which can be queried without the need to look at the IR in
1846 /// various places.
1848
1849 /// Determine whether the function \p F is IPO amendable
1850 ///
1851 /// If a function is exactly defined or it has alwaysinline attribute
1852 /// and is viable to be inlined, we say it is IPO amendable
1854 return F.hasExactDefinition() || InfoCache.InlineableFunctions.count(&F) ||
1855 (Configuration.IPOAmendableCB && Configuration.IPOAmendableCB(F));
1856 }
1857
1858 /// Mark the internal function \p F as live.
1859 ///
1860 /// This will trigger the identification and initialization of attributes for
1861 /// \p F.
1863 assert(F.hasLocalLinkage() &&
1864 "Only local linkage is assumed dead initially.");
1865
1866 if (Configuration.DefaultInitializeLiveInternals)
1868 if (Configuration.InitializationCallback)
1869 Configuration.InitializationCallback(*this, F);
1870 }
1871
1872 /// Record that \p U is to be replaces with \p NV after information was
1873 /// manifested. This also triggers deletion of trivially dead istructions.
1875 Value *&V = ToBeChangedUses[&U];
1876 if (V && (V->stripPointerCasts() == NV.stripPointerCasts() ||
1878 return false;
1879 assert((!V || V == &NV || isa<UndefValue>(NV)) &&
1880 "Use was registered twice for replacement with different values!");
1881 V = &NV;
1882 return true;
1883 }
1884
1885 /// Helper function to replace all uses associated with \p IRP with \p NV.
1886 /// Return true if there is any change. The flag \p ChangeDroppable indicates
1887 /// if dropppable uses should be changed too.
1889 bool ChangeDroppable = true) {
1891 auto *CB = cast<CallBase>(IRP.getCtxI());
1893 CB->getArgOperandUse(IRP.getCallSiteArgNo()), NV);
1894 }
1895 Value &V = IRP.getAssociatedValue();
1896 auto &Entry = ToBeChangedValues[&V];
1897 Value *CurNV = get<0>(Entry);
1898 if (CurNV && (CurNV->stripPointerCasts() == NV.stripPointerCasts() ||
1899 isa<UndefValue>(CurNV)))
1900 return false;
1901 assert((!CurNV || CurNV == &NV || isa<UndefValue>(NV)) &&
1902 "Value replacement was registered twice with different values!");
1903 Entry = {&NV, ChangeDroppable};
1904 return true;
1905 }
1906
1907 /// Record that \p I is to be replaced with `unreachable` after information
1908 /// was manifested.
1910 ToBeChangedToUnreachableInsts.insert(I);
1911 }
1912
1913 /// Record that \p II has at least one dead successor block. This information
1914 /// is used, e.g., to replace \p II with a call, after information was
1915 /// manifested.
1917 InvokeWithDeadSuccessor.insert(&II);
1918 }
1919
1920 /// Record that \p I is deleted after information was manifested. This also
1921 /// triggers deletion of trivially dead istructions.
1922 void deleteAfterManifest(Instruction &I) { ToBeDeletedInsts.insert(&I); }
1923
1924 /// Record that \p BB is deleted after information was manifested. This also
1925 /// triggers deletion of trivially dead istructions.
1926 void deleteAfterManifest(BasicBlock &BB) { ToBeDeletedBlocks.insert(&BB); }
1927
1928 // Record that \p BB is added during the manifest of an AA. Added basic blocks
1929 // are preserved in the IR.
1931 ManifestAddedBlocks.insert(&BB);
1932 }
1933
1934 /// Record that \p F is deleted after information was manifested.
1936 if (Configuration.DeleteFns)
1937 ToBeDeletedFunctions.insert(&F);
1938 }
1939
1940 /// Return the attributes of kind \p AK existing in the IR as operand bundles
1941 /// of an llvm.assume.
1942 LLVM_ABI bool getAttrsFromAssumes(const IRPosition &IRP,
1945
1946 /// Return true if any kind in \p AKs existing in the IR at a position that
1947 /// will affect this one. See also getAttrs(...).
1948 /// \param IgnoreSubsumingPositions Flag to determine if subsuming positions,
1949 /// e.g., the function position if this is an
1950 /// argument position, should be ignored.
1951 LLVM_ABI bool
1953 bool IgnoreSubsumingPositions = false,
1954 Attribute::AttrKind ImpliedAttributeKind = Attribute::None);
1955
1956 /// Return the attributes of any kind in \p AKs existing in the IR at a
1957 /// position that will affect this one. While each position can only have a
1958 /// single attribute of any kind in \p AKs, there are "subsuming" positions
1959 /// that could have an attribute as well. This method returns all attributes
1960 /// found in \p Attrs.
1961 /// \param IgnoreSubsumingPositions Flag to determine if subsuming positions,
1962 /// e.g., the function position if this is an
1963 /// argument position, should be ignored.
1964 LLVM_ABI void getAttrs(const IRPosition &IRP,
1967 bool IgnoreSubsumingPositions = false);
1968
1969 /// Remove all \p AttrKinds attached to \p IRP.
1973 ArrayRef<StringRef> Attrs);
1974
1975 /// Attach \p DeducedAttrs to \p IRP, if \p ForceReplace is set we do this
1976 /// even if the same attribute kind was already present.
1978 ArrayRef<Attribute> DeducedAttrs,
1979 bool ForceReplace = false);
1980
1981private:
1982 /// Helper to check \p Attrs for \p AK, if not found, check if \p
1983 /// AAType::isImpliedByIR is true, and if not, create AAType for \p IRP.
1984 /// If \p SkipHasAttrCheck is true, don't check whether the attribute is set
1985 /// first. This should be used if only some values of a complex IR attribute
1986 /// imply the AAType.
1987 template <Attribute::AttrKind AK, typename AAType>
1988 void checkAndQueryIRAttr(const IRPosition &IRP, AttributeSet Attrs,
1989 bool SkipHasAttrCheck = false);
1990
1991 /// Helper to apply \p CB on all attributes of type \p AttrDescs of \p IRP.
1992 template <typename DescTy>
1993 ChangeStatus updateAttrMap(const IRPosition &IRP, ArrayRef<DescTy> AttrDescs,
1994 function_ref<bool(const DescTy &, AttributeSet,
1995 AttributeMask &, AttrBuilder &)>
1996 CB);
1997
1998 /// Mapping from functions/call sites to their attributes.
2000
2001public:
2002 /// If \p IRP is assumed to be a constant, return it, if it is unclear yet,
2003 /// return std::nullopt, otherwise return `nullptr`.
2004 LLVM_ABI std::optional<Constant *>
2006 bool &UsedAssumedInformation);
2007 std::optional<Constant *> getAssumedConstant(const Value &V,
2008 const AbstractAttribute &AA,
2009 bool &UsedAssumedInformation) {
2010 return getAssumedConstant(IRPosition::value(V), AA, UsedAssumedInformation);
2011 }
2012
2013 /// If \p V is assumed simplified, return it, if it is unclear yet,
2014 /// return std::nullopt, otherwise return `nullptr`.
2015 std::optional<Value *> getAssumedSimplified(const IRPosition &IRP,
2016 const AbstractAttribute &AA,
2017 bool &UsedAssumedInformation,
2018 AA::ValueScope S) {
2019 return getAssumedSimplified(IRP, &AA, UsedAssumedInformation, S);
2020 }
2021 std::optional<Value *> getAssumedSimplified(const Value &V,
2022 const AbstractAttribute &AA,
2023 bool &UsedAssumedInformation,
2024 AA::ValueScope S) {
2026 UsedAssumedInformation, S);
2027 }
2028
2029 /// If \p V is assumed simplified, return it, if it is unclear yet,
2030 /// return std::nullopt, otherwise return `nullptr`. Same as the public
2031 /// version except that it can be used without recording dependences on any \p
2032 /// AA.
2033 LLVM_ABI std::optional<Value *>
2035 bool &UsedAssumedInformation, AA::ValueScope S);
2036
2037 /// Try to simplify \p IRP and in the scope \p S. If successful, true is
2038 /// returned and all potential values \p IRP can take are put into \p Values.
2039 /// If the result in \p Values contains select or PHI instructions it means
2040 /// those could not be simplified to a single value. Recursive calls with
2041 /// these instructions will yield their respective potential values. If false
2042 /// is returned no other information is valid.
2043 LLVM_ABI bool
2046 AA::ValueScope S, bool &UsedAssumedInformation,
2047 bool RecurseForSelectAndPHI = true);
2048
2049 /// Register \p CB as a simplification callback.
2050 /// `Attributor::getAssumedSimplified` will use these callbacks before
2051 /// we it will ask `AAValueSimplify`. It is important to ensure this
2052 /// is called before `identifyDefaultAbstractAttributes`, assuming the
2053 /// latter is called at all.
2054 using SimplifictionCallbackTy = std::function<std::optional<Value *>(
2055 const IRPosition &, const AbstractAttribute *, bool &)>;
2057 const SimplifictionCallbackTy &CB) {
2058 SimplificationCallbacks[IRP].emplace_back(CB);
2059 }
2060
2061 /// Return true if there is a simplification callback for \p IRP.
2063 return SimplificationCallbacks.count(IRP);
2064 }
2065
2066 /// Register \p CB as a simplification callback.
2067 /// Similar to \p registerSimplificationCallback, the call back will be called
2068 /// first when we simplify a global variable \p GV.
2070 std::function<std::optional<Constant *>(
2071 const GlobalVariable &, const AbstractAttribute *, bool &)>;
2073 const GlobalVariable &GV,
2075 GlobalVariableSimplificationCallbacks[&GV].emplace_back(CB);
2076 }
2077
2078 /// Return true if there is a simplification callback for \p GV.
2080 return GlobalVariableSimplificationCallbacks.count(&GV);
2081 }
2082
2083 /// Return \p std::nullopt if there is no call back registered for \p GV or
2084 /// the call back is still not sure if \p GV can be simplified. Return \p
2085 /// nullptr if \p GV can't be simplified.
2086 std::optional<Constant *>
2088 const AbstractAttribute *AA,
2089 bool &UsedAssumedInformation) {
2090 assert(GlobalVariableSimplificationCallbacks.contains(&GV));
2091 for (auto &CB : GlobalVariableSimplificationCallbacks.lookup(&GV)) {
2092 auto SimplifiedGV = CB(GV, AA, UsedAssumedInformation);
2093 // For now we assume the call back will not return a std::nullopt.
2094 assert(SimplifiedGV.has_value() && "SimplifiedGV has not value");
2095 return *SimplifiedGV;
2096 }
2097 llvm_unreachable("there must be a callback registered");
2098 }
2099
2101 std::function<bool(Attributor &, const AbstractAttribute *)>;
2103 const VirtualUseCallbackTy &CB) {
2104 VirtualUseCallbacks[&V].emplace_back(CB);
2105 }
2106
2107private:
2108 /// The vector with all simplification callbacks registered by outside AAs.
2110 SimplificationCallbacks;
2111
2112 /// The vector with all simplification callbacks for global variables
2113 /// registered by outside AAs.
2114 DenseMap<const GlobalVariable *,
2116 GlobalVariableSimplificationCallbacks;
2117
2119 VirtualUseCallbacks;
2120
2121public:
2122 /// Translate \p V from the callee context into the call site context.
2123 LLVM_ABI std::optional<Value *>
2124 translateArgumentToCallSiteContent(std::optional<Value *> V, CallBase &CB,
2125 const AbstractAttribute &AA,
2126 bool &UsedAssumedInformation);
2127
2128 /// Return true if \p AA (or its context instruction) is assumed dead.
2129 ///
2130 /// If \p LivenessAA is not provided it is queried.
2132 const AAIsDead *LivenessAA,
2133 bool &UsedAssumedInformation,
2134 bool CheckBBLivenessOnly = false,
2135 DepClassTy DepClass = DepClassTy::OPTIONAL);
2136
2137 /// Return true if \p I is assumed dead.
2138 ///
2139 /// If \p LivenessAA is not provided it is queried.
2140 LLVM_ABI bool isAssumedDead(const Instruction &I,
2141 const AbstractAttribute *QueryingAA,
2142 const AAIsDead *LivenessAA,
2143 bool &UsedAssumedInformation,
2144 bool CheckBBLivenessOnly = false,
2146 bool CheckForDeadStore = false);
2147
2148 /// Return true if \p U is assumed dead.
2149 ///
2150 /// If \p FnLivenessAA is not provided it is queried.
2151 LLVM_ABI bool isAssumedDead(const Use &U, const AbstractAttribute *QueryingAA,
2152 const AAIsDead *FnLivenessAA,
2153 bool &UsedAssumedInformation,
2154 bool CheckBBLivenessOnly = false,
2155 DepClassTy DepClass = DepClassTy::OPTIONAL);
2156
2157 /// Return true if \p IRP is assumed dead.
2158 ///
2159 /// If \p FnLivenessAA is not provided it is queried.
2160 LLVM_ABI bool isAssumedDead(const IRPosition &IRP,
2161 const AbstractAttribute *QueryingAA,
2162 const AAIsDead *FnLivenessAA,
2163 bool &UsedAssumedInformation,
2164 bool CheckBBLivenessOnly = false,
2165 DepClassTy DepClass = DepClassTy::OPTIONAL);
2166
2167 /// Return true if \p BB is assumed dead.
2168 ///
2169 /// If \p LivenessAA is not provided it is queried.
2170 LLVM_ABI bool isAssumedDead(const BasicBlock &BB,
2171 const AbstractAttribute *QueryingAA,
2172 const AAIsDead *FnLivenessAA,
2173 DepClassTy DepClass = DepClassTy::OPTIONAL);
2174
2175 /// Check \p Pred on all potential Callees of \p CB.
2176 ///
2177 /// This method will evaluate \p Pred with all potential callees of \p CB as
2178 /// input and return true if \p Pred does. If some callees might be unknown
2179 /// this function will return false.
2181 function_ref<bool(ArrayRef<const Function *> Callees)> Pred,
2182 const AbstractAttribute &QueryingAA, const CallBase &CB);
2183
2184 /// Check \p Pred on all (transitive) uses of \p V.
2185 ///
2186 /// This method will evaluate \p Pred on all (transitive) uses of the
2187 /// associated value and return true if \p Pred holds every time.
2188 /// If uses are skipped in favor of equivalent ones, e.g., if we look through
2189 /// memory, the \p EquivalentUseCB will be used to give the caller an idea
2190 /// what original used was replaced by a new one (or new ones). The visit is
2191 /// cut short if \p EquivalentUseCB returns false and the function will return
2192 /// false as well.
2194 function_ref<bool(const Use &, bool &)> Pred,
2195 const AbstractAttribute &QueryingAA, const Value &V,
2196 bool CheckBBLivenessOnly = false,
2197 DepClassTy LivenessDepClass = DepClassTy::OPTIONAL,
2198 bool IgnoreDroppableUses = true,
2199 function_ref<bool(const Use &OldU, const Use &NewU)> EquivalentUseCB =
2200 nullptr);
2201
2202 /// Emit a remark generically.
2203 ///
2204 /// This template function can be used to generically emit a remark. The
2205 /// RemarkKind should be one of the following:
2206 /// - OptimizationRemark to indicate a successful optimization attempt
2207 /// - OptimizationRemarkMissed to report a failed optimization attempt
2208 /// - OptimizationRemarkAnalysis to provide additional information about an
2209 /// optimization attempt
2210 ///
2211 /// The remark is built using a callback function \p RemarkCB that takes a
2212 /// RemarkKind as input and returns a RemarkKind.
2213 template <typename RemarkKind, typename RemarkCallBack>
2215 RemarkCallBack &&RemarkCB) const {
2216 if (!Configuration.OREGetter)
2217 return;
2218
2219 Function *F = I->getFunction();
2220 auto &ORE = Configuration.OREGetter(F);
2221
2222 if (RemarkName.starts_with("OMP"))
2223 ORE.emit([&]() {
2224 return RemarkCB(RemarkKind(Configuration.PassName, RemarkName, I))
2225 << " [" << RemarkName << "]";
2226 });
2227 else
2228 ORE.emit([&]() {
2229 return RemarkCB(RemarkKind(Configuration.PassName, RemarkName, I));
2230 });
2231 }
2232
2233 /// Emit a remark on a function.
2234 template <typename RemarkKind, typename RemarkCallBack>
2235 void emitRemark(Function *F, StringRef RemarkName,
2236 RemarkCallBack &&RemarkCB) const {
2237 if (!Configuration.OREGetter)
2238 return;
2239
2240 auto &ORE = Configuration.OREGetter(F);
2241
2242 if (RemarkName.starts_with("OMP"))
2243 ORE.emit([&]() {
2244 return RemarkCB(RemarkKind(Configuration.PassName, RemarkName, F))
2245 << " [" << RemarkName << "]";
2246 });
2247 else
2248 ORE.emit([&]() {
2249 return RemarkCB(RemarkKind(Configuration.PassName, RemarkName, F));
2250 });
2251 }
2252
2253 /// Helper struct used in the communication between an abstract attribute (AA)
2254 /// that wants to change the signature of a function and the Attributor which
2255 /// applies the changes. The struct is partially initialized with the
2256 /// information from the AA (see the constructor). All other members are
2257 /// provided by the Attributor prior to invoking any callbacks.
2258 struct ArgumentReplacementInfo {
2259 /// Callee repair callback type
2260 ///
2261 /// The function repair callback is invoked once to rewire the replacement
2262 /// arguments in the body of the new function. The argument replacement info
2263 /// is passed, as build from the registerFunctionSignatureRewrite call, as
2264 /// well as the replacement function and an iteratore to the first
2265 /// replacement argument.
2266 using CalleeRepairCBTy = std::function<void(
2267 const ArgumentReplacementInfo &, Function &, Function::arg_iterator)>;
2268
2269 /// Abstract call site (ACS) repair callback type
2270 ///
2271 /// The abstract call site repair callback is invoked once on every abstract
2272 /// call site of the replaced function (\see ReplacedFn). The callback needs
2273 /// to provide the operands for the call to the new replacement function.
2274 /// The number and type of the operands appended to the provided vector
2275 /// (second argument) is defined by the number and types determined through
2276 /// the replacement type vector (\see ReplacementTypes). The first argument
2277 /// is the ArgumentReplacementInfo object registered with the Attributor
2278 /// through the registerFunctionSignatureRewrite call.
2280 std::function<void(const ArgumentReplacementInfo &, AbstractCallSite,
2282
2283 /// Simple getters, see the corresponding members for details.
2284 ///{
2285
2286 Attributor &getAttributor() const { return A; }
2287 const Function &getReplacedFn() const { return ReplacedFn; }
2288 const Argument &getReplacedArg() const { return ReplacedArg; }
2289 unsigned getNumReplacementArgs() const { return ReplacementTypes.size(); }
2291 return ReplacementTypes;
2292 }
2293
2294 ///}
2295
2296 private:
2297 /// Constructor that takes the argument to be replaced, the types of
2298 /// the replacement arguments, as well as callbacks to repair the call sites
2299 /// and new function after the replacement happened.
2301 ArrayRef<Type *> ReplacementTypes,
2302 CalleeRepairCBTy &&CalleeRepairCB,
2303 ACSRepairCBTy &&ACSRepairCB)
2304 : A(A), ReplacedFn(*Arg.getParent()), ReplacedArg(Arg),
2305 ReplacementTypes(ReplacementTypes),
2306 CalleeRepairCB(std::move(CalleeRepairCB)),
2307 ACSRepairCB(std::move(ACSRepairCB)) {}
2308
2309 /// Reference to the attributor to allow access from the callbacks.
2310 Attributor &A;
2311
2312 /// The "old" function replaced by ReplacementFn.
2313 const Function &ReplacedFn;
2314
2315 /// The "old" argument replaced by new ones defined via ReplacementTypes.
2316 const Argument &ReplacedArg;
2317
2318 /// The types of the arguments replacing ReplacedArg.
2319 const SmallVector<Type *, 8> ReplacementTypes;
2320
2321 /// Callee repair callback, see CalleeRepairCBTy.
2322 const CalleeRepairCBTy CalleeRepairCB;
2323
2324 /// Abstract call site (ACS) repair callback, see ACSRepairCBTy.
2325 const ACSRepairCBTy ACSRepairCB;
2326
2327 /// Allow access to the private members from the Attributor.
2328 friend struct Attributor;
2329 };
2330
2331 /// Check if we can rewrite a function signature.
2332 ///
2333 /// The argument \p Arg is replaced with new ones defined by the number,
2334 /// order, and types in \p ReplacementTypes.
2335 ///
2336 /// \returns True, if the replacement can be registered, via
2337 /// registerFunctionSignatureRewrite, false otherwise.
2338 LLVM_ABI bool
2340 ArrayRef<Type *> ReplacementTypes);
2341
2342 /// Register a rewrite for a function signature.
2343 ///
2344 /// The argument \p Arg is replaced with new ones defined by the number,
2345 /// order, and types in \p ReplacementTypes. The rewiring at the call sites is
2346 /// done through \p ACSRepairCB and at the callee site through
2347 /// \p CalleeRepairCB.
2348 ///
2349 /// \returns True, if the replacement was registered, false otherwise.
2351 Argument &Arg, ArrayRef<Type *> ReplacementTypes,
2354
2355 /// Check \p Pred on all function call sites.
2356 ///
2357 /// This method will evaluate \p Pred on call sites and return
2358 /// true if \p Pred holds in every call sites. However, this is only possible
2359 /// all call sites are known, hence the function has internal linkage.
2360 /// If true is returned, \p UsedAssumedInformation is set if assumed
2361 /// information was used to skip or simplify potential call sites.
2363 const AbstractAttribute &QueryingAA,
2364 bool RequireAllCallSites,
2365 bool &UsedAssumedInformation);
2366
2367 /// Check \p Pred on all call sites of \p Fn.
2368 ///
2369 /// This method will evaluate \p Pred on call sites and return
2370 /// true if \p Pred holds in every call sites. However, this is only possible
2371 /// all call sites are known, hence the function has internal linkage.
2372 /// If true is returned, \p UsedAssumedInformation is set if assumed
2373 /// information was used to skip or simplify potential call sites.
2375 const Function &Fn,
2376 bool RequireAllCallSites,
2377 const AbstractAttribute *QueryingAA,
2378 bool &UsedAssumedInformation,
2379 bool CheckPotentiallyDead = false);
2380
2381 /// Check \p Pred on all values potentially returned by the function
2382 /// associated with \p QueryingAA.
2383 ///
2384 /// This is the context insensitive version of the method above.
2385 LLVM_ABI bool
2387 const AbstractAttribute &QueryingAA,
2389 bool RecurseForSelectAndPHI = true);
2390
2391 /// Check \p Pred on all instructions in \p Fn with an opcode present in
2392 /// \p Opcodes.
2393 ///
2394 /// This method will evaluate \p Pred on all instructions with an opcode
2395 /// present in \p Opcode and return true if \p Pred holds on all of them.
2397 const Function *Fn,
2398 const AbstractAttribute *QueryingAA,
2399 ArrayRef<unsigned> Opcodes,
2400 bool &UsedAssumedInformation,
2401 bool CheckBBLivenessOnly = false,
2402 bool CheckPotentiallyDead = false);
2403
2404 /// Check \p Pred on all instructions with an opcode present in \p Opcodes.
2405 ///
2406 /// This method will evaluate \p Pred on all instructions with an opcode
2407 /// present in \p Opcode and return true if \p Pred holds on all of them.
2409 const AbstractAttribute &QueryingAA,
2410 ArrayRef<unsigned> Opcodes,
2411 bool &UsedAssumedInformation,
2412 bool CheckBBLivenessOnly = false,
2413 bool CheckPotentiallyDead = false);
2414
2415 /// Check \p Pred on all call-like instructions (=CallBased derived).
2416 ///
2417 /// See checkForAllCallLikeInstructions(...) for more information.
2419 const AbstractAttribute &QueryingAA,
2420 bool &UsedAssumedInformation,
2421 bool CheckBBLivenessOnly = false,
2422 bool CheckPotentiallyDead = false) {
2424 Pred, QueryingAA,
2425 {(unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,
2426 (unsigned)Instruction::Call},
2427 UsedAssumedInformation, CheckBBLivenessOnly, CheckPotentiallyDead);
2428 }
2429
2430 /// Check \p Pred on all Read/Write instructions.
2431 ///
2432 /// This method will evaluate \p Pred on all instructions that read or write
2433 /// to memory present in the information cache and return true if \p Pred
2434 /// holds on all of them.
2435 LLVM_ABI bool
2437 AbstractAttribute &QueryingAA,
2438 bool &UsedAssumedInformation);
2439
2440 /// Create a shallow wrapper for \p F such that \p F has internal linkage
2441 /// afterwards. It also sets the original \p F 's name to anonymous
2442 ///
2443 /// A wrapper is a function with the same type (and attributes) as \p F
2444 /// that will only call \p F and return the result, if any.
2445 ///
2446 /// Assuming the declaration of looks like:
2447 /// rty F(aty0 arg0, ..., atyN argN);
2448 ///
2449 /// The wrapper will then look as follows:
2450 /// rty wrapper(aty0 arg0, ..., atyN argN) {
2451 /// return F(arg0, ..., argN);
2452 /// }
2453 ///
2455
2456 /// Returns true if the function \p F can be internalized. i.e. it has a
2457 /// compatible linkage.
2458 LLVM_ABI static bool isInternalizable(Function &F);
2459
2460 /// Make another copy of the function \p F such that the copied version has
2461 /// internal linkage afterwards and can be analysed. Then we replace all uses
2462 /// of the original function to the copied one
2463 ///
2464 /// Only non-locally linked functions that have `linkonce_odr` or `weak_odr`
2465 /// linkage can be internalized because these linkages guarantee that other
2466 /// definitions with the same name have the same semantics as this one.
2467 ///
2468 /// This will only be run if the `attributor-allow-deep-wrappers` option is
2469 /// set, or if the function is called with \p Force set to true.
2470 ///
2471 /// If the function \p F failed to be internalized the return value will be a
2472 /// null pointer.
2474 bool Force = false);
2475
2476 /// Make copies of each function in the set \p FnSet such that the copied
2477 /// version has internal linkage afterwards and can be analysed. Then we
2478 /// replace all uses of the original function to the copied one. The map
2479 /// \p FnMap contains a mapping of functions to their internalized versions.
2480 ///
2481 /// Only non-locally linked functions that have `linkonce_odr` or `weak_odr`
2482 /// linkage can be internalized because these linkages guarantee that other
2483 /// definitions with the same name have the same semantics as this one.
2484 ///
2485 /// This version will internalize all the functions in the set \p FnSet at
2486 /// once and then replace the uses. This prevents internalized functions being
2487 /// called by external functions when there is an internalized version in the
2488 /// module.
2489 LLVM_ABI static bool
2492
2493 /// Return the data layout associated with the anchor scope.
2494 const DataLayout &getDataLayout() const { return InfoCache.getDL(); }
2495
2496 /// The allocator used to allocate memory, e.g. for `AbstractAttribute`s.
2498
2500 return CGModifiedFunctions;
2501 }
2502
2503private:
2504 /// This method will do fixpoint iteration until fixpoint or the
2505 /// maximum iteration count is reached.
2506 ///
2507 /// If the maximum iteration count is reached, This method will
2508 /// indicate pessimistic fixpoint on attributes that transitively depend
2509 /// on attributes that were scheduled for an update.
2510 void runTillFixpoint();
2511
2512 /// Gets called after scheduling, manifests attributes to the LLVM IR.
2513 ChangeStatus manifestAttributes();
2514
2515 /// Gets called after attributes have been manifested, cleans up the IR.
2516 /// Deletes dead functions, blocks and instructions.
2517 /// Rewrites function signitures and updates the call graph.
2518 ChangeStatus cleanupIR();
2519
2520 /// Identify internal functions that are effectively dead, thus not reachable
2521 /// from a live entry point. The functions are added to ToBeDeletedFunctions.
2522 void identifyDeadInternalFunctions();
2523
2524 /// Run `::update` on \p AA and track the dependences queried while doing so.
2525 /// Also adjust the state if we know further updates are not necessary.
2527
2528 /// Remember the dependences on the top of the dependence stack such that they
2529 /// may trigger further updates. (\see DependenceStack)
2530 void rememberDependences();
2531
2532 /// Determine if CallBase context in \p IRP should be propagated.
2533 LLVM_ABI bool shouldPropagateCallBaseContext(const IRPosition &IRP);
2534
2535 /// Apply all requested function signature rewrites
2536 /// (\see registerFunctionSignatureRewrite) and return Changed if the module
2537 /// was altered.
2539 rewriteFunctionSignatures(SmallSetVector<Function *, 8> &ModifiedFns);
2540
2541 /// Check if the Attribute \p AA should be seeded.
2542 /// See getOrCreateAAFor.
2543 LLVM_ABI bool shouldSeedAttribute(AbstractAttribute &AA);
2544
2545 /// A nested map to lookup abstract attributes based on the argument position
2546 /// on the outer level, and the addresses of the static member (AAType::ID) on
2547 /// the inner level.
2548 ///{
2549 using AAMapKeyTy = std::pair<const char *, IRPosition>;
2551 ///}
2552
2553 /// Map to remember all requested signature changes (= argument replacements).
2555 ArgumentReplacementMap;
2556
2557 /// The set of functions we are deriving attributes for.
2558 SetVector<Function *> &Functions;
2559
2560 /// The information cache that holds pre-processed (LLVM-IR) information.
2561 InformationCache &InfoCache;
2562
2563 /// Abstract Attribute dependency graph
2564 AADepGraph DG;
2565
2566 /// Set of functions for which we modified the content such that it might
2567 /// impact the call graph.
2568 SmallSetVector<Function *, 8> CGModifiedFunctions;
2569
2570 /// Information about a dependence. If FromAA is changed ToAA needs to be
2571 /// updated as well.
2572 struct DepInfo {
2573 const AbstractAttribute *FromAA;
2574 const AbstractAttribute *ToAA;
2575 DepClassTy DepClass;
2576 };
2577
2578 /// The dependence stack is used to track dependences during an
2579 /// `AbstractAttribute::update` call. As `AbstractAttribute::update` can be
2580 /// recursive we might have multiple vectors of dependences in here. The stack
2581 /// size, should be adjusted according to the expected recursion depth and the
2582 /// inner dependence vector size to the expected number of dependences per
2583 /// abstract attribute. Since the inner vectors are actually allocated on the
2584 /// stack we can be generous with their size.
2585 using DependenceVector = SmallVector<DepInfo, 8>;
2587
2588 /// A set to remember the functions we already assume to be live and visited.
2589 DenseSet<const Function *> VisitedFunctions;
2590
2591 /// Uses we replace with a new value after manifest is done. We will remove
2592 /// then trivially dead instructions as well.
2593 SmallMapVector<Use *, Value *, 32> ToBeChangedUses;
2594
2595 /// Values we replace with a new value after manifest is done. We will remove
2596 /// then trivially dead instructions as well.
2597 SmallMapVector<Value *, PointerIntPair<Value *, 1, bool>, 32>
2598 ToBeChangedValues;
2599
2600 /// Instructions we replace with `unreachable` insts after manifest is done.
2601 SmallSetVector<WeakVH, 16> ToBeChangedToUnreachableInsts;
2602
2603 /// Invoke instructions with at least a single dead successor block.
2604 SmallSetVector<WeakVH, 16> InvokeWithDeadSuccessor;
2605
2606 /// A flag that indicates which stage of the process we are in. Initially, the
2607 /// phase is SEEDING. Phase is changed in `Attributor::run()`
2608 enum class AttributorPhase {
2609 SEEDING,
2610 UPDATE,
2611 MANIFEST,
2612 CLEANUP,
2613 } Phase = AttributorPhase::SEEDING;
2614
2615 /// The current initialization chain length. Tracked to avoid stack overflows.
2616 unsigned InitializationChainLength = 0;
2617
2618 /// Functions, blocks, and instructions we delete after manifest is done.
2619 ///
2620 ///{
2621 SmallPtrSet<BasicBlock *, 8> ManifestAddedBlocks;
2622 SmallSetVector<Function *, 8> ToBeDeletedFunctions;
2623 SmallSetVector<BasicBlock *, 8> ToBeDeletedBlocks;
2624 SmallSetVector<WeakVH, 8> ToBeDeletedInsts;
2625 ///}
2626
2627 /// Container with all the query AAs that requested an update via
2628 /// registerForUpdate.
2629 SmallSetVector<AbstractAttribute *, 16> QueryAAsAwaitingUpdate;
2630
2631 /// User provided configuration for this Attributor instance.
2632 const AttributorConfig Configuration;
2633
2634 friend AADepGraph;
2635 friend AttributorCallGraph;
2636};
2637
2638/// An interface to query the internal state of an abstract attribute.
2639///
2640/// The abstract state is a minimal interface that allows the Attributor to
2641/// communicate with the abstract attributes about their internal state without
2642/// enforcing or exposing implementation details, e.g., the (existence of an)
2643/// underlying lattice.
2644///
2645/// It is sufficient to be able to query if a state is (1) valid or invalid, (2)
2646/// at a fixpoint, and to indicate to the state that (3) an optimistic fixpoint
2647/// was reached or (4) a pessimistic fixpoint was enforced.
2648///
2649/// All methods need to be implemented by the subclass. For the common use case,
2650/// a single boolean state or a bit-encoded state, the BooleanState and
2651/// {Inc,Dec,Bit}IntegerState classes are already provided. An abstract
2652/// attribute can inherit from them to get the abstract state interface and
2653/// additional methods to directly modify the state based if needed. See the
2654/// class comments for help.
2656 virtual ~AbstractState() = default;
2657
2658 /// Return if this abstract state is in a valid state. If false, no
2659 /// information provided should be used.
2660 virtual bool isValidState() const = 0;
2661
2662 /// Return if this abstract state is fixed, thus does not need to be updated
2663 /// if information changes as it cannot change itself.
2664 virtual bool isAtFixpoint() const = 0;
2665
2666 /// Indicate that the abstract state should converge to the optimistic state.
2667 ///
2668 /// This will usually make the optimistically assumed state the known to be
2669 /// true state.
2670 ///
2671 /// \returns ChangeStatus::UNCHANGED as the assumed value should not change.
2673
2674 /// Indicate that the abstract state should converge to the pessimistic state.
2675 ///
2676 /// This will usually revert the optimistically assumed state to the known to
2677 /// be true state.
2678 ///
2679 /// \returns ChangeStatus::CHANGED as the assumed value may change.
2681};
2682
2683/// Simple state with integers encoding.
2684///
2685/// The interface ensures that the assumed bits are always a subset of the known
2686/// bits. Users can only add known bits and, except through adding known bits,
2687/// they can only remove assumed bits. This should guarantee monotonicity and
2688/// thereby the existence of a fixpoint (if used correctly). The fixpoint is
2689/// reached when the assumed and known state/bits are equal. Users can
2690/// force/inidicate a fixpoint. If an optimistic one is indicated, the known
2691/// state will catch up with the assumed one, for a pessimistic fixpoint it is
2692/// the other way around.
2693template <typename base_ty, base_ty BestState, base_ty WorstState>
2695 using base_t = base_ty;
2696
2697 IntegerStateBase() = default;
2699
2700 /// Return the best possible representable state.
2701 static constexpr base_t getBestState() { return BestState; }
2702 static constexpr base_t getBestState(const IntegerStateBase &) {
2703 return getBestState();
2704 }
2705
2706 /// Return the worst possible representable state.
2707 static constexpr base_t getWorstState() { return WorstState; }
2708 static constexpr base_t getWorstState(const IntegerStateBase &) {
2709 return getWorstState();
2710 }
2711
2712 /// See AbstractState::isValidState()
2713 /// NOTE: For now we simply pretend that the worst possible state is invalid.
2714 bool isValidState() const override { return Assumed != getWorstState(); }
2715
2716 /// See AbstractState::isAtFixpoint()
2717 bool isAtFixpoint() const override { return Assumed == Known; }
2718
2719 /// See AbstractState::indicateOptimisticFixpoint(...)
2724
2725 /// See AbstractState::indicatePessimisticFixpoint(...)
2730
2731 /// Return the known state encoding
2732 base_t getKnown() const { return Known; }
2733
2734 /// Return the assumed state encoding.
2735 base_t getAssumed() const { return Assumed; }
2736
2737 /// Equality for IntegerStateBase.
2738 bool
2740 return this->getAssumed() == R.getAssumed() &&
2741 this->getKnown() == R.getKnown();
2742 }
2743
2744 /// Inequality for IntegerStateBase.
2745 bool
2747 return !(*this == R);
2748 }
2749
2750 /// "Clamp" this state with \p R. The result is subtype dependent but it is
2751 /// intended that only information assumed in both states will be assumed in
2752 /// this one afterwards.
2756
2757 /// "Clamp" this state with \p R. The result is subtype dependent but it is
2758 /// intended that information known in either state will be known in
2759 /// this one afterwards.
2763
2765 joinOR(R.getAssumed(), R.getKnown());
2766 }
2767
2769 joinAND(R.getAssumed(), R.getKnown());
2770 }
2771
2772protected:
2773 /// Handle a new assumed value \p Value. Subtype dependent.
2775
2776 /// Handle a new known value \p Value. Subtype dependent.
2778
2779 /// Handle a value \p Value. Subtype dependent.
2780 virtual void joinOR(base_t AssumedValue, base_t KnownValue) = 0;
2781
2782 /// Handle a new assumed value \p Value. Subtype dependent.
2783 virtual void joinAND(base_t AssumedValue, base_t KnownValue) = 0;
2784
2785 /// The known state encoding in an integer of type base_t.
2787
2788 /// The assumed state encoding in an integer of type base_t.
2790};
2791
2792/// Specialization of the integer state for a bit-wise encoding.
2793template <typename base_ty = uint32_t, base_ty BestState = ~base_ty(0),
2794 base_ty WorstState = 0>
2796 : public IntegerStateBase<base_ty, BestState, WorstState> {
2798 using base_t = base_ty;
2799 BitIntegerState() = default;
2801
2802 /// Return true if the bits set in \p BitsEncoding are "known bits".
2803 bool isKnown(base_t BitsEncoding = BestState) const {
2804 return (this->Known & BitsEncoding) == BitsEncoding;
2805 }
2806
2807 /// Return true if the bits set in \p BitsEncoding are "assumed bits".
2808 bool isAssumed(base_t BitsEncoding = BestState) const {
2809 return (this->Assumed & BitsEncoding) == BitsEncoding;
2810 }
2811
2812 /// Add the bits in \p BitsEncoding to the "known bits".
2814 // Make sure we never miss any "known bits".
2815 this->Assumed |= Bits;
2816 this->Known |= Bits;
2817 return *this;
2818 }
2819
2820 /// Remove the bits in \p BitsEncoding from the "assumed bits" if not known.
2822 return intersectAssumedBits(~BitsEncoding);
2823 }
2824
2825 /// Remove the bits in \p BitsEncoding from the "known bits".
2827 this->Known = (this->Known & ~BitsEncoding);
2828 return *this;
2829 }
2830
2831 /// Keep only "assumed bits" also set in \p BitsEncoding but all known ones.
2833 // Make sure we never lose any "known bits".
2834 this->Assumed = (this->Assumed & BitsEncoding) | this->Known;
2835 return *this;
2836 }
2837
2838private:
2839 void handleNewAssumedValue(base_t Value) override {
2841 }
2842 void handleNewKnownValue(base_t Value) override { addKnownBits(Value); }
2843 void joinOR(base_t AssumedValue, base_t KnownValue) override {
2844 this->Known |= KnownValue;
2845 this->Assumed |= AssumedValue;
2846 }
2847 void joinAND(base_t AssumedValue, base_t KnownValue) override {
2848 this->Known &= KnownValue;
2849 this->Assumed &= AssumedValue;
2850 }
2851};
2852
2853/// Specialization of the integer state for an increasing value, hence ~0u is
2854/// the best state and 0 the worst.
2855template <typename base_ty = uint32_t, base_ty BestState = ~base_ty(0),
2856 base_ty WorstState = 0>
2858 : public IntegerStateBase<base_ty, BestState, WorstState> {
2860 using base_t = base_ty;
2861
2864
2865 /// Return the best possible representable state.
2866 static constexpr base_t getBestState() { return BestState; }
2867 static constexpr base_t
2871
2872 /// Take minimum of assumed and \p Value.
2874 // Make sure we never lose "known value".
2875 this->Assumed = std::max(std::min(this->Assumed, Value), this->Known);
2876 return *this;
2877 }
2878
2879 /// Take maximum of known and \p Value.
2881 // Make sure we never lose "known value".
2882 this->Assumed = std::max(Value, this->Assumed);
2883 this->Known = std::max(Value, this->Known);
2884 return *this;
2885 }
2886
2887private:
2888 void handleNewAssumedValue(base_t Value) override {
2890 }
2891 void handleNewKnownValue(base_t Value) override { takeKnownMaximum(Value); }
2892 void joinOR(base_t AssumedValue, base_t KnownValue) override {
2893 this->Known = std::max(this->Known, KnownValue);
2894 this->Assumed = std::max(this->Assumed, AssumedValue);
2895 }
2896 void joinAND(base_t AssumedValue, base_t KnownValue) override {
2897 this->Known = std::min(this->Known, KnownValue);
2898 this->Assumed = std::min(this->Assumed, AssumedValue);
2899 }
2900};
2901
2902/// Specialization of the integer state for a decreasing value, hence 0 is the
2903/// best state and ~0u the worst.
2904template <typename base_ty = uint32_t>
2905struct DecIntegerState : public IntegerStateBase<base_ty, 0, ~base_ty(0)> {
2906 using base_t = base_ty;
2907
2908 /// Take maximum of assumed and \p Value.
2910 // Make sure we never lose "known value".
2911 this->Assumed = std::min(std::max(this->Assumed, Value), this->Known);
2912 return *this;
2913 }
2914
2915 /// Take minimum of known and \p Value.
2917 // Make sure we never lose "known value".
2918 this->Assumed = std::min(Value, this->Assumed);
2919 this->Known = std::min(Value, this->Known);
2920 return *this;
2921 }
2922
2923private:
2924 void handleNewAssumedValue(base_t Value) override {
2926 }
2927 void handleNewKnownValue(base_t Value) override { takeKnownMinimum(Value); }
2928 void joinOR(base_t AssumedValue, base_t KnownValue) override {
2929 this->Assumed = std::min(this->Assumed, KnownValue);
2930 this->Assumed = std::min(this->Assumed, AssumedValue);
2931 }
2932 void joinAND(base_t AssumedValue, base_t KnownValue) override {
2933 this->Assumed = std::max(this->Assumed, KnownValue);
2934 this->Assumed = std::max(this->Assumed, AssumedValue);
2935 }
2936};
2937
2938/// Simple wrapper for a single bit (boolean) state.
2939struct BooleanState : public IntegerStateBase<bool, true, false> {
2942
2943 BooleanState() = default;
2945
2946 /// Set the assumed value to \p Value but never below the known one.
2947 void setAssumed(bool Value) { Assumed &= (Known | Value); }
2948
2949 /// Set the known and asssumed value to \p Value.
2950 void setKnown(bool Value) {
2951 Known |= Value;
2952 Assumed |= Value;
2953 }
2954
2955 /// Return true if the state is assumed to hold.
2956 bool isAssumed() const { return getAssumed(); }
2957
2958 /// Return true if the state is known to hold.
2959 bool isKnown() const { return getKnown(); }
2960
2961private:
2962 void handleNewAssumedValue(base_t Value) override {
2963 if (!Value)
2964 Assumed = Known;
2965 }
2966 void handleNewKnownValue(base_t Value) override {
2967 if (Value)
2968 Known = (Assumed = Value);
2969 }
2970 void joinOR(base_t AssumedValue, base_t KnownValue) override {
2971 Known |= KnownValue;
2972 Assumed |= AssumedValue;
2973 }
2974 void joinAND(base_t AssumedValue, base_t KnownValue) override {
2975 Known &= KnownValue;
2976 Assumed &= AssumedValue;
2977 }
2978};
2979
2980/// State for an integer range.
2982
2983 /// Bitwidth of the associated value.
2985
2986 /// State representing assumed range, initially set to empty.
2988
2989 /// State representing known range, initially set to [-inf, inf].
2991
2995
2999
3000 /// Return the worst possible representable state.
3002 return ConstantRange::getFull(BitWidth);
3003 }
3004
3005 /// Return the best possible representable state.
3007 return ConstantRange::getEmpty(BitWidth);
3008 }
3010 return getBestState(IRS.getBitWidth());
3011 }
3012
3013 /// Return associated values' bit width.
3014 uint32_t getBitWidth() const { return BitWidth; }
3015
3016 /// See AbstractState::isValidState()
3017 bool isValidState() const override {
3018 return BitWidth > 0 && !Assumed.isFullSet();
3019 }
3020
3021 /// See AbstractState::isAtFixpoint()
3022 bool isAtFixpoint() const override { return Assumed == Known; }
3023
3024 /// See AbstractState::indicateOptimisticFixpoint(...)
3029
3030 /// See AbstractState::indicatePessimisticFixpoint(...)
3035
3036 /// Return the known state encoding
3037 ConstantRange getKnown() const { return Known; }
3038
3039 /// Return the assumed state encoding.
3041
3042 /// Unite assumed range with the passed state.
3044 // Don't lose a known range.
3045 Assumed = Assumed.unionWith(R).intersectWith(Known);
3046 }
3047
3048 /// See IntegerRangeState::unionAssumed(..).
3050 unionAssumed(R.getAssumed());
3051 }
3052
3053 /// Intersect known range with the passed state.
3055 Assumed = Assumed.intersectWith(R);
3056 Known = Known.intersectWith(R);
3057 }
3058
3059 /// See IntegerRangeState::intersectKnown(..).
3061 intersectKnown(R.getKnown());
3062 }
3063
3064 /// Equality for IntegerRangeState.
3065 bool operator==(const IntegerRangeState &R) const {
3066 return getAssumed() == R.getAssumed() && getKnown() == R.getKnown();
3067 }
3068
3069 /// "Clamp" this state with \p R. The result is subtype dependent but it is
3070 /// intended that only information assumed in both states will be assumed in
3071 /// this one afterwards.
3073 // NOTE: `^=` operator seems like `intersect` but in this case, we need to
3074 // take `union`.
3075 unionAssumed(R);
3076 return *this;
3077 }
3078
3080 // NOTE: `&=` operator seems like `intersect` but in this case, we need to
3081 // take `union`.
3082 Known = Known.unionWith(R.getKnown());
3083 Assumed = Assumed.unionWith(R.getAssumed());
3084 return *this;
3085 }
3086};
3087
3088/// Simple state for a set.
3089///
3090/// This represents a state containing a set of values. The interface supports
3091/// modelling sets that contain all possible elements. The state's internal
3092/// value is modified using union or intersection operations.
3093template <typename BaseTy> struct SetState : public AbstractState {
3094 /// A wrapper around a set that has semantics for handling unions and
3095 /// intersections with a "universal" set that contains all elements.
3097 /// Creates a universal set with no concrete elements or an empty set.
3098 SetContents(bool Universal) : Universal(Universal) {}
3099
3100 /// Creates a non-universal set with concrete values.
3101 SetContents(const DenseSet<BaseTy> &Assumptions)
3102 : Universal(false), Set(Assumptions) {}
3103
3104 SetContents(bool Universal, const DenseSet<BaseTy> &Assumptions)
3105 : Universal(Universal), Set(Assumptions) {}
3106
3107 const DenseSet<BaseTy> &getSet() const { return Set; }
3108
3109 bool isUniversal() const { return Universal; }
3110
3111 bool empty() const { return Set.empty() && !Universal; }
3112
3113 /// Finds A := A ^ B where A or B could be the "Universal" set which
3114 /// contains every possible attribute. Returns true if changes were made.
3116 bool IsUniversal = Universal;
3117 unsigned Size = Set.size();
3118
3119 // A := A ^ U = A
3120 if (RHS.isUniversal())
3121 return false;
3122
3123 // A := U ^ B = B
3124 if (Universal)
3125 Set = RHS.getSet();
3126 else
3127 set_intersect(Set, RHS.getSet());
3128
3129 Universal &= RHS.isUniversal();
3130 return IsUniversal != Universal || Size != Set.size();
3131 }
3132
3133 /// Finds A := A u B where A or B could be the "Universal" set which
3134 /// contains every possible attribute. returns true if changes were made.
3135 bool getUnion(const SetContents &RHS) {
3136 bool IsUniversal = Universal;
3137 unsigned Size = Set.size();
3138
3139 // A := A u U = U = U u B
3140 if (!RHS.isUniversal() && !Universal)
3141 set_union(Set, RHS.getSet());
3142
3143 Universal |= RHS.isUniversal();
3144 return IsUniversal != Universal || Size != Set.size();
3145 }
3146
3147 private:
3148 /// Indicates if this set is "universal", containing every possible element.
3149 bool Universal;
3150
3151 /// The set of currently active assumptions.
3152 DenseSet<BaseTy> Set;
3153 };
3154
3155 SetState() : Known(false), Assumed(true), IsAtFixedpoint(false) {}
3156
3157 /// Initializes the known state with an initial set and initializes the
3158 /// assumed state as universal.
3160 : Known(Known), Assumed(true), IsAtFixedpoint(false) {}
3161
3162 /// See AbstractState::isValidState()
3163 bool isValidState() const override { return !Assumed.empty(); }
3164
3165 /// See AbstractState::isAtFixpoint()
3166 bool isAtFixpoint() const override { return IsAtFixedpoint; }
3167
3168 /// See AbstractState::indicateOptimisticFixpoint(...)
3170 IsAtFixedpoint = true;
3171 Known = Assumed;
3173 }
3174
3175 /// See AbstractState::indicatePessimisticFixpoint(...)
3177 IsAtFixedpoint = true;
3178 Assumed = Known;
3179 return ChangeStatus::CHANGED;
3180 }
3181
3182 /// Return the known state encoding.
3183 const SetContents &getKnown() const { return Known; }
3184
3185 /// Return the assumed state encoding.
3186 const SetContents &getAssumed() const { return Assumed; }
3187
3188 /// Returns if the set state contains the element.
3189 bool setContains(const BaseTy &Elem) const {
3190 return Assumed.getSet().contains(Elem) || Known.getSet().contains(Elem);
3191 }
3192
3193 /// Performs the set intersection between this set and \p RHS. Returns true if
3194 /// changes were made.
3196 bool IsUniversal = Assumed.isUniversal();
3197 unsigned SizeBefore = Assumed.getSet().size();
3198
3199 // Get intersection and make sure that the known set is still a proper
3200 // subset of the assumed set. A := K u (A ^ R).
3201 Assumed.getIntersection(RHS);
3202 Assumed.getUnion(Known);
3203
3204 return SizeBefore != Assumed.getSet().size() ||
3205 IsUniversal != Assumed.isUniversal();
3206 }
3207
3208 /// Performs the set union between this set and \p RHS. Returns true if
3209 /// changes were made.
3210 bool getUnion(const SetContents &RHS) { return Assumed.getUnion(RHS); }
3211
3212private:
3213 /// The set of values known for this state.
3214 SetContents Known;
3215
3216 /// The set of assumed values for this state.
3217 SetContents Assumed;
3218
3219 bool IsAtFixedpoint;
3220};
3221
3222/// Helper to tie a abstract state implementation to an abstract attribute.
3223template <typename StateTy, typename BaseType, class... Ts>
3224struct StateWrapper : public BaseType, public StateTy {
3225 /// Provide static access to the type of the state.
3227
3228 StateWrapper(const IRPosition &IRP, Ts... Args)
3229 : BaseType(IRP), StateTy(Args...) {}
3230
3231 /// See AbstractAttribute::getState(...).
3232 StateType &getState() override { return *this; }
3233
3234 /// See AbstractAttribute::getState(...).
3235 const StateType &getState() const override { return *this; }
3236};
3237
3238/// Helper class that provides common functionality to manifest IR attributes.
3239template <Attribute::AttrKind AK, typename BaseType, typename AAType>
3240struct IRAttribute : public BaseType {
3241 IRAttribute(const IRPosition &IRP) : BaseType(IRP) {}
3242
3243 /// Most boolean IRAttribute AAs don't do anything non-trivial
3244 /// in their initializers while non-boolean ones often do. Subclasses can
3245 /// change this.
3247
3248 /// Compile time access to the IR attribute kind.
3250
3251 /// Return true if the IR attribute(s) associated with this AA are implied for
3252 /// an undef value.
3253 static bool isImpliedByUndef() { return true; }
3254
3255 /// Return true if the IR attribute(s) associated with this AA are implied for
3256 /// an poison value.
3257 static bool isImpliedByPoison() { return true; }
3258
3259 static bool isImpliedByIR(Attributor &A, const IRPosition &IRP,
3260 Attribute::AttrKind ImpliedAttributeKind = AK,
3261 bool IgnoreSubsumingPositions = false) {
3262 if (AAType::isImpliedByUndef() && isa<UndefValue>(IRP.getAssociatedValue()))
3263 return true;
3264 if (AAType::isImpliedByPoison() &&
3266 return true;
3267 return A.hasAttr(IRP, {ImpliedAttributeKind}, IgnoreSubsumingPositions,
3268 ImpliedAttributeKind);
3269 }
3270
3271 /// See AbstractAttribute::manifest(...).
3273 if (isa<UndefValue>(this->getIRPosition().getAssociatedValue()))
3275 SmallVector<Attribute, 4> DeducedAttrs;
3276 getDeducedAttributes(A, this->getAnchorValue().getContext(), DeducedAttrs);
3277 if (DeducedAttrs.empty())
3279 return A.manifestAttrs(this->getIRPosition(), DeducedAttrs);
3280 }
3281
3282 /// Return the kind that identifies the abstract attribute implementation.
3283 Attribute::AttrKind getAttrKind() const { return AK; }
3284
3285 /// Return the deduced attributes in \p Attrs.
3287 SmallVectorImpl<Attribute> &Attrs) const {
3288 Attrs.emplace_back(Attribute::get(Ctx, getAttrKind()));
3289 }
3290};
3291
3292/// Base struct for all "concrete attribute" deductions.
3293///
3294/// The abstract attribute is a minimal interface that allows the Attributor to
3295/// orchestrate the abstract/fixpoint analysis. The design allows to hide away
3296/// implementation choices made for the subclasses but also to structure their
3297/// implementation and simplify the use of other abstract attributes in-flight.
3298///
3299/// To allow easy creation of new attributes, most methods have default
3300/// implementations. The ones that do not are generally straight forward, except
3301/// `AbstractAttribute::updateImpl` which is the location of most reasoning
3302/// associated with the abstract attribute. The update is invoked by the
3303/// Attributor in case the situation used to justify the current optimistic
3304/// state might have changed. The Attributor determines this automatically
3305/// by monitoring the `Attributor::getAAFor` calls made by abstract attributes.
3306///
3307/// The `updateImpl` method should inspect the IR and other abstract attributes
3308/// in-flight to justify the best possible (=optimistic) state. The actual
3309/// implementation is, similar to the underlying abstract state encoding, not
3310/// exposed. In the most common case, the `updateImpl` will go through a list of
3311/// reasons why its optimistic state is valid given the current information. If
3312/// any combination of them holds and is sufficient to justify the current
3313/// optimistic state, the method shall return UNCHAGED. If not, the optimistic
3314/// state is adjusted to the situation and the method shall return CHANGED.
3315///
3316/// If the manifestation of the "concrete attribute" deduced by the subclass
3317/// differs from the "default" behavior, which is a (set of) LLVM-IR
3318/// attribute(s) for an argument, call site argument, function return value, or
3319/// function, the `AbstractAttribute::manifest` method should be overloaded.
3320///
3321/// NOTE: If the state obtained via getState() is INVALID, thus if
3322/// AbstractAttribute::getState().isValidState() returns false, no
3323/// information provided by the methods of this class should be used.
3324/// NOTE: The Attributor currently has certain limitations to what we can do.
3325/// As a general rule of thumb, "concrete" abstract attributes should *for
3326/// now* only perform "backward" information propagation. That means
3327/// optimistic information obtained through abstract attributes should
3328/// only be used at positions that precede the origin of the information
3329/// with regards to the program flow. More practically, information can
3330/// *now* be propagated from instructions to their enclosing function, but
3331/// *not* from call sites to the called function. The mechanisms to allow
3332/// both directions will be added in the future.
3333/// NOTE: The mechanics of adding a new "concrete" abstract attribute are
3334/// described in the file comment.
3337
3339
3340 /// Virtual destructor.
3341 ~AbstractAttribute() override = default;
3342
3343 /// Compile time access to the IR attribute kind.
3345
3346 /// This function is used to identify if an \p DGN is of type
3347 /// AbstractAttribute so that the dyn_cast and cast can use such information
3348 /// to cast an AADepGraphNode to an AbstractAttribute.
3349 ///
3350 /// We eagerly return true here because all AADepGraphNodes except for the
3351 /// Synthethis Node are of type AbstractAttribute
3352 static bool classof(const AADepGraphNode *DGN) { return true; }
3353
3354 /// Return false if this AA does anything non-trivial (hence not done by
3355 /// default) in its initializer.
3356 static bool hasTrivialInitializer() { return false; }
3357
3358 /// Return true if this AA requires a "callee" (or an associted function) for
3359 /// a call site positon. Default is optimistic to minimize AAs.
3360 static bool requiresCalleeForCallBase() { return false; }
3361
3362 /// Return true if this AA requires non-asm "callee" for a call site positon.
3363 static bool requiresNonAsmForCallBase() { return true; }
3364
3365 /// Return true if this AA requires all callees for an argument or function
3366 /// positon.
3367 static bool requiresCallersForArgOrFunction() { return false; }
3368
3369 /// Return false if an AA should not be created for \p IRP.
3371 return true;
3372 }
3373
3374 /// Return false if an AA should not be updated for \p IRP.
3376 Function *AssociatedFn = IRP.getAssociatedFunction();
3377 bool IsFnInterface = IRP.isFnInterfaceKind();
3378 assert((!IsFnInterface || AssociatedFn) &&
3379 "Function interface without a function?");
3380
3381 // TODO: Not all attributes require an exact definition. Find a way to
3382 // enable deduction for some but not all attributes in case the
3383 // definition might be changed at runtime, see also
3384 // http://lists.llvm.org/pipermail/llvm-dev/2018-February/121275.html.
3385 // TODO: We could always determine abstract attributes and if sufficient
3386 // information was found we could duplicate the functions that do not
3387 // have an exact definition.
3388 return !IsFnInterface || A.isFunctionIPOAmendable(*AssociatedFn);
3389 }
3390
3391 /// Initialize the state with the information in the Attributor \p A.
3392 ///
3393 /// This function is called by the Attributor once all abstract attributes
3394 /// have been identified. It can and shall be used for task like:
3395 /// - identify existing knowledge in the IR and use it for the "known state"
3396 /// - perform any work that is not going to change over time, e.g., determine
3397 /// a subset of the IR, or attributes in-flight, that have to be looked at
3398 /// in the `updateImpl` method.
3399 virtual void initialize(Attributor &A) {}
3400
3401 /// A query AA is always scheduled as long as we do updates because it does
3402 /// lazy computation that cannot be determined to be done from the outside.
3403 /// However, while query AAs will not be fixed if they do not have outstanding
3404 /// dependences, we will only schedule them like other AAs. If a query AA that
3405 /// received a new query it needs to request an update via
3406 /// `Attributor::requestUpdateForAA`.
3407 virtual bool isQueryAA() const { return false; }
3408
3409 /// Return the internal abstract state for inspection.
3410 virtual StateType &getState() = 0;
3411 virtual const StateType &getState() const = 0;
3412
3413 /// Return an IR position, see struct IRPosition.
3414 const IRPosition &getIRPosition() const { return *this; };
3415 IRPosition &getIRPosition() { return *this; };
3416
3417 /// Helper functions, for debug purposes only.
3418 ///{
3419 void print(raw_ostream &OS) const { print(nullptr, OS); }
3420 void print(Attributor *, raw_ostream &OS) const override;
3421 virtual void printWithDeps(raw_ostream &OS) const;
3422 void dump() const { this->print(dbgs()); }
3423
3424 /// This function should return the "summarized" assumed state as string.
3425 virtual const std::string getAsStr(Attributor *A) const = 0;
3426
3427 /// This function should return the name of the AbstractAttribute
3428 virtual StringRef getName() const = 0;
3429
3430 /// This function should return the address of the ID of the AbstractAttribute
3431 virtual const char *getIdAddr() const = 0;
3432 ///}
3433
3434 /// Allow the Attributor access to the protected methods.
3435 friend struct Attributor;
3436
3437protected:
3438 /// Hook for the Attributor to trigger an update of the internal state.
3439 ///
3440 /// If this attribute is already fixed, this method will return UNCHANGED,
3441 /// otherwise it delegates to `AbstractAttribute::updateImpl`.
3442 ///
3443 /// \Return CHANGED if the internal state changed, otherwise UNCHANGED.
3445
3446 /// Hook for the Attributor to trigger the manifestation of the information
3447 /// represented by the abstract attribute in the LLVM-IR.
3448 ///
3449 /// \Return CHANGED if the IR was altered, otherwise UNCHANGED.
3453
3454 /// Hook to enable custom statistic tracking, called after manifest that
3455 /// resulted in a change if statistics are enabled.
3456 ///
3457 /// We require subclasses to provide an implementation so we remember to
3458 /// add statistics for them.
3459 virtual void trackStatistics() const = 0;
3460
3461 /// The actual update/transfer function which has to be implemented by the
3462 /// derived classes.
3463 ///
3464 /// If it is called, the environment has changed and we have to determine if
3465 /// the current information is still valid or adjust it otherwise.
3466 ///
3467 /// \Return CHANGED if the internal state changed, otherwise UNCHANGED.
3469};
3470
3471/// Forward declarations of output streams for debug purposes.
3472///
3473///{
3479template <typename base_ty, base_ty BestState, base_ty WorstState>
3483 return OS << "(" << S.getKnown() << "-" << S.getAssumed() << ")"
3484 << static_cast<const AbstractState &>(S);
3485}
3486LLVM_ABI raw_ostream &operator<<(raw_ostream &OS,
3487 const IntegerRangeState &State);
3488///}
3489
3490struct AttributorPass : public PassInfoMixin<AttributorPass> {
3492};
3498
3499/// A more lightweight version of the Attributor which only runs attribute
3500/// inference but no simplifications.
3501struct AttributorLightPass : public PassInfoMixin<AttributorLightPass> {
3503};
3504
3505/// A more lightweight version of the Attributor which only runs attribute
3506/// inference but no simplifications.
3508 : public PassInfoMixin<AttributorLightCGSCCPass> {
3511 CGSCCUpdateResult &UR);
3512};
3513
3514/// Helper function to clamp a state \p S of type \p StateType with the
3515/// information in \p R and indicate/return if \p S did change (as-in update is
3516/// required to be run again).
3517template <typename StateType>
3518ChangeStatus clampStateAndIndicateChange(StateType &S, const StateType &R) {
3519 auto Assumed = S.getAssumed();
3520 S ^= R;
3521 return Assumed == S.getAssumed() ? ChangeStatus::UNCHANGED
3523}
3524
3525/// ----------------------------------------------------------------------------
3526/// Abstract Attribute Classes
3527/// ----------------------------------------------------------------------------
3528
3530 : public IRAttribute<Attribute::NoUnwind,
3531 StateWrapper<BooleanState, AbstractAttribute>,
3532 AANoUnwind> {
3534
3535 /// Returns true if nounwind is assumed.
3536 bool isAssumedNoUnwind() const { return getAssumed(); }
3537
3538 /// Returns true if nounwind is known.
3539 bool isKnownNoUnwind() const { return getKnown(); }
3540
3541 /// Create an abstract attribute view for the position \p IRP.
3543 Attributor &A);
3544
3545 /// See AbstractAttribute::getName()
3546 StringRef getName() const override { return "AANoUnwind"; }
3547
3548 /// See AbstractAttribute::getIdAddr()
3549 const char *getIdAddr() const override { return &ID; }
3550
3551 /// This function should return true if the type of the \p AA is AANoUnwind
3552 static bool classof(const AbstractAttribute *AA) {
3553 return (AA->getIdAddr() == &ID);
3554 }
3555
3556 /// Unique ID (due to the unique address)
3557 LLVM_ABI static const char ID;
3558};
3559
3561 : public IRAttribute<Attribute::NoSync,
3562 StateWrapper<BooleanState, AbstractAttribute>,
3563 AANoSync> {
3565
3566 static bool isImpliedByIR(Attributor &A, const IRPosition &IRP,
3567 Attribute::AttrKind ImpliedAttributeKind,
3568 bool IgnoreSubsumingPositions = false) {
3569 // Note: This is also run for non-IPO amendable functions.
3570 assert(ImpliedAttributeKind == Attribute::NoSync);
3571 if (A.hasAttr(IRP, {Attribute::NoSync}, IgnoreSubsumingPositions,
3572 Attribute::NoSync))
3573 return true;
3574
3575 // Check for readonly + non-convergent.
3576 // TODO: We should be able to use hasAttr for Attributes, not only
3577 // AttrKinds.
3579 if (!F || F->isConvergent())
3580 return false;
3581
3583 A.getAttrs(IRP, {Attribute::Memory}, Attrs, IgnoreSubsumingPositions);
3584
3586 for (const Attribute &Attr : Attrs)
3587 ME &= Attr.getMemoryEffects();
3588
3589 if (!ME.onlyReadsMemory())
3590 return false;
3591
3592 A.manifestAttrs(IRP, Attribute::get(F->getContext(), Attribute::NoSync));
3593 return true;
3594 }
3595
3596 /// See AbstractAttribute::isValidIRPositionForInit
3598 if (!IRP.isFunctionScope() &&
3600 return false;
3601 return IRAttribute::isValidIRPositionForInit(A, IRP);
3602 }
3603
3604 /// Returns true if "nosync" is assumed.
3605 bool isAssumedNoSync() const { return getAssumed(); }
3606
3607 /// Returns true if "nosync" is known.
3608 bool isKnownNoSync() const { return getKnown(); }
3609
3610 /// Helper function used to determine whether an instruction is non-relaxed
3611 /// atomic. In other words, if an atomic instruction does not have unordered
3612 /// or monotonic ordering
3613 LLVM_ABI static bool isNonRelaxedAtomic(const Instruction *I);
3614
3615 /// Helper function specific for intrinsics which are potentially volatile.
3616 LLVM_ABI static bool isNoSyncIntrinsic(const Instruction *I);
3617
3618 /// Helper function to determine if \p CB is an aligned (GPU) barrier. Aligned
3619 /// barriers have to be executed by all threads. The flag \p ExecutedAligned
3620 /// indicates if the call is executed by all threads in a (thread) block in an
3621 /// aligned way. If that is the case, non-aligned barriers are effectively
3622 /// aligned barriers.
3623 LLVM_ABI static bool isAlignedBarrier(const CallBase &CB,
3624 bool ExecutedAligned);
3625
3626 /// Create an abstract attribute view for the position \p IRP.
3628 Attributor &A);
3629
3630 /// See AbstractAttribute::getName()
3631 StringRef getName() const override { return "AANoSync"; }
3632
3633 /// See AbstractAttribute::getIdAddr()
3634 const char *getIdAddr() const override { return &ID; }
3635
3636 /// This function should return true if the type of the \p AA is AANoSync
3637 static bool classof(const AbstractAttribute *AA) {
3638 return (AA->getIdAddr() == &ID);
3639 }
3640
3641 /// Unique ID (due to the unique address)
3642 LLVM_ABI static const char ID;
3643};
3644
3645/// An abstract interface for all nonnull attributes.
3647 : public IRAttribute<Attribute::MustProgress,
3648 StateWrapper<BooleanState, AbstractAttribute>,
3649 AAMustProgress> {
3651
3652 static bool isImpliedByIR(Attributor &A, const IRPosition &IRP,
3653 Attribute::AttrKind ImpliedAttributeKind,
3654 bool IgnoreSubsumingPositions = false) {
3655 // Note: This is also run for non-IPO amendable functions.
3656 assert(ImpliedAttributeKind == Attribute::MustProgress);
3657 return A.hasAttr(IRP, {Attribute::MustProgress, Attribute::WillReturn},
3658 IgnoreSubsumingPositions, Attribute::MustProgress);
3659 }
3660
3661 /// Return true if we assume that the underlying value is nonnull.
3662 bool isAssumedMustProgress() const { return getAssumed(); }
3663
3664 /// Return true if we know that underlying value is nonnull.
3665 bool isKnownMustProgress() const { return getKnown(); }
3666
3667 /// Create an abstract attribute view for the position \p IRP.
3669 Attributor &A);
3670
3671 /// See AbstractAttribute::getName()
3672 StringRef getName() const override { return "AAMustProgress"; }
3673
3674 /// See AbstractAttribute::getIdAddr()
3675 const char *getIdAddr() const override { return &ID; }
3676
3677 /// This function should return true if the type of the \p AA is
3678 /// AAMustProgress
3679 static bool classof(const AbstractAttribute *AA) {
3680 return (AA->getIdAddr() == &ID);
3681 }
3682
3683 /// Unique ID (due to the unique address)
3684 LLVM_ABI static const char ID;
3685};
3686
3687/// An abstract interface for all nonnull attributes.
3689 : public IRAttribute<Attribute::NonNull,
3690 StateWrapper<BooleanState, AbstractAttribute>,
3691 AANonNull> {
3693
3694 /// See AbstractAttribute::hasTrivialInitializer.
3695 static bool hasTrivialInitializer() { return false; }
3696
3697 /// See IRAttribute::isImpliedByUndef.
3698 /// Undef is not necessarily nonnull as nonnull + noundef would cause poison.
3699 /// Poison implies nonnull though.
3700 static bool isImpliedByUndef() { return false; }
3701
3702 /// See AbstractAttribute::isValidIRPositionForInit
3705 return false;
3706 return IRAttribute::isValidIRPositionForInit(A, IRP);
3707 }
3708
3709 /// See AbstractAttribute::isImpliedByIR(...).
3710 LLVM_ABI static bool isImpliedByIR(Attributor &A, const IRPosition &IRP,
3711 Attribute::AttrKind ImpliedAttributeKind,
3712 bool IgnoreSubsumingPositions = false);
3713
3714 /// Return true if we assume that the underlying value is nonnull.
3715 bool isAssumedNonNull() const { return getAssumed(); }
3716
3717 /// Return true if we know that underlying value is nonnull.
3718 bool isKnownNonNull() const { return getKnown(); }
3719
3720 /// Create an abstract attribute view for the position \p IRP.
3722 Attributor &A);
3723
3724 /// See AbstractAttribute::getName()
3725 StringRef getName() const override { return "AANonNull"; }
3726
3727 /// See AbstractAttribute::getIdAddr()
3728 const char *getIdAddr() const override { return &ID; }
3729
3730 /// This function should return true if the type of the \p AA is AANonNull
3731 static bool classof(const AbstractAttribute *AA) {
3732 return (AA->getIdAddr() == &ID);
3733 }
3734
3735 /// Unique ID (due to the unique address)
3736 LLVM_ABI static const char ID;
3737};
3738
3739/// An abstract attribute for norecurse.
3741 : public IRAttribute<Attribute::NoRecurse,
3742 StateWrapper<BooleanState, AbstractAttribute>,
3743 AANoRecurse> {
3745
3746 /// Return true if "norecurse" is assumed.
3747 bool isAssumedNoRecurse() const { return getAssumed(); }
3748
3749 /// Return true if "norecurse" is known.
3750 bool isKnownNoRecurse() const { return getKnown(); }
3751
3752 /// Create an abstract attribute view for the position \p IRP.
3754 Attributor &A);
3755
3756 /// See AbstractAttribute::getName()
3757 StringRef getName() const override { return "AANoRecurse"; }
3758
3759 /// See AbstractAttribute::getIdAddr()
3760 const char *getIdAddr() const override { return &ID; }
3761
3762 /// This function should return true if the type of the \p AA is AANoRecurse
3763 static bool classof(const AbstractAttribute *AA) {
3764 return (AA->getIdAddr() == &ID);
3765 }
3766
3767 /// Unique ID (due to the unique address)
3768 LLVM_ABI static const char ID;
3769};
3770
3771/// An abstract attribute for willreturn.
3773 : public IRAttribute<Attribute::WillReturn,
3774 StateWrapper<BooleanState, AbstractAttribute>,
3775 AAWillReturn> {
3777
3778 static bool isImpliedByIR(Attributor &A, const IRPosition &IRP,
3779 Attribute::AttrKind ImpliedAttributeKind,
3780 bool IgnoreSubsumingPositions = false) {
3781 // Note: This is also run for non-IPO amendable functions.
3782 assert(ImpliedAttributeKind == Attribute::WillReturn);
3783 if (IRAttribute::isImpliedByIR(A, IRP, ImpliedAttributeKind,
3784 IgnoreSubsumingPositions))
3785 return true;
3787 return false;
3788 A.manifestAttrs(IRP, Attribute::get(IRP.getAnchorValue().getContext(),
3789 Attribute::WillReturn));
3790 return true;
3791 }
3792
3793 /// Check for `mustprogress` and `readonly` as they imply `willreturn`.
3795 const IRPosition &IRP) {
3796 // Check for `mustprogress` in the scope and the associated function which
3797 // might be different if this is a call site.
3798 if (!A.hasAttr(IRP, {Attribute::MustProgress}))
3799 return false;
3800
3802 A.getAttrs(IRP, {Attribute::Memory}, Attrs,
3803 /* IgnoreSubsumingPositions */ false);
3804
3806 for (const Attribute &Attr : Attrs)
3807 ME &= Attr.getMemoryEffects();
3808 return ME.onlyReadsMemory();
3809 }
3810
3811 /// Return true if "willreturn" is assumed.
3812 bool isAssumedWillReturn() const { return getAssumed(); }
3813
3814 /// Return true if "willreturn" is known.
3815 bool isKnownWillReturn() const { return getKnown(); }
3816
3817 /// Create an abstract attribute view for the position \p IRP.
3819 Attributor &A);
3820
3821 /// See AbstractAttribute::getName()
3822 StringRef getName() const override { return "AAWillReturn"; }
3823
3824 /// See AbstractAttribute::getIdAddr()
3825 const char *getIdAddr() const override { return &ID; }
3826
3827 /// This function should return true if the type of the \p AA is AAWillReturn
3828 static bool classof(const AbstractAttribute *AA) {
3829 return (AA->getIdAddr() == &ID);
3830 }
3831
3832 /// Unique ID (due to the unique address)
3833 LLVM_ABI static const char ID;
3834};
3835
3836/// An abstract attribute for undefined behavior.
3838 : public StateWrapper<BooleanState, AbstractAttribute> {
3841
3842 /// Return true if "undefined behavior" is assumed.
3843 bool isAssumedToCauseUB() const { return getAssumed(); }
3844
3845 /// Return true if "undefined behavior" is assumed for a specific instruction.
3846 virtual bool isAssumedToCauseUB(Instruction *I) const = 0;
3847
3848 /// Return true if "undefined behavior" is known.
3849 bool isKnownToCauseUB() const { return getKnown(); }
3850
3851 /// Return true if "undefined behavior" is known for a specific instruction.
3852 virtual bool isKnownToCauseUB(Instruction *I) const = 0;
3853
3854 /// Create an abstract attribute view for the position \p IRP.
3856 Attributor &A);
3857
3858 /// See AbstractAttribute::getName()
3859 StringRef getName() const override { return "AAUndefinedBehavior"; }
3860
3861 /// See AbstractAttribute::getIdAddr()
3862 const char *getIdAddr() const override { return &ID; }
3863
3864 /// This function should return true if the type of the \p AA is
3865 /// AAUndefineBehavior
3866 static bool classof(const AbstractAttribute *AA) {
3867 return (AA->getIdAddr() == &ID);
3868 }
3869
3870 /// Unique ID (due to the unique address)
3871 LLVM_ABI static const char ID;
3872};
3873
3874/// An abstract interface to determine reachability of point A to B.
3876 : public StateWrapper<BooleanState, AbstractAttribute> {
3879
3880 /// Returns true if 'From' instruction is assumed to reach, 'To' instruction.
3881 /// Users should provide two positions they are interested in, and the class
3882 /// determines (and caches) reachability.
3884 Attributor &A, const Instruction &From, const Instruction &To,
3885 const AA::InstExclusionSetTy *ExclusionSet = nullptr) const = 0;
3886
3887 /// Create an abstract attribute view for the position \p IRP.
3890
3891 /// See AbstractAttribute::getName()
3892 StringRef getName() const override { return "AAIntraFnReachability"; }
3893
3894 /// See AbstractAttribute::getIdAddr()
3895 const char *getIdAddr() const override { return &ID; }
3896
3897 /// This function should return true if the type of the \p AA is
3898 /// AAIntraFnReachability
3899 static bool classof(const AbstractAttribute *AA) {
3900 return (AA->getIdAddr() == &ID);
3901 }
3902
3903 /// Unique ID (due to the unique address)
3904 LLVM_ABI static const char ID;
3905};
3906
3907/// An abstract interface for all noalias attributes.
3909 : public IRAttribute<Attribute::NoAlias,
3910 StateWrapper<BooleanState, AbstractAttribute>,
3911 AANoAlias> {
3913
3914 /// See AbstractAttribute::isValidIRPositionForInit
3916 if (!IRP.getAssociatedType()->isPointerTy())
3917 return false;
3918 return IRAttribute::isValidIRPositionForInit(A, IRP);
3919 }
3920
3921 /// See IRAttribute::isImpliedByIR
3922 LLVM_ABI static bool isImpliedByIR(Attributor &A, const IRPosition &IRP,
3923 Attribute::AttrKind ImpliedAttributeKind,
3924 bool IgnoreSubsumingPositions = false);
3925
3926 /// See AbstractAttribute::requiresCallersForArgOrFunction
3927 static bool requiresCallersForArgOrFunction() { return true; }
3928
3929 /// Return true if we assume that the underlying value is alias.
3930 bool isAssumedNoAlias() const { return getAssumed(); }
3931
3932 /// Return true if we know that underlying value is noalias.
3933 bool isKnownNoAlias() const { return getKnown(); }
3934
3935 /// Create an abstract attribute view for the position \p IRP.
3937 Attributor &A);
3938
3939 /// See AbstractAttribute::getName()
3940 StringRef getName() const override { return "AANoAlias"; }
3941
3942 /// See AbstractAttribute::getIdAddr()
3943 const char *getIdAddr() const override { return &ID; }
3944
3945 /// This function should return true if the type of the \p AA is AANoAlias
3946 static bool classof(const AbstractAttribute *AA) {
3947 return (AA->getIdAddr() == &ID);
3948 }
3949
3950 /// Unique ID (due to the unique address)
3951 LLVM_ABI static const char ID;
3952};
3953
3954/// An AbstractAttribute for nofree.
3956 : public IRAttribute<Attribute::NoFree,
3957 StateWrapper<BooleanState, AbstractAttribute>,
3958 AANoFree> {
3960
3961 /// See IRAttribute::isImpliedByIR
3962 static bool isImpliedByIR(Attributor &A, const IRPosition &IRP,
3963 Attribute::AttrKind ImpliedAttributeKind,
3964 bool IgnoreSubsumingPositions = false) {
3965 // Note: This is also run for non-IPO amendable functions.
3966 assert(ImpliedAttributeKind == Attribute::NoFree);
3967 return A.hasAttr(
3968 IRP, {Attribute::ReadNone, Attribute::ReadOnly, Attribute::NoFree},
3969 IgnoreSubsumingPositions, Attribute::NoFree);
3970 }
3971
3972 /// See AbstractAttribute::isValidIRPositionForInit
3974 if (!IRP.isFunctionScope() &&
3976 return false;
3977 return IRAttribute::isValidIRPositionForInit(A, IRP);
3978 }
3979
3980 /// Return true if "nofree" is assumed.
3981 bool isAssumedNoFree() const { return getAssumed(); }
3982
3983 /// Return true if "nofree" is known.
3984 bool isKnownNoFree() const { return getKnown(); }
3985
3986 /// Create an abstract attribute view for the position \p IRP.
3988 Attributor &A);
3989
3990 /// See AbstractAttribute::getName()
3991 StringRef getName() const override { return "AANoFree"; }
3992
3993 /// See AbstractAttribute::getIdAddr()
3994 const char *getIdAddr() const override { return &ID; }
3995
3996 /// This function should return true if the type of the \p AA is AANoFree
3997 static bool classof(const AbstractAttribute *AA) {
3998 return (AA->getIdAddr() == &ID);
3999 }
4000
4001 /// Unique ID (due to the unique address)
4002 LLVM_ABI static const char ID;
4003};
4004
4005/// An AbstractAttribute for noreturn.
4007 : public IRAttribute<Attribute::NoReturn,
4008 StateWrapper<BooleanState, AbstractAttribute>,
4009 AANoReturn> {
4011
4012 /// Return true if the underlying object is assumed to never return.
4013 bool isAssumedNoReturn() const { return getAssumed(); }
4014
4015 /// Return true if the underlying object is known to never return.
4016 bool isKnownNoReturn() const { return getKnown(); }
4017
4018 /// Create an abstract attribute view for the position \p IRP.
4020 Attributor &A);
4021
4022 /// See AbstractAttribute::getName()
4023 StringRef getName() const override { return "AANoReturn"; }
4024
4025 /// See AbstractAttribute::getIdAddr()
4026 const char *getIdAddr() const override { return &ID; }
4027
4028 /// This function should return true if the type of the \p AA is AANoReturn
4029 static bool classof(const AbstractAttribute *AA) {
4030 return (AA->getIdAddr() == &ID);
4031 }
4032
4033 /// Unique ID (due to the unique address)
4034 LLVM_ABI static const char ID;
4035};
4036
4037/// An abstract interface for liveness abstract attribute.
4039 : public StateWrapper<BitIntegerState<uint8_t, 3, 0>, AbstractAttribute> {
4041 AAIsDead(const IRPosition &IRP, Attributor &A) : Base(IRP) {}
4042
4043 /// See AbstractAttribute::isValidIRPositionForInit
4046 return isa<Function>(IRP.getAnchorValue()) &&
4047 !cast<Function>(IRP.getAnchorValue()).isDeclaration();
4048 return true;
4049 }
4050
4051 /// State encoding bits. A set bit in the state means the property holds.
4052 enum {
4055
4057 };
4058 static_assert(IS_DEAD == getBestState(), "Unexpected BEST_STATE value");
4059
4060protected:
4061 /// The query functions are protected such that other attributes need to go
4062 /// through the Attributor interfaces: `Attributor::isAssumedDead(...)`
4063
4064 /// Returns true if the underlying value is assumed dead.
4065 virtual bool isAssumedDead() const = 0;
4066
4067 /// Returns true if the underlying value is known dead.
4068 virtual bool isKnownDead() const = 0;
4069
4070 /// Returns true if \p BB is known dead.
4071 virtual bool isKnownDead(const BasicBlock *BB) const = 0;
4072
4073 /// Returns true if \p I is assumed dead.
4074 virtual bool isAssumedDead(const Instruction *I) const = 0;
4075
4076 /// Returns true if \p I is known dead.
4077 virtual bool isKnownDead(const Instruction *I) const = 0;
4078
4079 /// Return true if the underlying value is a store that is known to be
4080 /// removable. This is different from dead stores as the removable store
4081 /// can have an effect on live values, especially loads, but that effect
4082 /// is propagated which allows us to remove the store in turn.
4083 virtual bool isRemovableStore() const { return false; }
4084
4085 /// This method is used to check if at least one instruction in a collection
4086 /// of instructions is live.
4087 template <typename T> bool isLiveInstSet(T begin, T end) const {
4088 for (const auto &I : llvm::make_range(begin, end)) {
4089 assert(I->getFunction() == getIRPosition().getAssociatedFunction() &&
4090 "Instruction must be in the same anchor scope function.");
4091
4092 if (!isAssumedDead(I))
4093 return true;
4094 }
4095
4096 return false;
4097 }
4098
4099public:
4100 /// Create an abstract attribute view for the position \p IRP.
4102 Attributor &A);
4103
4104 /// Determine if \p F might catch asynchronous exceptions.
4106 return F.hasPersonalityFn() && !canSimplifyInvokeNoUnwind(&F);
4107 }
4108
4109 /// Returns true if \p BB is assumed dead.
4110 virtual bool isAssumedDead(const BasicBlock *BB) const = 0;
4111
4112 /// Return if the edge from \p From BB to \p To BB is assumed dead.
4113 /// This is specifically useful in AAReachability.
4114 virtual bool isEdgeDead(const BasicBlock *From, const BasicBlock *To) const {
4115 return false;
4116 }
4117
4118 /// See AbstractAttribute::getName()
4119 StringRef getName() const override { return "AAIsDead"; }
4120
4121 /// See AbstractAttribute::getIdAddr()
4122 const char *getIdAddr() const override { return &ID; }
4123
4124 /// This function should return true if the type of the \p AA is AAIsDead
4125 static bool classof(const AbstractAttribute *AA) {
4126 return (AA->getIdAddr() == &ID);
4127 }
4128
4129 /// Unique ID (due to the unique address)
4130 LLVM_ABI static const char ID;
4131
4132 friend struct Attributor;
4133};
4134
4135/// State for dereferenceable attribute
4137
4138 static DerefState getBestState() { return DerefState(); }
4139 static DerefState getBestState(const DerefState &) { return getBestState(); }
4140
4141 /// Return the worst possible representable state.
4143 DerefState DS;
4145 return DS;
4146 }
4148 return getWorstState();
4149 }
4150
4151 /// State representing for dereferenceable bytes.
4153
4154 /// Map representing for accessed memory offsets and sizes.
4155 /// A key is Offset and a value is size.
4156 /// If there is a load/store instruction something like,
4157 /// p[offset] = v;
4158 /// (offset, sizeof(v)) will be inserted to this map.
4159 /// std::map is used because we want to iterate keys in ascending order.
4160 std::map<int64_t, uint64_t> AccessedBytesMap;
4161
4162 /// Helper function to calculate dereferenceable bytes from current known
4163 /// bytes and accessed bytes.
4164 ///
4165 /// int f(int *A){
4166 /// *A = 0;
4167 /// *(A+2) = 2;
4168 /// *(A+1) = 1;
4169 /// *(A+10) = 10;
4170 /// }
4171 /// ```
4172 /// In that case, AccessedBytesMap is `{0:4, 4:4, 8:4, 40:4}`.
4173 /// AccessedBytesMap is std::map so it is iterated in accending order on
4174 /// key(Offset). So KnownBytes will be updated like this:
4175 ///
4176 /// |Access | KnownBytes
4177 /// |(0, 4)| 0 -> 4
4178 /// |(4, 4)| 4 -> 8
4179 /// |(8, 4)| 8 -> 12
4180 /// |(40, 4) | 12 (break)
4181 void computeKnownDerefBytesFromAccessedMap() {
4182 int64_t KnownBytes = DerefBytesState.getKnown();
4183 for (auto &Access : AccessedBytesMap) {
4184 if (KnownBytes < Access.first)
4185 break;
4186 KnownBytes = std::max(KnownBytes, Access.first + (int64_t)Access.second);
4187 }
4188
4189 DerefBytesState.takeKnownMaximum(KnownBytes);
4190 }
4191
4192 /// State representing that whether the value is globaly dereferenceable.
4193 BooleanState GlobalState;
4194
4195 /// See AbstractState::isValidState()
4196 bool isValidState() const override { return DerefBytesState.isValidState(); }
4197
4198 /// See AbstractState::isAtFixpoint()
4199 bool isAtFixpoint() const override {
4200 return !isValidState() ||
4201 (DerefBytesState.isAtFixpoint() && GlobalState.isAtFixpoint());
4202 }
4203
4204 /// See AbstractState::indicateOptimisticFixpoint(...)
4206 DerefBytesState.indicateOptimisticFixpoint();
4207 GlobalState.indicateOptimisticFixpoint();
4209 }
4210
4211 /// See AbstractState::indicatePessimisticFixpoint(...)
4213 DerefBytesState.indicatePessimisticFixpoint();
4214 GlobalState.indicatePessimisticFixpoint();
4215 return ChangeStatus::CHANGED;
4216 }
4217
4218 /// Update known dereferenceable bytes.
4219 void takeKnownDerefBytesMaximum(uint64_t Bytes) {
4220 DerefBytesState.takeKnownMaximum(Bytes);
4221
4222 // Known bytes might increase.
4223 computeKnownDerefBytesFromAccessedMap();
4224 }
4225
4226 /// Update assumed dereferenceable bytes.
4227 void takeAssumedDerefBytesMinimum(uint64_t Bytes) {
4228 DerefBytesState.takeAssumedMinimum(Bytes);
4229 }
4230
4231 /// Add accessed bytes to the map.
4232 void addAccessedBytes(int64_t Offset, uint64_t Size) {
4233 uint64_t &AccessedBytes = AccessedBytesMap[Offset];
4234 AccessedBytes = std::max(AccessedBytes, Size);
4235
4236 // Known bytes might increase.
4237 computeKnownDerefBytesFromAccessedMap();
4238 }
4239
4240 /// Equality for DerefState.
4241 bool operator==(const DerefState &R) const {
4242 return this->DerefBytesState == R.DerefBytesState &&
4243 this->GlobalState == R.GlobalState;
4244 }
4245
4246 /// Inequality for DerefState.
4247 bool operator!=(const DerefState &R) const { return !(*this == R); }
4248
4249 /// See IntegerStateBase::operator^=
4250 DerefState operator^=(const DerefState &R) {
4251 DerefBytesState ^= R.DerefBytesState;
4252 GlobalState ^= R.GlobalState;
4253 return *this;
4254 }
4255
4256 /// See IntegerStateBase::operator+=
4257 DerefState operator+=(const DerefState &R) {
4258 DerefBytesState += R.DerefBytesState;
4259 GlobalState += R.GlobalState;
4260 return *this;
4261 }
4262
4263 /// See IntegerStateBase::operator&=
4264 DerefState operator&=(const DerefState &R) {
4265 DerefBytesState &= R.DerefBytesState;
4266 GlobalState &= R.GlobalState;
4267 return *this;
4268 }
4269
4270 /// See IntegerStateBase::operator|=
4271 DerefState operator|=(const DerefState &R) {
4272 DerefBytesState |= R.DerefBytesState;
4273 GlobalState |= R.GlobalState;
4274 return *this;
4275 }
4276};
4277
4278/// An abstract interface for all dereferenceable attribute.
4280 : public IRAttribute<Attribute::Dereferenceable,
4281 StateWrapper<DerefState, AbstractAttribute>,
4282 AADereferenceable> {
4284
4285 /// See AbstractAttribute::isValidIRPositionForInit
4287 if (!IRP.getAssociatedType()->isPointerTy())
4288 return false;
4289 return IRAttribute::isValidIRPositionForInit(A, IRP);
4290 }
4291
4292 /// Return true if we assume that underlying value is
4293 /// dereferenceable(_or_null) globally.
4294 bool isAssumedGlobal() const { return GlobalState.getAssumed(); }
4295
4296 /// Return true if we know that underlying value is
4297 /// dereferenceable(_or_null) globally.
4298 bool isKnownGlobal() const { return GlobalState.getKnown(); }
4299
4300 /// Return assumed dereferenceable bytes.
4302 return DerefBytesState.getAssumed();
4303 }
4304
4305 /// Return known dereferenceable bytes.
4307 return DerefBytesState.getKnown();
4308 }
4309
4310 /// Create an abstract attribute view for the position \p IRP.
4312 Attributor &A);
4313
4314 /// See AbstractAttribute::getName()
4315 StringRef getName() const override { return "AADereferenceable"; }
4316
4317 /// See AbstractAttribute::getIdAddr()
4318 const char *getIdAddr() const override { return &ID; }
4319
4320 /// This function should return true if the type of the \p AA is
4321 /// AADereferenceable
4322 static bool classof(const AbstractAttribute *AA) {
4323 return (AA->getIdAddr() == &ID);
4324 }
4325
4326 /// Unique ID (due to the unique address)
4327 LLVM_ABI static const char ID;
4328};
4329
4332/// An abstract interface for all align attributes.
4334 : public IRAttribute<Attribute::Alignment,
4335 StateWrapper<AAAlignmentStateType, AbstractAttribute>,
4336 AAAlign> {
4338
4339 /// See AbstractAttribute::isValidIRPositionForInit
4342 return false;
4343 return IRAttribute::isValidIRPositionForInit(A, IRP);
4344 }
4345
4346 /// Return assumed alignment.
4347 Align getAssumedAlign() const { return Align(getAssumed()); }
4348
4349 /// Return known alignment.
4350 Align getKnownAlign() const { return Align(getKnown()); }
4351
4352 /// See AbstractAttribute::getName()
4353 StringRef getName() const override { return "AAAlign"; }
4354
4355 /// See AbstractAttribute::getIdAddr()
4356 const char *getIdAddr() const override { return &ID; }
4357
4358 /// This function should return true if the type of the \p AA is AAAlign
4359 static bool classof(const AbstractAttribute *AA) {
4360 return (AA->getIdAddr() == &ID);
4361 }
4362
4363 /// Create an abstract attribute view for the position \p IRP.
4365 Attributor &A);
4366
4367 /// Unique ID (due to the unique address)
4368 LLVM_ABI static const char ID;
4369};
4370
4371/// An abstract interface to track if a value leaves it's defining function
4372/// instance.
4373/// TODO: We should make it a ternary AA tracking uniqueness, and uniqueness
4374/// wrt. the Attributor analysis separately.
4375struct AAInstanceInfo : public StateWrapper<BooleanState, AbstractAttribute> {
4378
4379 /// Return true if we know that the underlying value is unique in its scope
4380 /// wrt. the Attributor analysis. That means it might not be unique but we can
4381 /// still use pointer equality without risking to represent two instances with
4382 /// one `llvm::Value`.
4383 bool isKnownUniqueForAnalysis() const { return isKnown(); }
4384
4385 /// Return true if we assume that the underlying value is unique in its scope
4386 /// wrt. the Attributor analysis. That means it might not be unique but we can
4387 /// still use pointer equality without risking to represent two instances with
4388 /// one `llvm::Value`.
4389 bool isAssumedUniqueForAnalysis() const { return isAssumed(); }
4390
4391 /// Create an abstract attribute view for the position \p IRP.
4393 Attributor &A);
4394
4395 /// See AbstractAttribute::getName()
4396 StringRef getName() const override { return "AAInstanceInfo"; }
4397
4398 /// See AbstractAttribute::getIdAddr()
4399 const char *getIdAddr() const override { return &ID; }
4400
4401 /// This function should return true if the type of the \p AA is
4402 /// AAInstanceInfo
4403 static bool classof(const AbstractAttribute *AA) {
4404 return (AA->getIdAddr() == &ID);
4405 }
4406
4407 /// Unique ID (due to the unique address)
4408 LLVM_ABI static const char ID;
4409};
4410
4411/// An abstract interface for all nocapture attributes.
4413 : public IRAttribute<
4414 Attribute::Captures,
4415 StateWrapper<BitIntegerState<uint16_t, 7, 0>, AbstractAttribute>,
4416 AANoCapture> {
4418
4419 /// See IRAttribute::isImpliedByIR
4420 LLVM_ABI static bool isImpliedByIR(Attributor &A, const IRPosition &IRP,
4421 Attribute::AttrKind ImpliedAttributeKind,
4422 bool IgnoreSubsumingPositions = false);
4423
4424 /// Update \p State according to the capture capabilities of \p F for position
4425 /// \p IRP.
4426 LLVM_ABI static void
4428 BitIntegerState &State);
4429
4430 /// See AbstractAttribute::isValidIRPositionForInit
4432 if (!IRP.getAssociatedType()->isPointerTy())
4433 return false;
4434 return IRAttribute::isValidIRPositionForInit(A, IRP);
4435 }
4436
4437 /// State encoding bits. A set bit in the state means the property holds.
4438 /// NO_CAPTURE is the best possible state, 0 the worst possible state.
4439 enum {
4443
4444 /// If we do not capture the value in memory or through integers we can only
4445 /// communicate it back as a derived pointer.
4447
4448 /// If we do not capture the value in memory, through integers, or as a
4449 /// derived pointer we know it is not captured.
4452 };
4453
4454 /// Return true if we know that the underlying value is not captured in its
4455 /// respective scope.
4456 bool isKnownNoCapture() const { return isKnown(NO_CAPTURE); }
4457
4458 /// Return true if we assume that the underlying value is not captured in its
4459 /// respective scope.
4460 bool isAssumedNoCapture() const { return isAssumed(NO_CAPTURE); }
4461
4462 /// Return true if we know that the underlying value is not captured in its
4463 /// respective scope but we allow it to escape through a "return".
4467
4468 /// Return true if we assume that the underlying value is not captured in its
4469 /// respective scope but we allow it to escape through a "return".
4473
4474 /// Create an abstract attribute view for the position \p IRP.
4476 Attributor &A);
4477
4478 /// See AbstractAttribute::getName()
4479 StringRef getName() const override { return "AANoCapture"; }
4480
4481 /// See AbstractAttribute::getIdAddr()
4482 const char *getIdAddr() const override { return &ID; }
4483
4484 /// This function should return true if the type of the \p AA is AANoCapture
4485 static bool classof(const AbstractAttribute *AA) {
4486 return (AA->getIdAddr() == &ID);
4487 }
4488
4489 /// Unique ID (due to the unique address)
4490 LLVM_ABI static const char ID;
4491};
4492
4494
4496
4501 return getBestState(VS.Ty);
4502 }
4503
4504 /// Return the worst possible representable state.
4507 DS.indicatePessimisticFixpoint();
4508 return DS;
4509 }
4512 return getWorstState(VS.Ty);
4513 }
4514
4515 /// See AbstractState::isValidState(...)
4516 bool isValidState() const override { return BS.isValidState(); }
4517
4518 /// See AbstractState::isAtFixpoint(...)
4519 bool isAtFixpoint() const override { return BS.isAtFixpoint(); }
4520
4521 /// Return the assumed state encoding.
4523 const ValueSimplifyStateType &getAssumed() const { return *this; }
4524
4525 /// See AbstractState::indicatePessimisticFixpoint(...)
4527 return BS.indicatePessimisticFixpoint();
4528 }
4529
4530 /// See AbstractState::indicateOptimisticFixpoint(...)
4532 return BS.indicateOptimisticFixpoint();
4533 }
4534
4535 /// "Clamp" this state with \p PVS.
4537 BS ^= VS.BS;
4538 unionAssumed(VS.SimplifiedAssociatedValue);
4539 return *this;
4540 }
4541
4543 if (isValidState() != RHS.isValidState())
4544 return false;
4545 if (!isValidState() && !RHS.isValidState())
4546 return true;
4547 return SimplifiedAssociatedValue == RHS.SimplifiedAssociatedValue;
4548 }
4549
4550protected:
4551 /// The type of the original value.
4553
4554 /// Merge \p Other into the currently assumed simplified value
4555 LLVM_ABI bool unionAssumed(std::optional<Value *> Other);
4556
4557 /// Helper to track validity and fixpoint
4559
4560 /// An assumed simplified value. Initially, it is set to std::nullopt, which
4561 /// means that the value is not clear under current assumption. If in the
4562 /// pessimistic state, getAssumedSimplifiedValue doesn't return this value but
4563 /// returns orignal associated value.
4564 std::optional<Value *> SimplifiedAssociatedValue;
4565};
4566
4567/// An abstract interface for value simplify abstract attribute.
4569 : public StateWrapper<ValueSimplifyStateType, AbstractAttribute, Type *> {
4572 : Base(IRP, IRP.getAssociatedType()) {}
4573
4574 /// Create an abstract attribute view for the position \p IRP.
4576 Attributor &A);
4577
4578 /// See AbstractAttribute::getName()
4579 StringRef getName() const override { return "AAValueSimplify"; }
4580
4581 /// See AbstractAttribute::getIdAddr()
4582 const char *getIdAddr() const override { return &ID; }
4583
4584 /// This function should return true if the type of the \p AA is
4585 /// AAValueSimplify
4586 static bool classof(const AbstractAttribute *AA) {
4587 return (AA->getIdAddr() == &ID);
4588 }
4589
4590 /// Unique ID (due to the unique address)
4591 LLVM_ABI static const char ID;
4592
4593private:
4594 /// Return an assumed simplified value if a single candidate is found. If
4595 /// there cannot be one, return original value. If it is not clear yet, return
4596 /// std::nullopt.
4597 ///
4598 /// Use `Attributor::getAssumedSimplified` for value simplification.
4599 virtual std::optional<Value *>
4600 getAssumedSimplifiedValue(Attributor &A) const = 0;
4601
4602 friend struct Attributor;
4603};
4604
4605struct AAHeapToStack : public StateWrapper<BooleanState, AbstractAttribute> {
4607 AAHeapToStack(const IRPosition &IRP, Attributor &A) : Base(IRP) {}
4608
4609 /// Returns true if HeapToStack conversion is assumed to be possible.
4610 virtual bool isAssumedHeapToStack(const CallBase &CB) const = 0;
4611
4612 /// Returns true if HeapToStack conversion is assumed and the CB is a
4613 /// callsite to a free operation to be removed.
4614 virtual bool isAssumedHeapToStackRemovedFree(CallBase &CB) const = 0;
4615
4616 /// Create an abstract attribute view for the position \p IRP.
4618 Attributor &A);
4619
4620 /// See AbstractAttribute::getName()
4621 StringRef getName() const override { return "AAHeapToStack"; }
4622
4623 /// See AbstractAttribute::getIdAddr()
4624 const char *getIdAddr() const override { return &ID; }
4625
4626 /// This function should return true if the type of the \p AA is AAHeapToStack
4627 static bool classof(const AbstractAttribute *AA) {
4628 return (AA->getIdAddr() == &ID);
4629 }
4630
4631 /// Unique ID (due to the unique address)
4632 LLVM_ABI static const char ID;
4633};
4634
4635/// An abstract interface for privatizability.
4636///
4637/// A pointer is privatizable if it can be replaced by a new, private one.
4638/// Privatizing pointer reduces the use count, interaction between unrelated
4639/// code parts.
4640///
4641/// In order for a pointer to be privatizable its value cannot be observed
4642/// (=nocapture), it is (for now) not written (=readonly & noalias), we know
4643/// what values are necessary to make the private copy look like the original
4644/// one, and the values we need can be loaded (=dereferenceable).
4646 : public StateWrapper<BooleanState, AbstractAttribute> {
4649
4650 /// See AbstractAttribute::isValidIRPositionForInit
4653 return false;
4655 }
4656
4657 /// Returns true if pointer privatization is assumed to be possible.
4658 bool isAssumedPrivatizablePtr() const { return getAssumed(); }
4659
4660 /// Returns true if pointer privatization is known to be possible.
4661 bool isKnownPrivatizablePtr() const { return getKnown(); }
4662
4663 /// See AbstractAttribute::requiresCallersForArgOrFunction
4664 static bool requiresCallersForArgOrFunction() { return true; }
4665
4666 /// Return the type we can choose for a private copy of the underlying
4667 /// value. std::nullopt means it is not clear yet, nullptr means there is
4668 /// none.
4669 virtual std::optional<Type *> getPrivatizableType() const = 0;
4670
4671 /// Create an abstract attribute view for the position \p IRP.
4673 Attributor &A);
4674
4675 /// See AbstractAttribute::getName()
4676 StringRef getName() const override { return "AAPrivatizablePtr"; }
4677
4678 /// See AbstractAttribute::getIdAddr()
4679 const char *getIdAddr() const override { return &ID; }
4680
4681 /// This function should return true if the type of the \p AA is
4682 /// AAPricatizablePtr
4683 static bool classof(const AbstractAttribute *AA) {
4684 return (AA->getIdAddr() == &ID);
4685 }
4686
4687 /// Unique ID (due to the unique address)
4688 LLVM_ABI static const char ID;
4689};
4690
4691/// An abstract interface for memory access kind related attributes
4692/// (readnone/readonly/writeonly).
4694 : public IRAttribute<
4695 Attribute::None,
4696 StateWrapper<BitIntegerState<uint8_t, 3>, AbstractAttribute>,
4697 AAMemoryBehavior> {
4699
4700 /// See AbstractAttribute::hasTrivialInitializer.
4701 static bool hasTrivialInitializer() { return false; }
4702
4703 /// See AbstractAttribute::isValidIRPositionForInit
4705 if (!IRP.isFunctionScope() && !IRP.getAssociatedType()->isPointerTy())
4706 return false;
4707 return IRAttribute::isValidIRPositionForInit(A, IRP);
4708 }
4709
4710 /// State encoding bits. A set bit in the state means the property holds.
4711 /// BEST_STATE is the best possible state, 0 the worst possible state.
4712 enum {
4713 NO_READS = 1 << 0,
4714 NO_WRITES = 1 << 1,
4716
4718 };
4719 static_assert(BEST_STATE == getBestState(), "Unexpected BEST_STATE value");
4720
4721 /// Return true if we know that the underlying value is not read or accessed
4722 /// in its respective scope.
4723 bool isKnownReadNone() const { return isKnown(NO_ACCESSES); }
4724
4725 /// Return true if we assume that the underlying value is not read or accessed
4726 /// in its respective scope.
4727 bool isAssumedReadNone() const { return isAssumed(NO_ACCESSES); }
4728
4729 /// Return true if we know that the underlying value is not accessed
4730 /// (=written) in its respective scope.
4731 bool isKnownReadOnly() const { return isKnown(NO_WRITES); }
4732
4733 /// Return true if we assume that the underlying value is not accessed
4734 /// (=written) in its respective scope.
4735 bool isAssumedReadOnly() const { return isAssumed(NO_WRITES); }
4736
4737 /// Return true if we know that the underlying value is not read in its
4738 /// respective scope.
4739 bool isKnownWriteOnly() const { return isKnown(NO_READS); }
4740
4741 /// Return true if we assume that the underlying value is not read in its
4742 /// respective scope.
4743 bool isAssumedWriteOnly() const { return isAssumed(NO_READS); }
4744
4745 /// Create an abstract attribute view for the position \p IRP.
4747 Attributor &A);
4748
4749 /// See AbstractAttribute::getName()
4750 StringRef getName() const override { return "AAMemoryBehavior"; }
4751
4752 /// See AbstractAttribute::getIdAddr()
4753 const char *getIdAddr() const override { return &ID; }
4754
4755 /// This function should return true if the type of the \p AA is
4756 /// AAMemoryBehavior
4757 static bool classof(const AbstractAttribute *AA) {
4758 return (AA->getIdAddr() == &ID);
4759 }
4760
4761 /// Unique ID (due to the unique address)
4762 LLVM_ABI static const char ID;
4763};
4764
4765/// An abstract interface for all memory location attributes
4766/// (readnone/argmemonly/inaccessiblememonly/inaccessibleorargmemonly).
4768 : public IRAttribute<
4769 Attribute::None,
4770 StateWrapper<BitIntegerState<uint32_t, 511>, AbstractAttribute>,
4771 AAMemoryLocation> {
4772 using MemoryLocationsKind = StateType::base_t;
4773
4775
4776 /// See AbstractAttribute::requiresCalleeForCallBase.
4777 static bool requiresCalleeForCallBase() { return true; }
4778
4779 /// See AbstractAttribute::hasTrivialInitializer.
4780 static bool hasTrivialInitializer() { return false; }
4781
4782 /// See AbstractAttribute::isValidIRPositionForInit
4784 if (!IRP.isFunctionScope() &&
4786 return false;
4787 return IRAttribute::isValidIRPositionForInit(A, IRP);
4788 }
4789
4790 /// Encoding of different locations that could be accessed by a memory
4791 /// access.
4792 enum {
4806
4807 // Helper bit to track if we gave up or not.
4809
4811 };
4812 static_assert(BEST_STATE == getBestState(), "Unexpected BEST_STATE value");
4813
4814 /// Return true if we know that the associated functions has no observable
4815 /// accesses.
4816 bool isKnownReadNone() const { return isKnown(NO_LOCATIONS); }
4817
4818 /// Return true if we assume that the associated functions has no observable
4819 /// accesses.
4820 bool isAssumedReadNone() const {
4822 }
4823
4824 /// Return true if we know that the associated functions has at most
4825 /// local/stack accesses.
4826 bool isKnowStackOnly() const {
4827 return isKnown(inverseLocation(NO_LOCAL_MEM, true, true));
4828 }
4829
4830 /// Return true if we assume that the associated functions has at most
4831 /// local/stack accesses.
4832 bool isAssumedStackOnly() const {
4833 return isAssumed(inverseLocation(NO_LOCAL_MEM, true, true));
4834 }
4835
4836 /// Return true if we know that the underlying value will only access
4837 /// inaccesible memory only (see Attribute::InaccessibleMemOnly).
4839 return isKnown(inverseLocation(NO_INACCESSIBLE_MEM, true, true));
4840 }
4841
4842 /// Return true if we assume that the underlying value will only access
4843 /// inaccesible memory only (see Attribute::InaccessibleMemOnly).
4845 return isAssumed(inverseLocation(NO_INACCESSIBLE_MEM, true, true));
4846 }
4847
4848 /// Return true if we know that the underlying value will only access
4849 /// argument pointees (see Attribute::ArgMemOnly).
4850 bool isKnownArgMemOnly() const {
4851 return isKnown(inverseLocation(NO_ARGUMENT_MEM, true, true));
4852 }
4853
4854 /// Return true if we assume that the underlying value will only access
4855 /// argument pointees (see Attribute::ArgMemOnly).
4856 bool isAssumedArgMemOnly() const {
4857 return isAssumed(inverseLocation(NO_ARGUMENT_MEM, true, true));
4858 }
4859
4860 /// Return true if we know that the underlying value will only access
4861 /// inaccesible memory or argument pointees (see
4862 /// Attribute::InaccessibleOrArgMemOnly).
4864 return isKnown(
4866 }
4867
4868 /// Return true if we assume that the underlying value will only access
4869 /// inaccesible memory or argument pointees (see
4870 /// Attribute::InaccessibleOrArgMemOnly).
4875
4876 /// Return true if the underlying value may access memory through arguement
4877 /// pointers of the associated function, if any.
4878 bool mayAccessArgMem() const { return !isAssumed(NO_ARGUMENT_MEM); }
4879
4880 /// Return true if only the memory locations specififed by \p MLK are assumed
4881 /// to be accessed by the associated function.
4883 return isAssumed(MLK);
4884 }
4885
4886 /// Return the locations that are assumed to be not accessed by the associated
4887 /// function, if any.
4891
4892 /// Return the inverse of location \p Loc, thus for NO_XXX the return
4893 /// describes ONLY_XXX. The flags \p AndLocalMem and \p AndConstMem determine
4894 /// if local (=stack) and constant memory are allowed as well. Most of the
4895 /// time we do want them to be included, e.g., argmemonly allows accesses via
4896 /// argument pointers or local or constant memory accesses.
4897 static MemoryLocationsKind
4898 inverseLocation(MemoryLocationsKind Loc, bool AndLocalMem, bool AndConstMem) {
4899 return NO_LOCATIONS & ~(Loc | (AndLocalMem ? NO_LOCAL_MEM : 0) |
4900 (AndConstMem ? NO_CONST_MEM : 0));
4901 };
4902
4903 /// Return the locations encoded by \p MLK as a readable string.
4905
4906 /// Simple enum to distinguish read/write/read-write accesses.
4908 NONE = 0,
4909 READ = 1 << 0,
4910 WRITE = 1 << 1,
4912 };
4913
4914 /// Check \p Pred on all accesses to the memory kinds specified by \p MLK.
4915 ///
4916 /// This method will evaluate \p Pred on all accesses (access instruction +
4917 /// underlying accessed memory pointer) and it will return true if \p Pred
4918 /// holds every time.
4920 function_ref<bool(const Instruction *, const Value *, AccessKind,
4922 Pred,
4923 MemoryLocationsKind MLK) const = 0;
4924
4925 /// Create an abstract attribute view for the position \p IRP.
4927 Attributor &A);
4928
4929 /// See AbstractState::getAsStr(Attributor).
4930 const std::string getAsStr(Attributor *A) const override {
4932 }
4933
4934 /// See AbstractAttribute::getName()
4935 StringRef getName() const override { return "AAMemoryLocation"; }
4936
4937 /// See AbstractAttribute::getIdAddr()
4938 const char *getIdAddr() const override { return &ID; }
4939
4940 /// This function should return true if the type of the \p AA is
4941 /// AAMemoryLocation
4942 static bool classof(const AbstractAttribute *AA) {
4943 return (AA->getIdAddr() == &ID);
4944 }
4945
4946 /// Unique ID (due to the unique address)
4947 LLVM_ABI static const char ID;
4948};
4949
4950/// An abstract interface for range value analysis.
4952 : public StateWrapper<IntegerRangeState, AbstractAttribute, uint32_t> {
4955 : Base(IRP, IRP.getAssociatedType()->getIntegerBitWidth()) {}
4956
4957 /// See AbstractAttribute::isValidIRPositionForInit
4959 if (!IRP.getAssociatedType()->isIntegerTy())
4960 return false;
4962 }
4963
4964 /// See AbstractAttribute::requiresCallersForArgOrFunction
4965 static bool requiresCallersForArgOrFunction() { return true; }
4966
4967 /// See AbstractAttribute::getState(...).
4968 IntegerRangeState &getState() override { return *this; }
4969 const IntegerRangeState &getState() const override { return *this; }
4970
4971 /// Create an abstract attribute view for the position \p IRP.
4973 Attributor &A);
4974
4975 /// Return an assumed range for the associated value a program point \p CtxI.
4976 /// If \p I is nullptr, simply return an assumed range.
4977 virtual ConstantRange
4979 const Instruction *CtxI = nullptr) const = 0;
4980
4981 /// Return a known range for the associated value at a program point \p CtxI.
4982 /// If \p I is nullptr, simply return a known range.
4983 virtual ConstantRange
4985 const Instruction *CtxI = nullptr) const = 0;
4986
4987 /// Return an assumed constant for the associated value a program point \p
4988 /// CtxI.
4989 std::optional<Constant *>
4990 getAssumedConstant(Attributor &A, const Instruction *CtxI = nullptr) const {
4991 ConstantRange RangeV = getAssumedConstantRange(A, CtxI);
4992 if (auto *C = RangeV.getSingleElement()) {
4995 AA::getWithType(*ConstantInt::get(Ty->getContext(), *C), *Ty));
4996 }
4997 if (RangeV.isEmptySet())
4998 return std::nullopt;
4999 return nullptr;
5000 }
5001
5002 /// See AbstractAttribute::getName()
5003 StringRef getName() const override { return "AAValueConstantRange"; }
5004
5005 /// See AbstractAttribute::getIdAddr()
5006 const char *getIdAddr() const override { return &ID; }
5007
5008 /// This function should return true if the type of the \p AA is
5009 /// AAValueConstantRange
5010 static bool classof(const AbstractAttribute *AA) {
5011 return (AA->getIdAddr() == &ID);
5012 }
5013
5014 /// Unique ID (due to the unique address)
5015 LLVM_ABI static const char ID;
5016};
5017
5018/// A class for a set state.
5019/// The assumed boolean state indicates whether the corresponding set is full
5020/// set or not. If the assumed state is false, this is the worst state. The
5021/// worst state (invalid state) of set of potential values is when the set
5022/// contains every possible value (i.e. we cannot in any way limit the value
5023/// that the target position can take). That never happens naturally, we only
5024/// force it. As for the conditions under which we force it, see
5025/// AAPotentialConstantValues.
5026template <typename MemberTy> struct PotentialValuesState : AbstractState {
5028
5029 PotentialValuesState() : IsValidState(true), UndefIsContained(false) {}
5030
5032 : IsValidState(IsValid), UndefIsContained(false) {}
5033
5034 /// See AbstractState::isValidState(...)
5035 bool isValidState() const override { return IsValidState.isValidState(); }
5036
5037 /// See AbstractState::isAtFixpoint(...)
5038 bool isAtFixpoint() const override { return IsValidState.isAtFixpoint(); }
5039
5040 /// See AbstractState::indicatePessimisticFixpoint(...)
5042 return IsValidState.indicatePessimisticFixpoint();
5043 }
5044
5045 /// See AbstractState::indicateOptimisticFixpoint(...)
5047 return IsValidState.indicateOptimisticFixpoint();
5048 }
5049
5050 /// Return the assumed state
5052 const PotentialValuesState &getAssumed() const { return *this; }
5053
5054 /// Return this set. We should check whether this set is valid or not by
5055 /// isValidState() before calling this function.
5056 const SetTy &getAssumedSet() const {
5057 assert(isValidState() && "This set shoud not be used when it is invalid!");
5058 return Set;
5059 }
5060
5061 /// Returns whether this state contains an undef value or not.
5062 bool undefIsContained() const {
5063 assert(isValidState() && "This flag shoud not be used when it is invalid!");
5064 return UndefIsContained;
5065 }
5066
5068 if (isValidState() != RHS.isValidState())
5069 return false;
5070 if (!isValidState() && !RHS.isValidState())
5071 return true;
5072 if (undefIsContained() != RHS.undefIsContained())
5073 return false;
5074 return Set == RHS.getAssumedSet();
5075 }
5076
5077 /// Maximum number of potential values to be tracked.
5078 /// This is set by -attributor-max-potential-values command line option
5079 static unsigned MaxPotentialValues;
5080
5081 /// Return empty set as the best state of potential values.
5083 return PotentialValuesState(true);
5084 }
5085
5087 return getBestState();
5088 }
5089
5090 /// Return full set as the worst state of potential values.
5092 return PotentialValuesState(false);
5093 }
5094
5095 /// Union assumed set with the passed value.
5096 void unionAssumed(const MemberTy &C) { insert(C); }
5097
5098 /// Union assumed set with assumed set of the passed state \p PVS.
5099 void unionAssumed(const PotentialValuesState &PVS) { unionWith(PVS); }
5100
5101 /// Union assumed set with an undef value.
5102 void unionAssumedWithUndef() { unionWithUndef(); }
5103
5104 /// "Clamp" this state with \p PVS.
5106 IsValidState ^= PVS.IsValidState;
5107 unionAssumed(PVS);
5108 return *this;
5109 }
5110
5112 IsValidState &= PVS.IsValidState;
5113 unionAssumed(PVS);
5114 return *this;
5115 }
5116
5117 bool contains(const MemberTy &V) const {
5118 return !isValidState() ? true : Set.contains(V);
5119 }
5120
5121protected:
5123 assert(isValidState() && "This set shoud not be used when it is invalid!");
5124 return Set;
5125 }
5126
5127private:
5128 /// Check the size of this set, and invalidate when the size is no
5129 /// less than \p MaxPotentialValues threshold.
5130 void checkAndInvalidate() {
5131 if (Set.size() >= MaxPotentialValues)
5133 else
5134 reduceUndefValue();
5135 }
5136
5137 /// If this state contains both undef and not undef, we can reduce
5138 /// undef to the not undef value.
5139 void reduceUndefValue() { UndefIsContained = UndefIsContained & Set.empty(); }
5140
5141 /// Insert an element into this set.
5142 void insert(const MemberTy &C) {
5143 if (!isValidState())
5144 return;
5145 Set.insert(C);
5146 checkAndInvalidate();
5147 }
5148
5149 /// Take union with R.
5150 void unionWith(const PotentialValuesState &R) {
5151 /// If this is a full set, do nothing.
5152 if (!isValidState())
5153 return;
5154 /// If R is full set, change L to a full set.
5155 if (!R.isValidState()) {
5157 return;
5158 }
5159 Set.insert_range(R.Set);
5160 UndefIsContained |= R.undefIsContained();
5161 checkAndInvalidate();
5162 }
5163
5164 /// Take union with an undef value.
5165 void unionWithUndef() {
5166 UndefIsContained = true;
5167 reduceUndefValue();
5168 }
5169
5170 /// Take intersection with R.
5171 void intersectWith(const PotentialValuesState &R) {
5172 /// If R is a full set, do nothing.
5173 if (!R.isValidState())
5174 return;
5175 /// If this is a full set, change this to R.
5176 if (!isValidState()) {
5177 *this = R;
5178 return;
5179 }
5180 SetTy IntersectSet;
5181 for (const MemberTy &C : Set) {
5182 if (R.Set.count(C))
5183 IntersectSet.insert(C);
5184 }
5185 Set = IntersectSet;
5186 UndefIsContained &= R.undefIsContained();
5187 reduceUndefValue();
5188 }
5189
5190 /// A helper state which indicate whether this state is valid or not.
5191 BooleanState IsValidState;
5192
5193 /// Container for potential values
5194 SetTy Set;
5195
5196 /// Flag for undef value
5197 bool UndefIsContained;
5198};
5199
5204
5205 bool operator==(const DenormalState Other) const {
5206 return Mode == Other.Mode && ModeF32 == Other.ModeF32;
5207 }
5208
5209 bool operator!=(const DenormalState Other) const {
5210 return Mode != Other.Mode || ModeF32 != Other.ModeF32;
5211 }
5212
5213 bool isValid() const { return Mode.isValid() && ModeF32.isValid(); }
5214
5218 if (Caller == Callee)
5219 return Caller;
5220 if (Callee == DenormalMode::Dynamic)
5221 return Caller;
5222 if (Caller == DenormalMode::Dynamic)
5223 return Callee;
5224 return DenormalMode::Invalid;
5225 }
5226
5228 return DenormalMode{unionDenormalKind(Callee.Output, Caller.Output),
5229 unionDenormalKind(Callee.Input, Caller.Input)};
5230 }
5231
5233 DenormalState Callee(*this);
5234 Callee.Mode = unionAssumed(Callee.Mode, Caller.Mode);
5235 Callee.ModeF32 = unionAssumed(Callee.ModeF32, Caller.ModeF32);
5236 return Callee;
5237 }
5238 };
5239
5241
5242 /// Explicitly track whether we've hit a fixed point.
5243 bool IsAtFixedpoint = false;
5244
5246
5247 DenormalState getKnown() const { return Known; }
5248
5249 // There's only really known or unknown, there's no speculatively assumable
5250 // state.
5251 DenormalState getAssumed() const { return Known; }
5252
5253 bool isValidState() const override { return Known.isValid(); }
5254
5255 /// Return true if there are no dynamic components to the denormal mode worth
5256 /// specializing.
5257 bool isModeFixed() const {
5258 return Known.Mode.Input != DenormalMode::Dynamic &&
5259 Known.Mode.Output != DenormalMode::Dynamic &&
5260 Known.ModeF32.Input != DenormalMode::Dynamic &&
5261 Known.ModeF32.Output != DenormalMode::Dynamic;
5262 }
5263
5264 bool isAtFixpoint() const override { return IsAtFixedpoint; }
5265
5271
5275
5279
5281 Known = Known.unionWith(Caller.getKnown());
5282 return *this;
5283 }
5284};
5285
5289
5293 const PotentialLLVMValuesState &R);
5294
5295/// An abstract interface for potential values analysis.
5296///
5297/// This AA collects potential values for each IR position.
5298/// An assumed set of potential values is initialized with the empty set (the
5299/// best state) and it will grow monotonically as we find more potential values
5300/// for this position.
5301/// The set might be forced to the worst state, that is, to contain every
5302/// possible value for this position in 2 cases.
5303/// 1. We surpassed the \p MaxPotentialValues threshold. This includes the
5304/// case that this position is affected (e.g. because of an operation) by a
5305/// Value that is in the worst state.
5306/// 2. We tried to initialize on a Value that we cannot handle (e.g. an
5307/// operator we do not currently handle).
5308///
5309/// For non constant integers see AAPotentialValues.
5311 : public StateWrapper<PotentialConstantIntValuesState, AbstractAttribute> {
5314
5315 /// See AbstractAttribute::isValidIRPositionForInit
5317 if (!IRP.getAssociatedType()->isIntegerTy())
5318 return false;
5320 }
5321
5322 /// See AbstractAttribute::requiresCallersForArgOrFunction
5323 static bool requiresCallersForArgOrFunction() { return true; }
5324
5325 /// See AbstractAttribute::getState(...).
5326 PotentialConstantIntValuesState &getState() override { return *this; }
5328 return *this;
5329 }
5330
5331 /// Create an abstract attribute view for the position \p IRP.
5334
5335 /// Return assumed constant for the associated value
5336 std::optional<Constant *>
5337 getAssumedConstant(Attributor &A, const Instruction *CtxI = nullptr) const {
5338 if (!isValidState())
5339 return nullptr;
5340 if (getAssumedSet().size() == 1) {
5343 *ConstantInt::get(Ty->getContext(), *(getAssumedSet().begin())),
5344 *Ty));
5345 }
5346 if (getAssumedSet().size() == 0) {
5347 if (undefIsContained())
5349 return std::nullopt;
5350 }
5351
5352 return nullptr;
5353 }
5354
5355 /// Return the minimum trailing zeros of potential constants
5357 if (!isValidState() || getAssumedSet().empty())
5358 return 0;
5359 unsigned TrailingZeros = getAssumedSet().begin()->getBitWidth() + 1;
5360 for (const APInt &It : getAssumedSet()) {
5361 if (It.countTrailingZeros() < TrailingZeros)
5362 TrailingZeros = It.countTrailingZeros();
5363 }
5364 if (TrailingZeros > getAssumedSet().begin()->getBitWidth())
5365 return 0;
5366 return TrailingZeros;
5367 }
5368 /// See AbstractAttribute::getName()
5369 StringRef getName() const override { return "AAPotentialConstantValues"; }
5370
5371 /// See AbstractAttribute::getIdAddr()
5372 const char *getIdAddr() const override { return &ID; }
5373
5374 /// This function should return true if the type of the \p AA is
5375 /// AAPotentialConstantValues
5376 static bool classof(const AbstractAttribute *AA) {
5377 return (AA->getIdAddr() == &ID);
5378 }
5379
5380 /// Unique ID (due to the unique address)
5381 LLVM_ABI static const char ID;
5382};
5383
5385 : public StateWrapper<PotentialLLVMValuesState, AbstractAttribute> {
5388
5389 /// See AbstractAttribute::requiresCallersForArgOrFunction
5390 static bool requiresCallersForArgOrFunction() { return true; }
5391
5392 /// See AbstractAttribute::getState(...).
5393 PotentialLLVMValuesState &getState() override { return *this; }
5394 const PotentialLLVMValuesState &getState() const override { return *this; }
5395
5396 /// Create an abstract attribute view for the position \p IRP.
5398 Attributor &A);
5399
5400 /// Extract the single value in \p Values if any.
5401 LLVM_ABI static Value *
5403 const IRPosition &IRP,
5405
5406 /// See AbstractAttribute::getName()
5407 StringRef getName() const override { return "AAPotentialValues"; }
5408
5409 /// See AbstractAttribute::getIdAddr()
5410 const char *getIdAddr() const override { return &ID; }
5411
5412 /// This function should return true if the type of the \p AA is
5413 /// AAPotentialValues
5414 static bool classof(const AbstractAttribute *AA) {
5415 return (AA->getIdAddr() == &ID);
5416 }
5417
5418 /// Unique ID (due to the unique address)
5419 LLVM_ABI static const char ID;
5420
5421private:
5422 virtual bool getAssumedSimplifiedValues(
5424 AA::ValueScope, bool RecurseForSelectAndPHI = false) const = 0;
5425
5426 friend struct Attributor;
5427};
5428
5429/// An abstract interface for all noundef attributes.
5431 : public IRAttribute<Attribute::NoUndef,
5432 StateWrapper<BooleanState, AbstractAttribute>,
5433 AANoUndef> {
5435
5436 /// See IRAttribute::isImpliedByUndef
5437 static bool isImpliedByUndef() { return false; }
5438
5439 /// See IRAttribute::isImpliedByPoison
5440 static bool isImpliedByPoison() { return false; }
5441
5442 /// See IRAttribute::isImpliedByIR
5443 LLVM_ABI static bool isImpliedByIR(Attributor &A, const IRPosition &IRP,
5444 Attribute::AttrKind ImpliedAttributeKind,
5445 bool IgnoreSubsumingPositions = false);
5446
5447 /// Return true if we assume that the underlying value is noundef.
5448 bool isAssumedNoUndef() const { return getAssumed(); }
5449
5450 /// Return true if we know that underlying value is noundef.
5451 bool isKnownNoUndef() const { return getKnown(); }
5452
5453 /// Create an abstract attribute view for the position \p IRP.
5455 Attributor &A);
5456
5457 /// See AbstractAttribute::getName()
5458 StringRef getName() const override { return "AANoUndef"; }
5459
5460 /// See AbstractAttribute::getIdAddr()
5461 const char *getIdAddr() const override { return &ID; }
5462
5463 /// This function should return true if the type of the \p AA is AANoUndef
5464 static bool classof(const AbstractAttribute *AA) {
5465 return (AA->getIdAddr() == &ID);
5466 }
5467
5468 /// Unique ID (due to the unique address)
5469 LLVM_ABI static const char ID;
5470};
5471
5473 : public IRAttribute<
5474 Attribute::NoFPClass,
5475 StateWrapper<BitIntegerState<uint32_t, fcAllFlags, fcNone>,
5476 AbstractAttribute>,
5477 AANoFPClass> {
5480
5482
5483 /// See AbstractAttribute::isValidIRPositionForInit
5485 return AttributeFuncs::isNoFPClassCompatibleType(IRP.getAssociatedType());
5486 }
5487
5488 /// Return the underlying assumed nofpclass.
5490 return static_cast<FPClassTest>(getAssumed());
5491 }
5492 /// Return the underlying known nofpclass.
5494 return static_cast<FPClassTest>(getKnown());
5495 }
5496
5497 /// Create an abstract attribute view for the position \p IRP.
5499 Attributor &A);
5500
5501 /// See AbstractAttribute::getName()
5502 StringRef getName() const override { return "AANoFPClass"; }
5503
5504 /// See AbstractAttribute::getIdAddr()
5505 const char *getIdAddr() const override { return &ID; }
5506
5507 /// This function should return true if the type of the \p AA is AANoFPClass
5508 static bool classof(const AbstractAttribute *AA) {
5509 return (AA->getIdAddr() == &ID);
5510 }
5511
5512 /// Unique ID (due to the unique address)
5513 LLVM_ABI static const char ID;
5514};
5515
5516struct AACallGraphNode;
5517struct AACallEdges;
5518
5519/// An Iterator for call edges, creates AACallEdges attributes in a lazy way.
5520/// This iterator becomes invalid if the underlying edge list changes.
5521/// So This shouldn't outlive a iteration of Attributor.
5522class AACallEdgeIterator
5523 : public iterator_adaptor_base<AACallEdgeIterator,
5524 SetVector<Function *>::iterator> {
5525 AACallEdgeIterator(Attributor &A, SetVector<Function *>::iterator Begin)
5526 : iterator_adaptor_base(Begin), A(A) {}
5527
5528public:
5530
5531private:
5532 Attributor &A;
5533 friend AACallEdges;
5534 friend AttributorCallGraph;
5535};
5536
5539 virtual ~AACallGraphNode() = default;
5540
5543
5544 /// Iterator range for exploring the call graph.
5549
5550protected:
5551 /// Reference to Attributor needed for GraphTraits implementation.
5553};
5554
5555/// An abstract state for querying live call edges.
5556/// This interface uses the Attributor's optimistic liveness
5557/// information to compute the edges that are alive.
5558struct AACallEdges : public StateWrapper<BooleanState, AbstractAttribute>,
5561
5563 : Base(IRP), AACallGraphNode(A) {}
5564
5565 /// See AbstractAttribute::requiresNonAsmForCallBase.
5566 static bool requiresNonAsmForCallBase() { return false; }
5567
5568 /// Get the optimistic edges.
5569 virtual const SetVector<Function *> &getOptimisticEdges() const = 0;
5570
5571 /// Is there any call with a unknown callee.
5572 virtual bool hasUnknownCallee() const = 0;
5573
5574 /// Is there any call with a unknown callee, excluding any inline asm.
5575 virtual bool hasNonAsmUnknownCallee() const = 0;
5576
5577 /// Iterator for exploring the call graph.
5581
5582 /// Iterator for exploring the call graph.
5586
5587 /// Create an abstract attribute view for the position \p IRP.
5589 Attributor &A);
5590
5591 /// See AbstractAttribute::getName()
5592 StringRef getName() const override { return "AACallEdges"; }
5593
5594 /// See AbstractAttribute::getIdAddr()
5595 const char *getIdAddr() const override { return &ID; }
5596
5597 /// This function should return true if the type of the \p AA is AACallEdges.
5598 static bool classof(const AbstractAttribute *AA) {
5599 return (AA->getIdAddr() == &ID);
5600 }
5601
5602 /// Unique ID (due to the unique address)
5603 LLVM_ABI static const char ID;
5604};
5605
5606// Synthetic root node for the Attributor's internal call graph.
5609 ~AttributorCallGraph() override = default;
5610
5612 return AACallEdgeIterator(A, A.Functions.begin());
5613 }
5614
5616 return AACallEdgeIterator(A, A.Functions.end());
5617 }
5618
5619 /// Force populate the entire call graph.
5620 void populateAll() const {
5621 for (const AACallGraphNode *AA : optimisticEdgesRange()) {
5622 // Nothing else to do here.
5623 (void)AA;
5624 }
5625 }
5626
5627 LLVM_ABI void print();
5628};
5629
5630template <> struct GraphTraits<AACallGraphNode *> {
5633
5635 return Node->optimisticEdgesBegin();
5636 }
5637
5639 return Node->optimisticEdgesEnd();
5640 }
5641};
5642
5643template <>
5647
5649 return static_cast<AACallGraphNode *>(G);
5650 }
5651
5653 return G->optimisticEdgesBegin();
5654 }
5655
5657 return G->optimisticEdgesEnd();
5658 }
5659};
5660
5661template <>
5664
5666 const AttributorCallGraph *Graph) {
5667 const AACallEdges *AACE = static_cast<const AACallEdges *>(Node);
5668 return AACE->getAssociatedFunction()->getName().str();
5669 }
5670
5672 const AttributorCallGraph *Graph) {
5673 // Hide the synth root.
5674 return static_cast<const AACallGraphNode *>(Graph) == Node;
5675 }
5676};
5677
5679 : public StateWrapper<BooleanState, AbstractAttribute> {
5682
5683 /// Summary about the execution domain of a block or instruction.
5708
5709 /// Create an abstract attribute view for the position \p IRP.
5711 Attributor &A);
5712
5713 /// See AbstractAttribute::getName().
5714 StringRef getName() const override { return "AAExecutionDomain"; }
5715
5716 /// See AbstractAttribute::getIdAddr().
5717 const char *getIdAddr() const override { return &ID; }
5718
5719 /// Check if an instruction is executed only by the initial thread.
5721 return isExecutedByInitialThreadOnly(*I.getParent());
5722 }
5723
5724 /// Check if a basic block is executed only by the initial thread.
5725 virtual bool isExecutedByInitialThreadOnly(const BasicBlock &) const = 0;
5726
5727 /// Check if the instruction \p I is executed in an aligned region, that is,
5728 /// the synchronizing effects before and after \p I are both aligned barriers.
5729 /// This effectively means all threads execute \p I together.
5731 const Instruction &I) const = 0;
5732
5734 /// Return the execution domain with which the call \p CB is entered and the
5735 /// one with which it is left.
5736 virtual std::pair<ExecutionDomainTy, ExecutionDomainTy>
5737 getExecutionDomain(const CallBase &CB) const = 0;
5739
5740 /// Helper function to determine if \p FI is a no-op given the information
5741 /// about its execution from \p ExecDomainAA.
5742 virtual bool isNoOpFence(const FenceInst &FI) const = 0;
5743
5744 /// This function should return true if the type of the \p AA is
5745 /// AAExecutionDomain.
5746 static bool classof(const AbstractAttribute *AA) {
5747 return (AA->getIdAddr() == &ID);
5748 }
5749
5750 /// Unique ID (due to the unique address)
5751 LLVM_ABI static const char ID;
5752};
5753
5754/// An abstract Attribute for computing reachability between functions.
5756 : public StateWrapper<BooleanState, AbstractAttribute> {
5758
5760
5761 /// If the function represented by this possition can reach \p Fn.
5762 bool canReach(Attributor &A, const Function &Fn) const {
5763 Function *Scope = getAnchorScope();
5764 if (!Scope || Scope->isDeclaration())
5765 return true;
5766 return instructionCanReach(A, Scope->getEntryBlock().front(), Fn);
5767 }
5768
5769 /// Can \p Inst reach \p Fn.
5770 /// See also AA::isPotentiallyReachable.
5772 Attributor &A, const Instruction &Inst, const Function &Fn,
5773 const AA::InstExclusionSetTy *ExclusionSet = nullptr) const = 0;
5774
5775 /// Create an abstract attribute view for the position \p IRP.
5778
5779 /// See AbstractAttribute::getName()
5780 StringRef getName() const override { return "AAInterFnReachability"; }
5781
5782 /// See AbstractAttribute::getIdAddr()
5783 const char *getIdAddr() const override { return &ID; }
5784
5785 /// This function should return true if the type of the \p AA is AACallEdges.
5786 static bool classof(const AbstractAttribute *AA) {
5787 return (AA->getIdAddr() == &ID);
5788 }
5789
5790 /// Unique ID (due to the unique address)
5791 LLVM_ABI static const char ID;
5792};
5793
5794/// An abstract Attribute for determining the necessity of the convergent
5795/// attribute.
5796struct AANonConvergent : public StateWrapper<BooleanState, AbstractAttribute> {
5798
5800
5801 /// Create an abstract attribute view for the position \p IRP.
5803 Attributor &A);
5804
5805 /// Return true if "non-convergent" is assumed.
5806 bool isAssumedNotConvergent() const { return getAssumed(); }
5807
5808 /// Return true if "non-convergent" is known.
5809 bool isKnownNotConvergent() const { return getKnown(); }
5810
5811 /// See AbstractAttribute::getName()
5812 StringRef getName() const override { return "AANonConvergent"; }
5813
5814 /// See AbstractAttribute::getIdAddr()
5815 const char *getIdAddr() const override { return &ID; }
5816
5817 /// This function should return true if the type of the \p AA is
5818 /// AANonConvergent.
5819 static bool classof(const AbstractAttribute *AA) {
5820 return (AA->getIdAddr() == &ID);
5821 }
5822
5823 /// Unique ID (due to the unique address)
5824 LLVM_ABI static const char ID;
5825};
5826
5827/// An abstract interface for struct information.
5830
5831 /// See AbstractAttribute::isValidIRPositionForInit
5834 return false;
5836 }
5837
5839 // First two bits to distinguish may and must accesses.
5840 AK_MUST = 1 << 0,
5841 AK_MAY = 1 << 1,
5842
5843 // Then two bits for read and write. These are not exclusive.
5844 AK_R = 1 << 2,
5845 AK_W = 1 << 3,
5847
5848 // One special case for assumptions about memory content. These
5849 // are neither reads nor writes. They are however always modeled
5850 // as read to avoid using them for write removal.
5852
5853 // Helper for easy access.
5860 };
5861
5862 /// A helper containing a list of offsets computed for a Use. Ideally this
5863 /// list should be strictly ascending, but we ensure that only when we
5864 /// actually translate the list of offsets to a RangeList.
5865 struct OffsetInfo {
5869
5870 const_iterator begin() const { return Offsets.begin(); }
5871 const_iterator end() const { return Offsets.end(); }
5872
5873 bool operator==(const OffsetInfo &RHS) const {
5874 return Offsets == RHS.Offsets;
5875 }
5876
5877 bool operator!=(const OffsetInfo &RHS) const { return !(*this == RHS); }
5878
5879 bool insert(int64_t Offset) { return Offsets.insert(Offset).second; }
5880 bool isUnassigned() const { return Offsets.size() == 0; }
5881
5882 bool isUnknown() const {
5883 if (isUnassigned())
5884 return false;
5885 if (Offsets.size() == 1)
5886 return *Offsets.begin() == AA::RangeTy::Unknown;
5887 return false;
5888 }
5889
5890 void setUnknown() {
5891 Offsets.clear();
5893 }
5894
5895 void addToAll(int64_t Inc) {
5896 VecTy NewOffsets;
5897 for (auto &Offset : Offsets)
5898 NewOffsets.insert(Offset + Inc);
5899 Offsets = std::move(NewOffsets);
5900 }
5901
5902 /// Copy offsets from \p R into the current list.
5903 ///
5904 /// Ideally all lists should be strictly ascending, but we defer that to the
5905 /// actual use of the list. So we just blindly append here.
5906 bool merge(const OffsetInfo &R) { return set_union(Offsets, R.Offsets); }
5907 };
5908
5909 /// A container for a list of ranges.
5910 struct RangeList {
5911 // The set of ranges rarely contains more than one element, and is unlikely
5912 // to contain more than say four elements. So we find the middle-ground with
5913 // a sorted vector. This avoids hard-coding a rarely used number like "four"
5914 // into every instance of a SmallSet.
5920
5921 RangeList(const RangeTy &R) { Ranges.push_back(R); }
5923 Ranges.reserve(Offsets.size());
5924 for (unsigned i = 0, e = Offsets.size(); i != e; ++i) {
5925 assert(((i + 1 == e) || Offsets[i] < Offsets[i + 1]) &&
5926 "Expected strictly ascending offsets.");
5927 Ranges.emplace_back(Offsets[i], Size);
5928 }
5929 }
5930 RangeList() = default;
5931
5932 iterator begin() { return Ranges.begin(); }
5933 iterator end() { return Ranges.end(); }
5934 const_iterator begin() const { return Ranges.begin(); }
5935 const_iterator end() const { return Ranges.end(); }
5936
5937 // Helpers required for std::set_difference
5939 void push_back(const RangeTy &R) {
5940 assert((Ranges.empty() || RangeTy::LessThan(Ranges.back(), R)) &&
5941 "Ensure the last element is the greatest.");
5942 Ranges.push_back(R);
5943 }
5944
5945 /// Copy ranges from \p L that are not in \p R, into \p D.
5946 static void set_difference(const RangeList &L, const RangeList &R,
5947 RangeList &D) {
5948 std::set_difference(L.begin(), L.end(), R.begin(), R.end(),
5949 std::back_inserter(D), RangeTy::LessThan);
5950 }
5951
5952 unsigned size() const { return Ranges.size(); }
5953
5954 bool operator==(const RangeList &OI) const { return Ranges == OI.Ranges; }
5955
5956 /// Merge the ranges in \p RHS into the current ranges.
5957 /// - Merging a list of unknown ranges makes the current list unknown.
5958 /// - Ranges with the same offset are merged according to RangeTy::operator&
5959 /// \return true if the current RangeList changed.
5960 bool merge(const RangeList &RHS) {
5961 if (isUnknown())
5962 return false;
5963 if (RHS.isUnknown()) {
5964 setUnknown();
5965 return true;
5966 }
5967
5968 if (Ranges.empty()) {
5969 Ranges = RHS.Ranges;
5970 return true;
5971 }
5972
5973 bool Changed = false;
5974 auto LPos = Ranges.begin();
5975 for (auto &R : RHS.Ranges) {
5976 auto Result = insert(LPos, R);
5977 if (isUnknown())
5978 return true;
5979 LPos = Result.first;
5980 Changed |= Result.second;
5981 }
5982 return Changed;
5983 }
5984
5985 /// Insert \p R at the given iterator \p Pos, and merge if necessary.
5986 ///
5987 /// This assumes that all ranges before \p Pos are LessThan \p R, and
5988 /// then maintains the sorted order for the suffix list.
5989 ///
5990 /// \return The place of insertion and true iff anything changed.
5991 std::pair<iterator, bool> insert(iterator Pos, const RangeTy &R) {
5992 if (isUnknown())
5993 return std::make_pair(Ranges.begin(), false);
5994 if (R.offsetOrSizeAreUnknown()) {
5995 return std::make_pair(setUnknown(), true);
5996 }
5997
5998 // Maintain this as a sorted vector of unique entries.
5999 auto LB = std::lower_bound(Pos, Ranges.end(), R, RangeTy::LessThan);
6000 if (LB == Ranges.end() || LB->Offset != R.Offset)
6001 return std::make_pair(Ranges.insert(LB, R), true);
6002 bool Changed = *LB != R;
6003 *LB &= R;
6004 if (LB->offsetOrSizeAreUnknown())
6005 return std::make_pair(setUnknown(), true);
6006 return std::make_pair(LB, Changed);
6007 }
6008
6009 /// Insert the given range \p R, maintaining sorted order.
6010 ///
6011 /// \return The place of insertion and true iff anything changed.
6012 std::pair<iterator, bool> insert(const RangeTy &R) {
6013 return insert(Ranges.begin(), R);
6014 }
6015
6016 /// Add the increment \p Inc to the offset of every range.
6017 void addToAllOffsets(int64_t Inc) {
6018 assert(!isUnassigned() &&
6019 "Cannot increment if the offset is not yet computed!");
6020 if (isUnknown())
6021 return;
6022 for (auto &R : Ranges) {
6023 R.Offset += Inc;
6024 }
6025 }
6026
6027 /// Return true iff there is exactly one range and it is known.
6028 bool isUnique() const {
6029 return Ranges.size() == 1 && !Ranges.front().offsetOrSizeAreUnknown();
6030 }
6031
6032 /// Return the unique range, assuming it exists.
6033 const RangeTy &getUnique() const {
6034 assert(isUnique() && "No unique range to return!");
6035 return Ranges.front();
6036 }
6037
6038 /// Return true iff the list contains an unknown range.
6039 bool isUnknown() const {
6040 if (isUnassigned())
6041 return false;
6042 if (Ranges.front().offsetOrSizeAreUnknown()) {
6043 assert(Ranges.size() == 1 && "Unknown is a singleton range.");
6044 return true;
6045 }
6046 return false;
6047 }
6048
6049 /// Discard all ranges and insert a single unknown range.
6051 Ranges.clear();
6052 Ranges.push_back(RangeTy::getUnknown());
6053 return Ranges.begin();
6054 }
6055
6056 /// Return true if no ranges have been inserted.
6057 bool isUnassigned() const { return Ranges.size() == 0; }
6058 };
6059
6060 /// An access description.
6061 struct Access {
6062 Access(Instruction *I, int64_t Offset, int64_t Size,
6063 std::optional<Value *> Content, AccessKind Kind, Type *Ty)
6064 : LocalI(I), RemoteI(I), Content(Content), Ranges(Offset, Size),
6065 Kind(Kind), Ty(Ty) {
6066 verify();
6067 }
6068 Access(Instruction *LocalI, Instruction *RemoteI, const RangeList &Ranges,
6069 std::optional<Value *> Content, AccessKind K, Type *Ty)
6070 : LocalI(LocalI), RemoteI(RemoteI), Content(Content), Ranges(Ranges),
6071 Kind(K), Ty(Ty) {
6072 if (Ranges.size() > 1) {
6073 Kind = AccessKind(Kind | AK_MAY);
6074 Kind = AccessKind(Kind & ~AK_MUST);
6075 }
6076 verify();
6077 }
6078 Access(Instruction *LocalI, Instruction *RemoteI, int64_t Offset,
6079 int64_t Size, std::optional<Value *> Content, AccessKind Kind,
6080 Type *Ty)
6081 : LocalI(LocalI), RemoteI(RemoteI), Content(Content),
6082 Ranges(Offset, Size), Kind(Kind), Ty(Ty) {
6083 verify();
6084 }
6085 Access(const Access &Other) = default;
6086
6087 Access &operator=(const Access &Other) = default;
6088 bool operator==(const Access &R) const {
6089 return LocalI == R.LocalI && RemoteI == R.RemoteI && Ranges == R.Ranges &&
6090 Content == R.Content && Kind == R.Kind;
6091 }
6092 bool operator!=(const Access &R) const { return !(*this == R); }
6093
6095 assert(RemoteI == R.RemoteI && "Expected same instruction!");
6096 assert(LocalI == R.LocalI && "Expected same instruction!");
6097
6098 // Note that every Access object corresponds to a unique Value, and only
6099 // accesses to the same Value are merged. Hence we assume that all ranges
6100 // are the same size. If ranges can be different size, then the contents
6101 // must be dropped.
6102 Ranges.merge(R.Ranges);
6103 Content =
6104 AA::combineOptionalValuesInAAValueLatice(Content, R.Content, Ty);
6105
6106 // Combine the access kind, which results in a bitwise union.
6107 // If there is more than one range, then this must be a MAY.
6108 // If we combine a may and a must access we clear the must bit.
6109 Kind = AccessKind(Kind | R.Kind);
6110 if ((Kind & AK_MAY) || Ranges.size() > 1) {
6111 Kind = AccessKind(Kind | AK_MAY);
6112 Kind = AccessKind(Kind & ~AK_MUST);
6113 }
6114 verify();
6115 return *this;
6116 }
6117
6118 void verify() {
6119 assert(isMustAccess() + isMayAccess() == 1 &&
6120 "Expect must or may access, not both.");
6121 assert(isAssumption() + isWrite() <= 1 &&
6122 "Expect assumption access or write access, never both.");
6123 assert((isMayAccess() || Ranges.size() == 1) &&
6124 "Cannot be a must access if there are multiple ranges.");
6125 }
6126
6127 /// Return the access kind.
6128 AccessKind getKind() const { return Kind; }
6129
6130 /// Return true if this is a read access.
6131 bool isRead() const { return Kind & AK_R; }
6132
6133 /// Return true if this is a write access.
6134 bool isWrite() const { return Kind & AK_W; }
6135
6136 /// Return true if this is a write access.
6137 bool isWriteOrAssumption() const { return isWrite() || isAssumption(); }
6138
6139 /// Return true if this is an assumption access.
6140 bool isAssumption() const { return Kind == AK_ASSUMPTION; }
6141
6142 bool isMustAccess() const {
6143 bool MustAccess = Kind & AK_MUST;
6144 assert((!MustAccess || Ranges.size() < 2) &&
6145 "Cannot be a must access if there are multiple ranges.");
6146 return MustAccess;
6147 }
6148
6149 bool isMayAccess() const {
6150 bool MayAccess = Kind & AK_MAY;
6151 assert((MayAccess || Ranges.size() < 2) &&
6152 "Cannot be a must access if there are multiple ranges.");
6153 return MayAccess;
6154 }
6155
6156 /// Return the instruction that causes the access with respect to the local
6157 /// scope of the associated attribute.
6158 Instruction *getLocalInst() const { return LocalI; }
6159
6160 /// Return the actual instruction that causes the access.
6161 Instruction *getRemoteInst() const { return RemoteI; }
6162
6163 /// Return true if the value written is not known yet.
6164 bool isWrittenValueYetUndetermined() const { return !Content; }
6165
6166 /// Return true if the value written cannot be determined at all.
6168 return Content.has_value() && !*Content;
6169 }
6170
6171 /// Set the value written to nullptr, i.e., unknown.
6172 void setWrittenValueUnknown() { Content = nullptr; }
6173
6174 /// Return the type associated with the access, if known.
6175 Type *getType() const { return Ty; }
6176
6177 /// Return the value writen, if any.
6180 "Value needs to be determined before accessing it.");
6181 return *Content;
6182 }
6183
6184 /// Return the written value which can be `llvm::null` if it is not yet
6185 /// determined.
6186 std::optional<Value *> getContent() const { return Content; }
6187
6188 bool hasUniqueRange() const { return Ranges.isUnique(); }
6189 const AA::RangeTy &getUniqueRange() const { return Ranges.getUnique(); }
6190
6191 /// Add a range accessed by this Access.
6192 ///
6193 /// If there are multiple ranges, then this is a "may access".
6194 void addRange(int64_t Offset, int64_t Size) {
6195 Ranges.insert({Offset, Size});
6196 if (!hasUniqueRange()) {
6197 Kind = AccessKind(Kind | AK_MAY);
6198 Kind = AccessKind(Kind & ~AK_MUST);
6199 }
6200 }
6201
6202 const RangeList &getRanges() const { return Ranges; }
6203
6205 const_iterator begin() const { return Ranges.begin(); }
6206 const_iterator end() const { return Ranges.end(); }
6207
6208 private:
6209 /// The instruction responsible for the access with respect to the local
6210 /// scope of the associated attribute.
6211 Instruction *LocalI;
6212
6213 /// The instruction responsible for the access.
6214 Instruction *RemoteI;
6215
6216 /// The value written, if any. `std::nullopt` means "not known yet",
6217 /// `nullptr` cannot be determined.
6218 std::optional<Value *> Content;
6219
6220 /// Set of potential ranges accessed from the base pointer.
6221 RangeList Ranges;
6222
6223 /// The access kind, e.g., READ, as bitset (could be more than one).
6225
6226 /// The type of the content, thus the type read/written, can be null if not
6227 /// available.
6228 Type *Ty;
6229 };
6230
6231 /// Create an abstract attribute view for the position \p IRP.
6233 Attributor &A);
6234
6235 /// See AbstractAttribute::getName()
6236 StringRef getName() const override { return "AAPointerInfo"; }
6237
6238 /// See AbstractAttribute::getIdAddr()
6239 const char *getIdAddr() const override { return &ID; }
6240
6242 using const_bin_iterator = OffsetBinsTy::const_iterator;
6243 virtual const_bin_iterator begin() const = 0;
6244 virtual const_bin_iterator end() const = 0;
6245 virtual int64_t numOffsetBins() const = 0;
6246 virtual bool reachesReturn() const = 0;
6247 virtual void addReturnedOffsetsTo(OffsetInfo &) const = 0;
6248
6249 /// Call \p CB on all accesses that might interfere with \p Range and return
6250 /// true if all such accesses were known and the callback returned true for
6251 /// all of them, false otherwise. An access interferes with an offset-size
6252 /// pair if it might read or write that memory region.
6254 AA::RangeTy Range, function_ref<bool(const Access &, bool)> CB) const = 0;
6255
6256 /// Call \p CB on all accesses that might interfere with \p I and
6257 /// return true if all such accesses were known and the callback returned true
6258 /// for all of them, false otherwise. In contrast to forallInterferingAccesses
6259 /// this function will perform reasoning to exclude write accesses that cannot
6260 /// affect the load even if they on the surface look as if they would. The
6261 /// flag \p HasBeenWrittenTo will be set to true if we know that \p I does not
6262 /// read the initial value of the underlying memory. If \p SkipCB is given and
6263 /// returns false for a potentially interfering access, that access is not
6264 /// checked for actual interference.
6266 Attributor &A, const AbstractAttribute &QueryingAA, Instruction &I,
6267 bool FindInterferingWrites, bool FindInterferingReads,
6268 function_ref<bool(const Access &, bool)> CB, bool &HasBeenWrittenTo,
6270 function_ref<bool(const Access &)> SkipCB = nullptr) const = 0;
6271
6272 /// This function should return true if the type of the \p AA is AAPointerInfo
6273 static bool classof(const AbstractAttribute *AA) {
6274 return (AA->getIdAddr() == &ID);
6275 }
6276
6277 /// Unique ID (due to the unique address)
6278 LLVM_ABI static const char ID;
6279};
6280
6282
6283/// An abstract attribute for getting assumption information.
6285 : public StateWrapper<SetState<StringRef>, AbstractAttribute,
6286 DenseSet<StringRef>> {
6287 using Base =
6289
6291 const DenseSet<StringRef> &Known)
6292 : Base(IRP, Known) {}
6293
6294 /// Returns true if the assumption set contains the assumption \p Assumption.
6295 virtual bool hasAssumption(const StringRef Assumption) const = 0;
6296
6297 /// Create an abstract attribute view for the position \p IRP.
6299 Attributor &A);
6300
6301 /// See AbstractAttribute::getName()
6302 StringRef getName() const override { return "AAAssumptionInfo"; }
6303
6304 /// See AbstractAttribute::getIdAddr()
6305 const char *getIdAddr() const override { return &ID; }
6306
6307 /// This function should return true if the type of the \p AA is
6308 /// AAAssumptionInfo
6309 static bool classof(const AbstractAttribute *AA) {
6310 return (AA->getIdAddr() == &ID);
6311 }
6312
6313 /// Unique ID (due to the unique address)
6314 LLVM_ABI static const char ID;
6315};
6316
6317/// An abstract attribute for getting all assumption underlying objects.
6320
6321 /// See AbstractAttribute::isValidIRPositionForInit
6324 return false;
6326 }
6327
6328 /// See AbstractAttribute::requiresCallersForArgOrFunction
6329 static bool requiresCallersForArgOrFunction() { return true; }
6330
6331 /// Create an abstract attribute biew for the position \p IRP.
6333 Attributor &A);
6334
6335 /// See AbstractAttribute::getName()
6336 StringRef getName() const override { return "AAUnderlyingObjects"; }
6337
6338 /// See AbstractAttribute::getIdAddr()
6339 const char *getIdAddr() const override { return &ID; }
6340
6341 /// This function should return true if the type of the \p AA is
6342 /// AAUnderlyingObjects.
6343 static bool classof(const AbstractAttribute *AA) {
6344 return (AA->getIdAddr() == &ID);
6345 }
6346
6347 /// Unique ID (due to the unique address)
6348 LLVM_ABI static const char ID;
6349
6350 /// Check \p Pred on all underlying objects in \p Scope collected so far.
6351 ///
6352 /// This method will evaluate \p Pred on all underlying objects in \p Scope
6353 /// collected so far and return true if \p Pred holds on all of them.
6354 virtual bool
6356 AA::ValueScope Scope = AA::Interprocedural) const = 0;
6357};
6358
6359/// An abstract interface for identifying pointers from which loads can be
6360/// marked invariant.
6363
6364 /// See AbstractAttribute::isValidIRPositionForInit
6366 if (!IRP.getAssociatedType()->isPointerTy())
6367 return false;
6368
6370 }
6371
6372 /// Create an abstract attribute view for the position \p IRP.
6375
6376 /// Return true if the pointer's contents are known to remain invariant.
6377 virtual bool isKnownInvariant() const = 0;
6378 virtual bool isKnownLocallyInvariant() const = 0;
6379
6380 /// Return true if the pointer's contents are assumed to remain invariant.
6381 virtual bool isAssumedInvariant() const = 0;
6382 virtual bool isAssumedLocallyInvariant() const = 0;
6383
6384 /// See AbstractAttribute::getName().
6385 StringRef getName() const override { return "AAInvariantLoadPointer"; }
6386
6387 /// See AbstractAttribute::getIdAddr().
6388 const char *getIdAddr() const override { return &ID; }
6389
6390 /// This function should return true if the type of the \p AA is
6391 /// AAInvariantLoadPointer
6392 static bool classof(const AbstractAttribute *AA) {
6393 return (AA->getIdAddr() == &ID);
6394 }
6395
6396 /// Unique ID (due to the unique address).
6397 LLVM_ABI static const char ID;
6398};
6399
6400/// An abstract interface for address space information.
6401struct AAAddressSpace : public StateWrapper<BooleanState, AbstractAttribute> {
6404
6405 /// See AbstractAttribute::isValidIRPositionForInit
6408 return false;
6410 }
6411
6412 /// See AbstractAttribute::requiresCallersForArgOrFunction
6413 static bool requiresCallersForArgOrFunction() { return true; }
6414
6415 /// Return the address space of the associated value. \p NoAddressSpace is
6416 /// returned if the associated value is dead. This functions is not supposed
6417 /// to be called if the AA is invalid.
6418 virtual uint32_t getAddressSpace() const = 0;
6419
6420 /// Create an abstract attribute view for the position \p IRP.
6422 Attributor &A);
6423
6424 /// See AbstractAttribute::getName()
6425 StringRef getName() const override { return "AAAddressSpace"; }
6426
6427 /// See AbstractAttribute::getIdAddr()
6428 const char *getIdAddr() const override { return &ID; }
6429
6430 /// This function should return true if the type of the \p AA is
6431 /// AAAssumptionInfo
6432 static bool classof(const AbstractAttribute *AA) {
6433 return (AA->getIdAddr() == &ID);
6434 }
6435
6436 /// Unique ID (due to the unique address)
6437 LLVM_ABI static const char ID;
6438
6439protected:
6440 // Invalid address space which indicates the associated value is dead.
6441 static const uint32_t InvalidAddressSpace = ~0U;
6442};
6443
6444/// An abstract interface for potential address space information.
6446 : public StateWrapper<BooleanState, AbstractAttribute> {
6451
6452 /// See AbstractAttribute::isValidIRPositionForInit
6455 return false;
6457 }
6458
6459 /// See AbstractAttribute::requiresCallersForArgOrFunction
6460 static bool requiresCallersForArgOrFunction() { return true; }
6461
6462 /// Create an abstract attribute view for the position \p IRP.
6464 Attributor &A);
6465 /// See AbstractAttribute::getName()
6466 StringRef getName() const override { return "AANoAliasAddrSpace"; }
6467
6468 /// See AbstractAttribute::getIdAddr()
6469 const char *getIdAddr() const override { return &ID; }
6470
6471 /// This function should return true if the type of the \p AA is
6472 /// AAAssumptionInfo
6473 static bool classof(const AbstractAttribute *AA) {
6474 return (AA->getIdAddr() == &ID);
6475 }
6476
6477 /// Unique ID (due to the unique address)
6478 LLVM_ABI static const char ID;
6479
6480protected:
6483};
6484
6485struct AAAllocationInfo : public StateWrapper<BooleanState, AbstractAttribute> {
6488
6489 /// See AbstractAttribute::isValidIRPositionForInit
6492 return false;
6494 }
6495
6496 /// Create an abstract attribute view for the position \p IRP.
6498 Attributor &A);
6499
6500 virtual std::optional<TypeSize> getAllocatedSize() const = 0;
6501
6502 /// See AbstractAttribute::getName()
6503 StringRef getName() const override { return "AAAllocationInfo"; }
6504
6505 /// See AbstractAttribute::getIdAddr()
6506 const char *getIdAddr() const override { return &ID; }
6507
6508 /// This function should return true if the type of the \p AA is
6509 /// AAAllocationInfo
6510 static bool classof(const AbstractAttribute *AA) {
6511 return (AA->getIdAddr() == &ID);
6512 }
6513
6514 constexpr static const std::optional<TypeSize> HasNoAllocationSize =
6515 std::make_optional<TypeSize>(-1, true);
6516
6517 LLVM_ABI static const char ID;
6518};
6519
6520/// An abstract interface for llvm::GlobalValue information interference.
6522 : public StateWrapper<BooleanState, AbstractAttribute> {
6525
6526 /// See AbstractAttribute::isValidIRPositionForInit
6529 return false;
6530 auto *GV = dyn_cast<GlobalValue>(&IRP.getAnchorValue());
6531 if (!GV)
6532 return false;
6533 return GV->hasLocalLinkage();
6534 }
6535
6536 /// Create an abstract attribute view for the position \p IRP.
6538 Attributor &A);
6539
6540 /// Return true iff \p U is a potential use of the associated global value.
6541 virtual bool isPotentialUse(const Use &U) const = 0;
6542
6543 /// See AbstractAttribute::getName()
6544 StringRef getName() const override { return "AAGlobalValueInfo"; }
6545
6546 /// See AbstractAttribute::getIdAddr()
6547 const char *getIdAddr() const override { return &ID; }
6548
6549 /// This function should return true if the type of the \p AA is
6550 /// AAGlobalValueInfo
6551 static bool classof(const AbstractAttribute *AA) {
6552 return (AA->getIdAddr() == &ID);
6553 }
6554
6555 /// Unique ID (due to the unique address)
6556 LLVM_ABI static const char ID;
6557};
6558
6559/// An abstract interface for indirect call information interference.
6561 : public StateWrapper<BooleanState, AbstractAttribute> {
6564
6565 /// See AbstractAttribute::isValidIRPositionForInit
6568 return false;
6569 auto *CB = cast<CallBase>(IRP.getCtxI());
6570 return CB->getOpcode() == Instruction::Call && CB->isIndirectCall() &&
6571 !CB->isMustTailCall();
6572 }
6573
6574 /// Create an abstract attribute view for the position \p IRP.
6576 Attributor &A);
6577
6578 /// Call \CB on each potential callee value and return true if all were known
6579 /// and \p CB returned true on all of them. Otherwise, return false.
6580 virtual bool foreachCallee(function_ref<bool(Function *)> CB) const = 0;
6581
6582 /// See AbstractAttribute::getName()
6583 StringRef getName() const override { return "AAIndirectCallInfo"; }
6584
6585 /// See AbstractAttribute::getIdAddr()
6586 const char *getIdAddr() const override { return &ID; }
6587
6588 /// This function should return true if the type of the \p AA is
6589 /// AAIndirectCallInfo
6590 /// This function should return true if the type of the \p AA is
6591 /// AADenormalFPMath.
6592 static bool classof(const AbstractAttribute *AA) {
6593 return (AA->getIdAddr() == &ID);
6594 }
6595
6596 /// Unique ID (due to the unique address)
6597 LLVM_ABI static const char ID;
6598};
6599
6600/// An abstract Attribute for specializing "dynamic" components of
6601/// denormal_fpenv to a known denormal mode.
6603 : public StateWrapper<DenormalFPMathState, AbstractAttribute> {
6605
6607
6608 /// Create an abstract attribute view for the position \p IRP.
6610 Attributor &A);
6611
6612 /// See AbstractAttribute::getName()
6613 StringRef getName() const override { return "AADenormalFPMath"; }
6614
6615 /// See AbstractAttribute::getIdAddr()
6616 const char *getIdAddr() const override { return &ID; }
6617
6618 /// This function should return true if the type of the \p AA is
6619 /// AADenormalFPMath.
6620 static bool classof(const AbstractAttribute *AA) {
6621 return (AA->getIdAddr() == &ID);
6622 }
6623
6624 /// Unique ID (due to the unique address)
6625 LLVM_ABI static const char ID;
6626};
6627
6628/// Run options, used by the pass manager.
6639
6640namespace AA {
6641/// Helper to avoid creating an AA for IR Attributes that might already be set.
6642template <Attribute::AttrKind AK, typename AAType = AbstractAttribute>
6644 const IRPosition &IRP, DepClassTy DepClass, bool &IsKnown,
6645 bool IgnoreSubsumingPositions = false,
6646 const AAType **AAPtr = nullptr) {
6647 IsKnown = false;
6648 switch (AK) {
6649#define CASE(ATTRNAME, AANAME, ...) \
6650 case Attribute::ATTRNAME: { \
6651 if (AANAME::isImpliedByIR(A, IRP, AK, IgnoreSubsumingPositions)) \
6652 return IsKnown = true; \
6653 if (!QueryingAA) \
6654 return false; \
6655 const auto *AA = A.getAAFor<AANAME>(*QueryingAA, IRP, DepClass); \
6656 if (AAPtr) \
6657 *AAPtr = reinterpret_cast<const AAType *>(AA); \
6658 if (!AA || !AA->isAssumed(__VA_ARGS__)) \
6659 return false; \
6660 IsKnown = AA->isKnown(__VA_ARGS__); \
6661 return true; \
6662 }
6663 CASE(NoUnwind, AANoUnwind, );
6664 CASE(WillReturn, AAWillReturn, );
6665 CASE(NoFree, AANoFree, );
6666 CASE(Captures, AANoCapture, );
6667 CASE(NoRecurse, AANoRecurse, );
6668 CASE(NoReturn, AANoReturn, );
6669 CASE(NoSync, AANoSync, );
6670 CASE(NoAlias, AANoAlias, );
6671 CASE(NonNull, AANonNull, );
6672 CASE(MustProgress, AAMustProgress, );
6673 CASE(NoUndef, AANoUndef, );
6677#undef CASE
6678 default:
6679 llvm_unreachable("hasAssumedIRAttr not available for this attribute kind");
6680 };
6681}
6682} // namespace AA
6683
6684} // end namespace llvm
6685
6686#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
ArrayRef - 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:279
Analysis pass which computes a DominatorTree.
Definition Dominators.h:278
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:589
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.
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
std::string str() const
str - 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:284
bool isPtrOrPtrVectorTy() const
Return true if this is a pointer type or a vector of pointer types.
Definition Type.h:287
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:709
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:557
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:207
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:508
bool operator|=(SparseBitVector< ElementSize > &LHS, const SparseBitVector< ElementSize > *RHS)
@ OPTIONAL
The target may be valid if the source is not.
Definition Attributor.h:520
@ NONE
Do not track a dependence between source and target.
Definition Attributor.h:521
@ REQUIRED
The target cannot be valid if the source is not.
Definition Attributor.h:519
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:870
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:538
friend struct Attributor
Definition Attributor.h:560
mapped_iterator< DepSetTy::iterator, decltype(&DepGetVal)> iterator
Definition Attributor.h:545
mapped_iterator< DepSetTy::iterator, decltype(&DepGetValAA)> aaiterator
Definition Attributor.h:546
virtual ~AADepGraphNode()=default
SmallSetVector< DepTy, 2 > DepSetTy
Definition Attributor.h:530
static AADepGraphNode * DepGetVal(const DepTy &DT)
Definition Attributor.h:537
DepSetTy & getDeps()
Definition Attributor.h:558
iterator child_begin()
Definition Attributor.h:551
DepSetTy Deps
Set of dependency graph nodes which should be updated if this one is updated.
Definition Attributor.h:535
friend struct AADepGraph
Definition Attributor.h:561
virtual void print(Attributor *, raw_ostream &OS) const
Definition Attributor.h:555
aaiterator begin()
Definition Attributor.h:549
PointerIntPair< AADepGraphNode *, 1 > DepTy
Definition Attributor.h:529
void print(raw_ostream &OS) const
Definition Attributor.h:554
The data structure for the dependency graph.
Definition Attributor.h:569
~AADepGraph()=default
iterator begin()
Definition Attributor.h:584
mapped_iterator< AADepGraphNode::DepSetTy::iterator, decltype(&DepGetVal)> iterator
Definition Attributor.h:575
LLVM_ABI void viewGraph()
AADepGraphNode SyntheticRoot
There is no root node for the dependency graph.
Definition Attributor.h:581
LLVM_ABI void print()
Print dependency graph.
static AADepGraphNode * DepGetVal(const DepTy &DT)
Definition Attributor.h:574
iterator end()
Definition Attributor.h:585
LLVM_ABI void dumpGraph()
Dump graph to file.
AADepGraphNode * GetEntryNode()
Definition Attributor.h:582
AADepGraph()=default
AADepGraphNode::DepTy DepTy
Definition Attributor.h:573
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 LLVM_ABI bool isNoSyncIntrinsic(const Instruction *I)
Helper function specific for intrinsics which are potentially volatile.
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:444
static AA::ValueAndContext getEmptyKey()
Definition Attributor.h:434
static unsigned getHashValue(const AA::ValueAndContext &VAC)
Definition Attributor.h:440
DenseMapInfo< AA::ValueAndContext::Base > Base
Definition Attributor.h:433
static AA::ValueAndContext getTombstoneKey()
Definition Attributor.h:437
static AA::ValueScope getTombstoneKey()
Definition Attributor.h:456
static AA::ValueScope getEmptyKey()
Definition Attributor.h:453
static bool isEqual(const AA::ValueScope &LHS, const AA::ValueScope &RHS)
Definition Attributor.h:463
DenseMapInfo< unsigned char > Base
Definition Attributor.h:452
static unsigned getHashValue(const AA::ValueScope &S)
Definition Attributor.h:459
static IRPosition getEmptyKey()
static IRPosition getTombstoneKey()
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:605
Function * getAssociatedFunction() const
Return the associated function, if any.
Definition Attributor.h:736
void setAttrList(const AttributeList &AttrList) const
Update the attributes associated with this function or call site scope.
Definition Attributor.h:872
unsigned getAttrIdx() const
Return the index in the attribute list for this position.
Definition Attributor.h:837
bool hasCallBaseContext() const
Check if the position has any call base context.
Definition Attributor.h:954
static const IRPosition callsite_returned(const CallBase &CB)
Create a position describing the returned value of CB.
Definition Attributor.h:673
static const IRPosition returned(const Function &F, const CallBaseContext *CBContext=nullptr)
Create a position describing the returned value of F.
Definition Attributor.h:655
LLVM_ABI Argument * getAssociatedArgument() const
Return the associated argument, if any.
bool isAnyCallSitePosition() const
Definition Attributor.h:921
bool operator!=(const IRPosition &RHS) const
Definition Attributor.h:714
static const IRPosition value(const Value &V, const CallBaseContext *CBContext=nullptr)
Create a position describing the value of V.
Definition Attributor.h:629
CallBase CallBaseContext
Definition Attributor.h:608
AttributeList getAttrList() const
Return the attributes associated with this function or call site scope.
Definition Attributor.h:865
int getCalleeArgNo() const
Return the callee argument number of the associated value if it is an argument or call site argument,...
Definition Attributor.h:823
static const IRPosition inst(const Instruction &I, const CallBaseContext *CBContext=nullptr)
Create a position describing the instruction I.
Definition Attributor.h:641
static const IRPosition callsite_argument(const CallBase &CB, unsigned ArgNo)
Create a position describing the argument of CB at position ArgNo.
Definition Attributor.h:678
static LLVM_ABI const IRPosition TombstoneKey
Definition Attributor.h:960
Kind
The positions we distinguish in the IR.
Definition Attributor.h:611
@ IRP_ARGUMENT
An attribute for a function argument.
Definition Attributor.h:619
@ IRP_RETURNED
An attribute for the function return value.
Definition Attributor.h:615
@ IRP_CALL_SITE
An attribute for a call site (function scope).
Definition Attributor.h:618
@ IRP_CALL_SITE_RETURNED
An attribute for a call site return value.
Definition Attributor.h:616
@ IRP_FUNCTION
An attribute for a function (scope).
Definition Attributor.h:617
@ IRP_FLOAT
A position that is not associated with a spot suitable for attributes.
Definition Attributor.h:613
@ IRP_CALL_SITE_ARGUMENT
An attribute for a call site argument.
Definition Attributor.h:620
@ IRP_INVALID
An invalid position.
Definition Attributor.h:612
Instruction * getCtxI() const
Return the context instruction, if any.
Definition Attributor.h:789
static const IRPosition argument(const Argument &Arg, const CallBaseContext *CBContext=nullptr)
Create a position describing the argument Arg.
Definition Attributor.h:662
Type * getAssociatedType() const
Return the type this abstract attribute is associated with.
Definition Attributor.h:812
static LLVM_ABI const IRPosition EmptyKey
Special DenseMap key values.
Definition Attributor.h:959
bool isFunctionScope() const
Return true if this is a function or call site position.
Definition Attributor.h:766
bool operator==(const IRPosition &RHS) const
Definition Attributor.h:711
static const IRPosition callsite_argument(AbstractCallSite ACS, unsigned ArgNo)
Create a position describing the argument of ACS at position ArgNo.
Definition Attributor.h:685
static const IRPosition function(const Function &F, const CallBaseContext *CBContext=nullptr)
Create a position describing the function scope of F.
Definition Attributor.h:648
const CallBaseContext * getCallBaseContext() const
Get the call base context from the position.
Definition Attributor.h:951
Value & getAssociatedValue() const
Return the value this abstract attribute is associated with.
Definition Attributor.h:803
Value * getArg(unsigned ArgNo) const
Return theargument ArgNo associated with this function or call site scope.
Definition Attributor.h:891
Value & getAnchorValue() const
Return the value this abstract attribute is anchored with.
Definition Attributor.h:722
Value * getAttrListAnchor() const
Return the value attributes are attached to.
Definition Attributor.h:858
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:832
bool isFnInterfaceKind() const
Return true if the position refers to a function interface, that is the function scope,...
Definition Attributor.h:754
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:701
IRPosition stripCallBaseContext() const
Return the same position without the call base context.
Definition Attributor.h:944
unsigned getNumArgs() const
Return the number of arguments associated with this function or call site scope.
Definition Attributor.h:880
Kind getPositionKind() const
Return the associated position kind.
Definition Attributor.h:901
bool isArgumentPosition() const
Return true if the position is an argument or call site argument.
Definition Attributor.h:933
static const IRPosition callsite_function(const CallBase &CB)
Create a position describing the function scope of CB.
Definition Attributor.h:668
IRPosition()
Default constructor available to create invalid positions implicitly.
Definition Attributor.h:626
Function * getAnchorScope() const
Return the Function surrounding the anchor value.
Definition Attributor.h:777
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 to automatically provide informational APIs needed for passes.
Definition PassManager.h:70
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