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