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 /// Record that \p U is to be replaces with \p NV after information was
1832 /// manifested. This also triggers deletion of trivially dead istructions.
1834 Value *&V = ToBeChangedUses[&U];
1835 if (V && (V->stripPointerCasts() == NV.stripPointerCasts() ||
1836 isa_and_nonnull<UndefValue>(V)))
1837 return false;
1838 assert((!V || V == &NV || isa<UndefValue>(NV)) &&
1839 "Use was registered twice for replacement with different values!");
1840 V = &NV;
1841 return true;
1842 }
1843
1844 /// Helper function to replace all uses associated with \p IRP with \p NV.
1845 /// Return true if there is any change. The flag \p ChangeDroppable indicates
1846 /// if dropppable uses should be changed too.
1848 bool ChangeDroppable = true) {
1850 auto *CB = cast<CallBase>(IRP.getCtxI());
1852 CB->getArgOperandUse(IRP.getCallSiteArgNo()), NV);
1853 }
1854 Value &V = IRP.getAssociatedValue();
1855 auto &Entry = ToBeChangedValues[&V];
1856 Value *CurNV = get<0>(Entry);
1857 if (CurNV && (CurNV->stripPointerCasts() == NV.stripPointerCasts() ||
1858 isa<UndefValue>(CurNV)))
1859 return false;
1860 assert((!CurNV || CurNV == &NV || isa<UndefValue>(NV)) &&
1861 "Value replacement was registered twice with different values!");
1862 Entry = {&NV, ChangeDroppable};
1863 return true;
1864 }
1865
1866 /// Record that \p I is to be replaced with `unreachable` after information
1867 /// was manifested.
1869 ToBeChangedToUnreachableInsts.insert(I);
1870 }
1871
1872 /// Record that \p II has at least one dead successor block. This information
1873 /// is used, e.g., to replace \p II with a call, after information was
1874 /// manifested.
1876 InvokeWithDeadSuccessor.insert(&II);
1877 }
1878
1879 /// Record that \p I is deleted after information was manifested. This also
1880 /// triggers deletion of trivially dead istructions.
1881 void deleteAfterManifest(Instruction &I) { ToBeDeletedInsts.insert(&I); }
1882
1883 /// Record that \p BB is deleted after information was manifested. This also
1884 /// triggers deletion of trivially dead istructions.
1885 void deleteAfterManifest(BasicBlock &BB) { ToBeDeletedBlocks.insert(&BB); }
1886
1887 // Record that \p BB is added during the manifest of an AA. Added basic blocks
1888 // are preserved in the IR.
1890 ManifestAddedBlocks.insert(&BB);
1891 }
1892
1893 /// Record that \p F is deleted after information was manifested.
1895 if (Configuration.DeleteFns)
1896 ToBeDeletedFunctions.insert(&F);
1897 }
1898
1899 /// Return the attributes of kind \p AK existing in the IR as operand bundles
1900 /// of an llvm.assume.
1903
1904 /// Return true if any kind in \p AKs existing in the IR at a position that
1905 /// will affect this one. See also getAttrs(...).
1906 /// \param IgnoreSubsumingPositions Flag to determine if subsuming positions,
1907 /// e.g., the function position if this is an
1908 /// argument position, should be ignored.
1910 bool IgnoreSubsumingPositions = false,
1911 Attribute::AttrKind ImpliedAttributeKind = Attribute::None);
1912
1913 /// Return the attributes of any kind in \p AKs existing in the IR at a
1914 /// position that will affect this one. While each position can only have a
1915 /// single attribute of any kind in \p AKs, there are "subsuming" positions
1916 /// that could have an attribute as well. This method returns all attributes
1917 /// found in \p Attrs.
1918 /// \param IgnoreSubsumingPositions Flag to determine if subsuming positions,
1919 /// e.g., the function position if this is an
1920 /// argument position, should be ignored.
1923 bool IgnoreSubsumingPositions = false);
1924
1925 /// Remove all \p AttrKinds attached to \p IRP.
1929
1930 /// Attach \p DeducedAttrs to \p IRP, if \p ForceReplace is set we do this
1931 /// even if the same attribute kind was already present.
1933 ArrayRef<Attribute> DeducedAttrs,
1934 bool ForceReplace = false);
1935
1936private:
1937 /// Helper to check \p Attrs for \p AK, if not found, check if \p
1938 /// AAType::isImpliedByIR is true, and if not, create AAType for \p IRP.
1939 template <Attribute::AttrKind AK, typename AAType>
1940 void checkAndQueryIRAttr(const IRPosition &IRP, AttributeSet Attrs);
1941
1942 /// Helper to apply \p CB on all attributes of type \p AttrDescs of \p IRP.
1943 template <typename DescTy>
1944 ChangeStatus updateAttrMap(const IRPosition &IRP, ArrayRef<DescTy> AttrDescs,
1945 function_ref<bool(const DescTy &, AttributeSet,
1947 CB);
1948
1949 /// Mapping from functions/call sites to their attributes.
1951
1952public:
1953 /// If \p IRP is assumed to be a constant, return it, if it is unclear yet,
1954 /// return std::nullopt, otherwise return `nullptr`.
1955 std::optional<Constant *> getAssumedConstant(const IRPosition &IRP,
1956 const AbstractAttribute &AA,
1957 bool &UsedAssumedInformation);
1958 std::optional<Constant *> getAssumedConstant(const Value &V,
1959 const AbstractAttribute &AA,
1960 bool &UsedAssumedInformation) {
1961 return getAssumedConstant(IRPosition::value(V), AA, UsedAssumedInformation);
1962 }
1963
1964 /// If \p V is assumed simplified, return it, if it is unclear yet,
1965 /// return std::nullopt, otherwise return `nullptr`.
1966 std::optional<Value *> getAssumedSimplified(const IRPosition &IRP,
1967 const AbstractAttribute &AA,
1968 bool &UsedAssumedInformation,
1969 AA::ValueScope S) {
1970 return getAssumedSimplified(IRP, &AA, UsedAssumedInformation, S);
1971 }
1972 std::optional<Value *> getAssumedSimplified(const Value &V,
1973 const AbstractAttribute &AA,
1974 bool &UsedAssumedInformation,
1975 AA::ValueScope S) {
1977 UsedAssumedInformation, S);
1978 }
1979
1980 /// If \p V is assumed simplified, return it, if it is unclear yet,
1981 /// return std::nullopt, otherwise return `nullptr`. Same as the public
1982 /// version except that it can be used without recording dependences on any \p
1983 /// AA.
1984 std::optional<Value *> getAssumedSimplified(const IRPosition &V,
1985 const AbstractAttribute *AA,
1986 bool &UsedAssumedInformation,
1987 AA::ValueScope S);
1988
1989 /// Try to simplify \p IRP and in the scope \p S. If successful, true is
1990 /// returned and all potential values \p IRP can take are put into \p Values.
1991 /// If the result in \p Values contains select or PHI instructions it means
1992 /// those could not be simplified to a single value. Recursive calls with
1993 /// these instructions will yield their respective potential values. If false
1994 /// is returned no other information is valid.
1995 bool getAssumedSimplifiedValues(const IRPosition &IRP,
1996 const AbstractAttribute *AA,
1999 bool &UsedAssumedInformation,
2000 bool RecurseForSelectAndPHI = true);
2001
2002 /// Register \p CB as a simplification callback.
2003 /// `Attributor::getAssumedSimplified` will use these callbacks before
2004 /// we it will ask `AAValueSimplify`. It is important to ensure this
2005 /// is called before `identifyDefaultAbstractAttributes`, assuming the
2006 /// latter is called at all.
2007 using SimplifictionCallbackTy = std::function<std::optional<Value *>(
2008 const IRPosition &, const AbstractAttribute *, bool &)>;
2010 const SimplifictionCallbackTy &CB) {
2011 SimplificationCallbacks[IRP].emplace_back(CB);
2012 }
2013
2014 /// Return true if there is a simplification callback for \p IRP.
2016 return SimplificationCallbacks.count(IRP);
2017 }
2018
2019 /// Register \p CB as a simplification callback.
2020 /// Similar to \p registerSimplificationCallback, the call back will be called
2021 /// first when we simplify a global variable \p GV.
2023 std::function<std::optional<Constant *>(
2024 const GlobalVariable &, const AbstractAttribute *, bool &)>;
2026 const GlobalVariable &GV,
2028 GlobalVariableSimplificationCallbacks[&GV].emplace_back(CB);
2029 }
2030
2031 /// Return true if there is a simplification callback for \p GV.
2033 return GlobalVariableSimplificationCallbacks.count(&GV);
2034 }
2035
2036 /// Return \p std::nullopt if there is no call back registered for \p GV or
2037 /// the call back is still not sure if \p GV can be simplified. Return \p
2038 /// nullptr if \p GV can't be simplified.
2039 std::optional<Constant *>
2041 const AbstractAttribute *AA,
2042 bool &UsedAssumedInformation) {
2043 assert(GlobalVariableSimplificationCallbacks.contains(&GV));
2044 for (auto &CB : GlobalVariableSimplificationCallbacks.lookup(&GV)) {
2045 auto SimplifiedGV = CB(GV, AA, UsedAssumedInformation);
2046 // For now we assume the call back will not return a std::nullopt.
2047 assert(SimplifiedGV.has_value() && "SimplifiedGV has not value");
2048 return *SimplifiedGV;
2049 }
2050 llvm_unreachable("there must be a callback registered");
2051 }
2052
2054 std::function<bool(Attributor &, const AbstractAttribute *)>;
2056 const VirtualUseCallbackTy &CB) {
2057 VirtualUseCallbacks[&V].emplace_back(CB);
2058 }
2059
2060private:
2061 /// The vector with all simplification callbacks registered by outside AAs.
2063 SimplificationCallbacks;
2064
2065 /// The vector with all simplification callbacks for global variables
2066 /// registered by outside AAs.
2067 DenseMap<const GlobalVariable *,
2069 GlobalVariableSimplificationCallbacks;
2070
2072 VirtualUseCallbacks;
2073
2074public:
2075 /// Translate \p V from the callee context into the call site context.
2076 std::optional<Value *>
2077 translateArgumentToCallSiteContent(std::optional<Value *> V, CallBase &CB,
2078 const AbstractAttribute &AA,
2079 bool &UsedAssumedInformation);
2080
2081 /// Return true if \p AA (or its context instruction) is assumed dead.
2082 ///
2083 /// If \p LivenessAA is not provided it is queried.
2084 bool isAssumedDead(const AbstractAttribute &AA, const AAIsDead *LivenessAA,
2085 bool &UsedAssumedInformation,
2086 bool CheckBBLivenessOnly = false,
2087 DepClassTy DepClass = DepClassTy::OPTIONAL);
2088
2089 /// Return true if \p I is assumed dead.
2090 ///
2091 /// If \p LivenessAA is not provided it is queried.
2092 bool isAssumedDead(const Instruction &I, const AbstractAttribute *QueryingAA,
2093 const AAIsDead *LivenessAA, bool &UsedAssumedInformation,
2094 bool CheckBBLivenessOnly = false,
2096 bool CheckForDeadStore = false);
2097
2098 /// Return true if \p U is assumed dead.
2099 ///
2100 /// If \p FnLivenessAA is not provided it is queried.
2101 bool isAssumedDead(const Use &U, const AbstractAttribute *QueryingAA,
2102 const AAIsDead *FnLivenessAA, bool &UsedAssumedInformation,
2103 bool CheckBBLivenessOnly = false,
2104 DepClassTy DepClass = DepClassTy::OPTIONAL);
2105
2106 /// Return true if \p IRP is assumed dead.
2107 ///
2108 /// If \p FnLivenessAA is not provided it is queried.
2109 bool isAssumedDead(const IRPosition &IRP, const AbstractAttribute *QueryingAA,
2110 const AAIsDead *FnLivenessAA, bool &UsedAssumedInformation,
2111 bool CheckBBLivenessOnly = false,
2112 DepClassTy DepClass = DepClassTy::OPTIONAL);
2113
2114 /// Return true if \p BB is assumed dead.
2115 ///
2116 /// If \p LivenessAA is not provided it is queried.
2117 bool isAssumedDead(const BasicBlock &BB, const AbstractAttribute *QueryingAA,
2118 const AAIsDead *FnLivenessAA,
2119 DepClassTy DepClass = DepClassTy::OPTIONAL);
2120
2121 /// Check \p Pred on all potential Callees of \p CB.
2122 ///
2123 /// This method will evaluate \p Pred with all potential callees of \p CB as
2124 /// input and return true if \p Pred does. If some callees might be unknown
2125 /// this function will return false.
2126 bool checkForAllCallees(
2127 function_ref<bool(ArrayRef<const Function *> Callees)> Pred,
2128 const AbstractAttribute &QueryingAA, const CallBase &CB);
2129
2130 /// Check \p Pred on all (transitive) uses of \p V.
2131 ///
2132 /// This method will evaluate \p Pred on all (transitive) uses of the
2133 /// associated value and return true if \p Pred holds every time.
2134 /// If uses are skipped in favor of equivalent ones, e.g., if we look through
2135 /// memory, the \p EquivalentUseCB will be used to give the caller an idea
2136 /// what original used was replaced by a new one (or new ones). The visit is
2137 /// cut short if \p EquivalentUseCB returns false and the function will return
2138 /// false as well.
2139 bool checkForAllUses(function_ref<bool(const Use &, bool &)> Pred,
2140 const AbstractAttribute &QueryingAA, const Value &V,
2141 bool CheckBBLivenessOnly = false,
2142 DepClassTy LivenessDepClass = DepClassTy::OPTIONAL,
2143 bool IgnoreDroppableUses = true,
2144 function_ref<bool(const Use &OldU, const Use &NewU)>
2145 EquivalentUseCB = nullptr);
2146
2147 /// Emit a remark generically.
2148 ///
2149 /// This template function can be used to generically emit a remark. The
2150 /// RemarkKind should be one of the following:
2151 /// - OptimizationRemark to indicate a successful optimization attempt
2152 /// - OptimizationRemarkMissed to report a failed optimization attempt
2153 /// - OptimizationRemarkAnalysis to provide additional information about an
2154 /// optimization attempt
2155 ///
2156 /// The remark is built using a callback function \p RemarkCB that takes a
2157 /// RemarkKind as input and returns a RemarkKind.
2158 template <typename RemarkKind, typename RemarkCallBack>
2160 RemarkCallBack &&RemarkCB) const {
2161 if (!Configuration.OREGetter)
2162 return;
2163
2164 Function *F = I->getFunction();
2165 auto &ORE = Configuration.OREGetter(F);
2166
2167 if (RemarkName.starts_with("OMP"))
2168 ORE.emit([&]() {
2169 return RemarkCB(RemarkKind(Configuration.PassName, RemarkName, I))
2170 << " [" << RemarkName << "]";
2171 });
2172 else
2173 ORE.emit([&]() {
2174 return RemarkCB(RemarkKind(Configuration.PassName, RemarkName, I));
2175 });
2176 }
2177
2178 /// Emit a remark on a function.
2179 template <typename RemarkKind, typename RemarkCallBack>
2180 void emitRemark(Function *F, StringRef RemarkName,
2181 RemarkCallBack &&RemarkCB) const {
2182 if (!Configuration.OREGetter)
2183 return;
2184
2185 auto &ORE = Configuration.OREGetter(F);
2186
2187 if (RemarkName.starts_with("OMP"))
2188 ORE.emit([&]() {
2189 return RemarkCB(RemarkKind(Configuration.PassName, RemarkName, F))
2190 << " [" << RemarkName << "]";
2191 });
2192 else
2193 ORE.emit([&]() {
2194 return RemarkCB(RemarkKind(Configuration.PassName, RemarkName, F));
2195 });
2196 }
2197
2198 /// Helper struct used in the communication between an abstract attribute (AA)
2199 /// that wants to change the signature of a function and the Attributor which
2200 /// applies the changes. The struct is partially initialized with the
2201 /// information from the AA (see the constructor). All other members are
2202 /// provided by the Attributor prior to invoking any callbacks.
2204 /// Callee repair callback type
2205 ///
2206 /// The function repair callback is invoked once to rewire the replacement
2207 /// arguments in the body of the new function. The argument replacement info
2208 /// is passed, as build from the registerFunctionSignatureRewrite call, as
2209 /// well as the replacement function and an iteratore to the first
2210 /// replacement argument.
2211 using CalleeRepairCBTy = std::function<void(
2213
2214 /// Abstract call site (ACS) repair callback type
2215 ///
2216 /// The abstract call site repair callback is invoked once on every abstract
2217 /// call site of the replaced function (\see ReplacedFn). The callback needs
2218 /// to provide the operands for the call to the new replacement function.
2219 /// The number and type of the operands appended to the provided vector
2220 /// (second argument) is defined by the number and types determined through
2221 /// the replacement type vector (\see ReplacementTypes). The first argument
2222 /// is the ArgumentReplacementInfo object registered with the Attributor
2223 /// through the registerFunctionSignatureRewrite call.
2225 std::function<void(const ArgumentReplacementInfo &, AbstractCallSite,
2227
2228 /// Simple getters, see the corresponding members for details.
2229 ///{
2230
2231 Attributor &getAttributor() const { return A; }
2232 const Function &getReplacedFn() const { return ReplacedFn; }
2233 const Argument &getReplacedArg() const { return ReplacedArg; }
2234 unsigned getNumReplacementArgs() const { return ReplacementTypes.size(); }
2236 return ReplacementTypes;
2237 }
2238
2239 ///}
2240
2241 private:
2242 /// Constructor that takes the argument to be replaced, the types of
2243 /// the replacement arguments, as well as callbacks to repair the call sites
2244 /// and new function after the replacement happened.
2246 ArrayRef<Type *> ReplacementTypes,
2247 CalleeRepairCBTy &&CalleeRepairCB,
2248 ACSRepairCBTy &&ACSRepairCB)
2249 : A(A), ReplacedFn(*Arg.getParent()), ReplacedArg(Arg),
2250 ReplacementTypes(ReplacementTypes.begin(), ReplacementTypes.end()),
2251 CalleeRepairCB(std::move(CalleeRepairCB)),
2252 ACSRepairCB(std::move(ACSRepairCB)) {}
2253
2254 /// Reference to the attributor to allow access from the callbacks.
2255 Attributor &A;
2256
2257 /// The "old" function replaced by ReplacementFn.
2258 const Function &ReplacedFn;
2259
2260 /// The "old" argument replaced by new ones defined via ReplacementTypes.
2261 const Argument &ReplacedArg;
2262
2263 /// The types of the arguments replacing ReplacedArg.
2264 const SmallVector<Type *, 8> ReplacementTypes;
2265
2266 /// Callee repair callback, see CalleeRepairCBTy.
2267 const CalleeRepairCBTy CalleeRepairCB;
2268
2269 /// Abstract call site (ACS) repair callback, see ACSRepairCBTy.
2270 const ACSRepairCBTy ACSRepairCB;
2271
2272 /// Allow access to the private members from the Attributor.
2273 friend struct Attributor;
2274 };
2275
2276 /// Check if we can rewrite a function signature.
2277 ///
2278 /// The argument \p Arg is replaced with new ones defined by the number,
2279 /// order, and types in \p ReplacementTypes.
2280 ///
2281 /// \returns True, if the replacement can be registered, via
2282 /// registerFunctionSignatureRewrite, false otherwise.
2284 ArrayRef<Type *> ReplacementTypes);
2285
2286 /// Register a rewrite for a function signature.
2287 ///
2288 /// The argument \p Arg is replaced with new ones defined by the number,
2289 /// order, and types in \p ReplacementTypes. The rewiring at the call sites is
2290 /// done through \p ACSRepairCB and at the callee site through
2291 /// \p CalleeRepairCB.
2292 ///
2293 /// \returns True, if the replacement was registered, false otherwise.
2295 Argument &Arg, ArrayRef<Type *> ReplacementTypes,
2298
2299 /// Check \p Pred on all function call sites.
2300 ///
2301 /// This method will evaluate \p Pred on call sites and return
2302 /// true if \p Pred holds in every call sites. However, this is only possible
2303 /// all call sites are known, hence the function has internal linkage.
2304 /// If true is returned, \p UsedAssumedInformation is set if assumed
2305 /// information was used to skip or simplify potential call sites.
2307 const AbstractAttribute &QueryingAA,
2308 bool RequireAllCallSites,
2309 bool &UsedAssumedInformation);
2310
2311 /// Check \p Pred on all call sites of \p Fn.
2312 ///
2313 /// This method will evaluate \p Pred on call sites and return
2314 /// true if \p Pred holds in every call sites. However, this is only possible
2315 /// all call sites are known, hence the function has internal linkage.
2316 /// If true is returned, \p UsedAssumedInformation is set if assumed
2317 /// information was used to skip or simplify potential call sites.
2319 const Function &Fn, bool RequireAllCallSites,
2320 const AbstractAttribute *QueryingAA,
2321 bool &UsedAssumedInformation,
2322 bool CheckPotentiallyDead = false);
2323
2324 /// Check \p Pred on all values potentially returned by the function
2325 /// associated with \p QueryingAA.
2326 ///
2327 /// This is the context insensitive version of the method above.
2328 bool
2330 const AbstractAttribute &QueryingAA,
2332 bool RecurseForSelectAndPHI = true);
2333
2334 /// Check \p Pred on all instructions in \p Fn with an opcode present in
2335 /// \p Opcodes.
2336 ///
2337 /// This method will evaluate \p Pred on all instructions with an opcode
2338 /// present in \p Opcode and return true if \p Pred holds on all of them.
2340 const Function *Fn,
2341 const AbstractAttribute *QueryingAA,
2342 ArrayRef<unsigned> Opcodes,
2343 bool &UsedAssumedInformation,
2344 bool CheckBBLivenessOnly = false,
2345 bool CheckPotentiallyDead = false);
2346
2347 /// Check \p Pred on all instructions with an opcode present in \p Opcodes.
2348 ///
2349 /// This method will evaluate \p Pred on all instructions with an opcode
2350 /// present in \p Opcode and return true if \p Pred holds on all of them.
2352 const AbstractAttribute &QueryingAA,
2353 ArrayRef<unsigned> Opcodes,
2354 bool &UsedAssumedInformation,
2355 bool CheckBBLivenessOnly = false,
2356 bool CheckPotentiallyDead = false);
2357
2358 /// Check \p Pred on all call-like instructions (=CallBased derived).
2359 ///
2360 /// See checkForAllCallLikeInstructions(...) for more information.
2362 const AbstractAttribute &QueryingAA,
2363 bool &UsedAssumedInformation,
2364 bool CheckBBLivenessOnly = false,
2365 bool CheckPotentiallyDead = false) {
2367 Pred, QueryingAA,
2368 {(unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,
2369 (unsigned)Instruction::Call},
2370 UsedAssumedInformation, CheckBBLivenessOnly, CheckPotentiallyDead);
2371 }
2372
2373 /// Check \p Pred on all Read/Write instructions.
2374 ///
2375 /// This method will evaluate \p Pred on all instructions that read or write
2376 /// to memory present in the information cache and return true if \p Pred
2377 /// holds on all of them.
2379 AbstractAttribute &QueryingAA,
2380 bool &UsedAssumedInformation);
2381
2382 /// Create a shallow wrapper for \p F such that \p F has internal linkage
2383 /// afterwards. It also sets the original \p F 's name to anonymous
2384 ///
2385 /// A wrapper is a function with the same type (and attributes) as \p F
2386 /// that will only call \p F and return the result, if any.
2387 ///
2388 /// Assuming the declaration of looks like:
2389 /// rty F(aty0 arg0, ..., atyN argN);
2390 ///
2391 /// The wrapper will then look as follows:
2392 /// rty wrapper(aty0 arg0, ..., atyN argN) {
2393 /// return F(arg0, ..., argN);
2394 /// }
2395 ///
2396 static void createShallowWrapper(Function &F);
2397
2398 /// Returns true if the function \p F can be internalized. i.e. it has a
2399 /// compatible linkage.
2400 static bool isInternalizable(Function &F);
2401
2402 /// Make another copy of the function \p F such that the copied version has
2403 /// internal linkage afterwards and can be analysed. Then we replace all uses
2404 /// of the original function to the copied one
2405 ///
2406 /// Only non-locally linked functions that have `linkonce_odr` or `weak_odr`
2407 /// linkage can be internalized because these linkages guarantee that other
2408 /// definitions with the same name have the same semantics as this one.
2409 ///
2410 /// This will only be run if the `attributor-allow-deep-wrappers` option is
2411 /// set, or if the function is called with \p Force set to true.
2412 ///
2413 /// If the function \p F failed to be internalized the return value will be a
2414 /// null pointer.
2415 static Function *internalizeFunction(Function &F, bool Force = false);
2416
2417 /// Make copies of each function in the set \p FnSet such that the copied
2418 /// version has internal linkage afterwards and can be analysed. Then we
2419 /// replace all uses of the original function to the copied one. The map
2420 /// \p FnMap contains a mapping of functions to their internalized versions.
2421 ///
2422 /// Only non-locally linked functions that have `linkonce_odr` or `weak_odr`
2423 /// linkage can be internalized because these linkages guarantee that other
2424 /// definitions with the same name have the same semantics as this one.
2425 ///
2426 /// This version will internalize all the functions in the set \p FnSet at
2427 /// once and then replace the uses. This prevents internalized functions being
2428 /// called by external functions when there is an internalized version in the
2429 /// module.
2432
2433 /// Return the data layout associated with the anchor scope.
2434 const DataLayout &getDataLayout() const { return InfoCache.DL; }
2435
2436 /// The allocator used to allocate memory, e.g. for `AbstractAttribute`s.
2438
2440 return CGModifiedFunctions;
2441 }
2442
2443private:
2444 /// This method will do fixpoint iteration until fixpoint or the
2445 /// maximum iteration count is reached.
2446 ///
2447 /// If the maximum iteration count is reached, This method will
2448 /// indicate pessimistic fixpoint on attributes that transitively depend
2449 /// on attributes that were scheduled for an update.
2450 void runTillFixpoint();
2451
2452 /// Gets called after scheduling, manifests attributes to the LLVM IR.
2453 ChangeStatus manifestAttributes();
2454
2455 /// Gets called after attributes have been manifested, cleans up the IR.
2456 /// Deletes dead functions, blocks and instructions.
2457 /// Rewrites function signitures and updates the call graph.
2458 ChangeStatus cleanupIR();
2459
2460 /// Identify internal functions that are effectively dead, thus not reachable
2461 /// from a live entry point. The functions are added to ToBeDeletedFunctions.
2462 void identifyDeadInternalFunctions();
2463
2464 /// Run `::update` on \p AA and track the dependences queried while doing so.
2465 /// Also adjust the state if we know further updates are not necessary.
2466 ChangeStatus updateAA(AbstractAttribute &AA);
2467
2468 /// Remember the dependences on the top of the dependence stack such that they
2469 /// may trigger further updates. (\see DependenceStack)
2470 void rememberDependences();
2471
2472 /// Determine if CallBase context in \p IRP should be propagated.
2473 bool shouldPropagateCallBaseContext(const IRPosition &IRP);
2474
2475 /// Apply all requested function signature rewrites
2476 /// (\see registerFunctionSignatureRewrite) and return Changed if the module
2477 /// was altered.
2479 rewriteFunctionSignatures(SmallSetVector<Function *, 8> &ModifiedFns);
2480
2481 /// Check if the Attribute \p AA should be seeded.
2482 /// See getOrCreateAAFor.
2483 bool shouldSeedAttribute(AbstractAttribute &AA);
2484
2485 /// A nested map to lookup abstract attributes based on the argument position
2486 /// on the outer level, and the addresses of the static member (AAType::ID) on
2487 /// the inner level.
2488 ///{
2489 using AAMapKeyTy = std::pair<const char *, IRPosition>;
2491 ///}
2492
2493 /// Map to remember all requested signature changes (= argument replacements).
2495 ArgumentReplacementMap;
2496
2497 /// The set of functions we are deriving attributes for.
2498 SetVector<Function *> &Functions;
2499
2500 /// The information cache that holds pre-processed (LLVM-IR) information.
2501 InformationCache &InfoCache;
2502
2503 /// Abstract Attribute dependency graph
2504 AADepGraph DG;
2505
2506 /// Set of functions for which we modified the content such that it might
2507 /// impact the call graph.
2508 SmallSetVector<Function *, 8> CGModifiedFunctions;
2509
2510 /// Information about a dependence. If FromAA is changed ToAA needs to be
2511 /// updated as well.
2512 struct DepInfo {
2513 const AbstractAttribute *FromAA;
2514 const AbstractAttribute *ToAA;
2515 DepClassTy DepClass;
2516 };
2517
2518 /// The dependence stack is used to track dependences during an
2519 /// `AbstractAttribute::update` call. As `AbstractAttribute::update` can be
2520 /// recursive we might have multiple vectors of dependences in here. The stack
2521 /// size, should be adjusted according to the expected recursion depth and the
2522 /// inner dependence vector size to the expected number of dependences per
2523 /// abstract attribute. Since the inner vectors are actually allocated on the
2524 /// stack we can be generous with their size.
2525 using DependenceVector = SmallVector<DepInfo, 8>;
2526 SmallVector<DependenceVector *, 16> DependenceStack;
2527
2528 /// A set to remember the functions we already assume to be live and visited.
2529 DenseSet<const Function *> VisitedFunctions;
2530
2531 /// Uses we replace with a new value after manifest is done. We will remove
2532 /// then trivially dead instructions as well.
2533 SmallMapVector<Use *, Value *, 32> ToBeChangedUses;
2534
2535 /// Values we replace with a new value after manifest is done. We will remove
2536 /// then trivially dead instructions as well.
2537 SmallMapVector<Value *, PointerIntPair<Value *, 1, bool>, 32>
2538 ToBeChangedValues;
2539
2540 /// Instructions we replace with `unreachable` insts after manifest is done.
2541 SmallSetVector<WeakVH, 16> ToBeChangedToUnreachableInsts;
2542
2543 /// Invoke instructions with at least a single dead successor block.
2544 SmallSetVector<WeakVH, 16> InvokeWithDeadSuccessor;
2545
2546 /// A flag that indicates which stage of the process we are in. Initially, the
2547 /// phase is SEEDING. Phase is changed in `Attributor::run()`
2548 enum class AttributorPhase {
2549 SEEDING,
2550 UPDATE,
2551 MANIFEST,
2552 CLEANUP,
2553 } Phase = AttributorPhase::SEEDING;
2554
2555 /// The current initialization chain length. Tracked to avoid stack overflows.
2556 unsigned InitializationChainLength = 0;
2557
2558 /// Functions, blocks, and instructions we delete after manifest is done.
2559 ///
2560 ///{
2561 SmallPtrSet<BasicBlock *, 8> ManifestAddedBlocks;
2562 SmallSetVector<Function *, 8> ToBeDeletedFunctions;
2563 SmallSetVector<BasicBlock *, 8> ToBeDeletedBlocks;
2564 SmallSetVector<WeakVH, 8> ToBeDeletedInsts;
2565 ///}
2566
2567 /// Container with all the query AAs that requested an update via
2568 /// registerForUpdate.
2569 SmallSetVector<AbstractAttribute *, 16> QueryAAsAwaitingUpdate;
2570
2571 /// User provided configuration for this Attributor instance.
2572 const AttributorConfig Configuration;
2573
2574 friend AADepGraph;
2575 friend AttributorCallGraph;
2576};
2577
2578/// An interface to query the internal state of an abstract attribute.
2579///
2580/// The abstract state is a minimal interface that allows the Attributor to
2581/// communicate with the abstract attributes about their internal state without
2582/// enforcing or exposing implementation details, e.g., the (existence of an)
2583/// underlying lattice.
2584///
2585/// It is sufficient to be able to query if a state is (1) valid or invalid, (2)
2586/// at a fixpoint, and to indicate to the state that (3) an optimistic fixpoint
2587/// was reached or (4) a pessimistic fixpoint was enforced.
2588///
2589/// All methods need to be implemented by the subclass. For the common use case,
2590/// a single boolean state or a bit-encoded state, the BooleanState and
2591/// {Inc,Dec,Bit}IntegerState classes are already provided. An abstract
2592/// attribute can inherit from them to get the abstract state interface and
2593/// additional methods to directly modify the state based if needed. See the
2594/// class comments for help.
2596 virtual ~AbstractState() = default;
2597
2598 /// Return if this abstract state is in a valid state. If false, no
2599 /// information provided should be used.
2600 virtual bool isValidState() const = 0;
2601
2602 /// Return if this abstract state is fixed, thus does not need to be updated
2603 /// if information changes as it cannot change itself.
2604 virtual bool isAtFixpoint() const = 0;
2605
2606 /// Indicate that the abstract state should converge to the optimistic state.
2607 ///
2608 /// This will usually make the optimistically assumed state the known to be
2609 /// true state.
2610 ///
2611 /// \returns ChangeStatus::UNCHANGED as the assumed value should not change.
2613
2614 /// Indicate that the abstract state should converge to the pessimistic state.
2615 ///
2616 /// This will usually revert the optimistically assumed state to the known to
2617 /// be true state.
2618 ///
2619 /// \returns ChangeStatus::CHANGED as the assumed value may change.
2621};
2622
2623/// Simple state with integers encoding.
2624///
2625/// The interface ensures that the assumed bits are always a subset of the known
2626/// bits. Users can only add known bits and, except through adding known bits,
2627/// they can only remove assumed bits. This should guarantee monotonicity and
2628/// thereby the existence of a fixpoint (if used correctly). The fixpoint is
2629/// reached when the assumed and known state/bits are equal. Users can
2630/// force/inidicate a fixpoint. If an optimistic one is indicated, the known
2631/// state will catch up with the assumed one, for a pessimistic fixpoint it is
2632/// the other way around.
2633template <typename base_ty, base_ty BestState, base_ty WorstState>
2635 using base_t = base_ty;
2636
2637 IntegerStateBase() = default;
2639
2640 /// Return the best possible representable state.
2641 static constexpr base_t getBestState() { return BestState; }
2642 static constexpr base_t getBestState(const IntegerStateBase &) {
2643 return getBestState();
2644 }
2645
2646 /// Return the worst possible representable state.
2647 static constexpr base_t getWorstState() { return WorstState; }
2648 static constexpr base_t getWorstState(const IntegerStateBase &) {
2649 return getWorstState();
2650 }
2651
2652 /// See AbstractState::isValidState()
2653 /// NOTE: For now we simply pretend that the worst possible state is invalid.
2654 bool isValidState() const override { return Assumed != getWorstState(); }
2655
2656 /// See AbstractState::isAtFixpoint()
2657 bool isAtFixpoint() const override { return Assumed == Known; }
2658
2659 /// See AbstractState::indicateOptimisticFixpoint(...)
2661 Known = Assumed;
2663 }
2664
2665 /// See AbstractState::indicatePessimisticFixpoint(...)
2667 Assumed = Known;
2668 return ChangeStatus::CHANGED;
2669 }
2670
2671 /// Return the known state encoding
2672 base_t getKnown() const { return Known; }
2673
2674 /// Return the assumed state encoding.
2675 base_t getAssumed() const { return Assumed; }
2676
2677 /// Equality for IntegerStateBase.
2678 bool
2680 return this->getAssumed() == R.getAssumed() &&
2681 this->getKnown() == R.getKnown();
2682 }
2683
2684 /// Inequality for IntegerStateBase.
2685 bool
2687 return !(*this == R);
2688 }
2689
2690 /// "Clamp" this state with \p R. The result is subtype dependent but it is
2691 /// intended that only information assumed in both states will be assumed in
2692 /// this one afterwards.
2694 handleNewAssumedValue(R.getAssumed());
2695 }
2696
2697 /// "Clamp" this state with \p R. The result is subtype dependent but it is
2698 /// intended that information known in either state will be known in
2699 /// this one afterwards.
2701 handleNewKnownValue(R.getKnown());
2702 }
2703
2705 joinOR(R.getAssumed(), R.getKnown());
2706 }
2707
2709 joinAND(R.getAssumed(), R.getKnown());
2710 }
2711
2712protected:
2713 /// Handle a new assumed value \p Value. Subtype dependent.
2715
2716 /// Handle a new known value \p Value. Subtype dependent.
2718
2719 /// Handle a value \p Value. Subtype dependent.
2720 virtual void joinOR(base_t AssumedValue, base_t KnownValue) = 0;
2721
2722 /// Handle a new assumed value \p Value. Subtype dependent.
2723 virtual void joinAND(base_t AssumedValue, base_t KnownValue) = 0;
2724
2725 /// The known state encoding in an integer of type base_t.
2727
2728 /// The assumed state encoding in an integer of type base_t.
2730};
2731
2732/// Specialization of the integer state for a bit-wise encoding.
2733template <typename base_ty = uint32_t, base_ty BestState = ~base_ty(0),
2734 base_ty WorstState = 0>
2736 : public IntegerStateBase<base_ty, BestState, WorstState> {
2738 using base_t = base_ty;
2739 BitIntegerState() = default;
2741
2742 /// Return true if the bits set in \p BitsEncoding are "known bits".
2743 bool isKnown(base_t BitsEncoding = BestState) const {
2744 return (this->Known & BitsEncoding) == BitsEncoding;
2745 }
2746
2747 /// Return true if the bits set in \p BitsEncoding are "assumed bits".
2748 bool isAssumed(base_t BitsEncoding = BestState) const {
2749 return (this->Assumed & BitsEncoding) == BitsEncoding;
2750 }
2751
2752 /// Add the bits in \p BitsEncoding to the "known bits".
2754 // Make sure we never miss any "known bits".
2755 this->Assumed |= Bits;
2756 this->Known |= Bits;
2757 return *this;
2758 }
2759
2760 /// Remove the bits in \p BitsEncoding from the "assumed bits" if not known.
2762 return intersectAssumedBits(~BitsEncoding);
2763 }
2764
2765 /// Remove the bits in \p BitsEncoding from the "known bits".
2767 this->Known = (this->Known & ~BitsEncoding);
2768 return *this;
2769 }
2770
2771 /// Keep only "assumed bits" also set in \p BitsEncoding but all known ones.
2773 // Make sure we never lose any "known bits".
2774 this->Assumed = (this->Assumed & BitsEncoding) | this->Known;
2775 return *this;
2776 }
2777
2778private:
2779 void handleNewAssumedValue(base_t Value) override {
2781 }
2782 void handleNewKnownValue(base_t Value) override { addKnownBits(Value); }
2783 void joinOR(base_t AssumedValue, base_t KnownValue) override {
2784 this->Known |= KnownValue;
2785 this->Assumed |= AssumedValue;
2786 }
2787 void joinAND(base_t AssumedValue, base_t KnownValue) override {
2788 this->Known &= KnownValue;
2789 this->Assumed &= AssumedValue;
2790 }
2791};
2792
2793/// Specialization of the integer state for an increasing value, hence ~0u is
2794/// the best state and 0 the worst.
2795template <typename base_ty = uint32_t, base_ty BestState = ~base_ty(0),
2796 base_ty WorstState = 0>
2798 : public IntegerStateBase<base_ty, BestState, WorstState> {
2800 using base_t = base_ty;
2801
2804
2805 /// Return the best possible representable state.
2806 static constexpr base_t getBestState() { return BestState; }
2807 static constexpr base_t
2809 return getBestState();
2810 }
2811
2812 /// Take minimum of assumed and \p Value.
2814 // Make sure we never lose "known value".
2815 this->Assumed = std::max(std::min(this->Assumed, Value), this->Known);
2816 return *this;
2817 }
2818
2819 /// Take maximum of known and \p Value.
2821 // Make sure we never lose "known value".
2822 this->Assumed = std::max(Value, this->Assumed);
2823 this->Known = std::max(Value, this->Known);
2824 return *this;
2825 }
2826
2827private:
2828 void handleNewAssumedValue(base_t Value) override {
2830 }
2831 void handleNewKnownValue(base_t Value) override { takeKnownMaximum(Value); }
2832 void joinOR(base_t AssumedValue, base_t KnownValue) override {
2833 this->Known = std::max(this->Known, KnownValue);
2834 this->Assumed = std::max(this->Assumed, AssumedValue);
2835 }
2836 void joinAND(base_t AssumedValue, base_t KnownValue) override {
2837 this->Known = std::min(this->Known, KnownValue);
2838 this->Assumed = std::min(this->Assumed, AssumedValue);
2839 }
2840};
2841
2842/// Specialization of the integer state for a decreasing value, hence 0 is the
2843/// best state and ~0u the worst.
2844template <typename base_ty = uint32_t>
2845struct DecIntegerState : public IntegerStateBase<base_ty, 0, ~base_ty(0)> {
2846 using base_t = base_ty;
2847
2848 /// Take maximum of assumed and \p Value.
2850 // Make sure we never lose "known value".
2851 this->Assumed = std::min(std::max(this->Assumed, Value), this->Known);
2852 return *this;
2853 }
2854
2855 /// Take minimum of known and \p Value.
2857 // Make sure we never lose "known value".
2858 this->Assumed = std::min(Value, this->Assumed);
2859 this->Known = std::min(Value, this->Known);
2860 return *this;
2861 }
2862
2863private:
2864 void handleNewAssumedValue(base_t Value) override {
2866 }
2867 void handleNewKnownValue(base_t Value) override { takeKnownMinimum(Value); }
2868 void joinOR(base_t AssumedValue, base_t KnownValue) override {
2869 this->Assumed = std::min(this->Assumed, KnownValue);
2870 this->Assumed = std::min(this->Assumed, AssumedValue);
2871 }
2872 void joinAND(base_t AssumedValue, base_t KnownValue) override {
2873 this->Assumed = std::max(this->Assumed, KnownValue);
2874 this->Assumed = std::max(this->Assumed, AssumedValue);
2875 }
2876};
2877
2878/// Simple wrapper for a single bit (boolean) state.
2879struct BooleanState : public IntegerStateBase<bool, true, false> {
2882
2883 BooleanState() = default;
2885
2886 /// Set the assumed value to \p Value but never below the known one.
2887 void setAssumed(bool Value) { Assumed &= (Known | Value); }
2888
2889 /// Set the known and asssumed value to \p Value.
2890 void setKnown(bool Value) {
2891 Known |= Value;
2892 Assumed |= Value;
2893 }
2894
2895 /// Return true if the state is assumed to hold.
2896 bool isAssumed() const { return getAssumed(); }
2897
2898 /// Return true if the state is known to hold.
2899 bool isKnown() const { return getKnown(); }
2900
2901private:
2902 void handleNewAssumedValue(base_t Value) override {
2903 if (!Value)
2904 Assumed = Known;
2905 }
2906 void handleNewKnownValue(base_t Value) override {
2907 if (Value)
2908 Known = (Assumed = Value);
2909 }
2910 void joinOR(base_t AssumedValue, base_t KnownValue) override {
2911 Known |= KnownValue;
2912 Assumed |= AssumedValue;
2913 }
2914 void joinAND(base_t AssumedValue, base_t KnownValue) override {
2915 Known &= KnownValue;
2916 Assumed &= AssumedValue;
2917 }
2918};
2919
2920/// State for an integer range.
2922
2923 /// Bitwidth of the associated value.
2925
2926 /// State representing assumed range, initially set to empty.
2928
2929 /// State representing known range, initially set to [-inf, inf].
2931
2934 Known(ConstantRange::getFull(BitWidth)) {}
2935
2937 : BitWidth(CR.getBitWidth()), Assumed(CR),
2939
2940 /// Return the worst possible representable state.
2942 return ConstantRange::getFull(BitWidth);
2943 }
2944
2945 /// Return the best possible representable state.
2947 return ConstantRange::getEmpty(BitWidth);
2948 }
2950 return getBestState(IRS.getBitWidth());
2951 }
2952
2953 /// Return associated values' bit width.
2954 uint32_t getBitWidth() const { return BitWidth; }
2955
2956 /// See AbstractState::isValidState()
2957 bool isValidState() const override {
2958 return BitWidth > 0 && !Assumed.isFullSet();
2959 }
2960
2961 /// See AbstractState::isAtFixpoint()
2962 bool isAtFixpoint() const override { return Assumed == Known; }
2963
2964 /// See AbstractState::indicateOptimisticFixpoint(...)
2966 Known = Assumed;
2967 return ChangeStatus::CHANGED;
2968 }
2969
2970 /// See AbstractState::indicatePessimisticFixpoint(...)
2972 Assumed = Known;
2973 return ChangeStatus::CHANGED;
2974 }
2975
2976 /// Return the known state encoding
2977 ConstantRange getKnown() const { return Known; }
2978
2979 /// Return the assumed state encoding.
2981
2982 /// Unite assumed range with the passed state.
2984 // Don't lose a known range.
2986 }
2987
2988 /// See IntegerRangeState::unionAssumed(..).
2990 unionAssumed(R.getAssumed());
2991 }
2992
2993 /// Intersect known range with the passed state.
2997 }
2998
2999 /// See IntegerRangeState::intersectKnown(..).
3001 intersectKnown(R.getKnown());
3002 }
3003
3004 /// Equality for IntegerRangeState.
3005 bool operator==(const IntegerRangeState &R) const {
3006 return getAssumed() == R.getAssumed() && getKnown() == R.getKnown();
3007 }
3008
3009 /// "Clamp" this state with \p R. The result is subtype dependent but it is
3010 /// intended that only information assumed in both states will be assumed in
3011 /// this one afterwards.
3013 // NOTE: `^=` operator seems like `intersect` but in this case, we need to
3014 // take `union`.
3015 unionAssumed(R);
3016 return *this;
3017 }
3018
3020 // NOTE: `&=` operator seems like `intersect` but in this case, we need to
3021 // take `union`.
3022 Known = Known.unionWith(R.getKnown());
3023 Assumed = Assumed.unionWith(R.getAssumed());
3024 return *this;
3025 }
3026};
3027
3028/// Simple state for a set.
3029///
3030/// This represents a state containing a set of values. The interface supports
3031/// modelling sets that contain all possible elements. The state's internal
3032/// value is modified using union or intersection operations.
3033template <typename BaseTy> struct SetState : public AbstractState {
3034 /// A wrapper around a set that has semantics for handling unions and
3035 /// intersections with a "universal" set that contains all elements.
3037 /// Creates a universal set with no concrete elements or an empty set.
3038 SetContents(bool Universal) : Universal(Universal) {}
3039
3040 /// Creates a non-universal set with concrete values.
3041 SetContents(const DenseSet<BaseTy> &Assumptions)
3042 : Universal(false), Set(Assumptions) {}
3043
3044 SetContents(bool Universal, const DenseSet<BaseTy> &Assumptions)
3045 : Universal(Universal), Set(Assumptions) {}
3046
3047 const DenseSet<BaseTy> &getSet() const { return Set; }
3048
3049 bool isUniversal() const { return Universal; }
3050
3051 bool empty() const { return Set.empty() && !Universal; }
3052
3053 /// Finds A := A ^ B where A or B could be the "Universal" set which
3054 /// contains every possible attribute. Returns true if changes were made.
3056 bool IsUniversal = Universal;
3057 unsigned Size = Set.size();
3058
3059 // A := A ^ U = A
3060 if (RHS.isUniversal())
3061 return false;
3062
3063 // A := U ^ B = B
3064 if (Universal)
3065 Set = RHS.getSet();
3066 else
3067 set_intersect(Set, RHS.getSet());
3068
3069 Universal &= RHS.isUniversal();
3070 return IsUniversal != Universal || Size != Set.size();
3071 }
3072
3073 /// Finds A := A u B where A or B could be the "Universal" set which
3074 /// contains every possible attribute. returns true if changes were made.
3075 bool getUnion(const SetContents &RHS) {
3076 bool IsUniversal = Universal;
3077 unsigned Size = Set.size();
3078
3079 // A := A u U = U = U u B
3080 if (!RHS.isUniversal() && !Universal)
3081 set_union(Set, RHS.getSet());
3082
3083 Universal |= RHS.isUniversal();
3084 return IsUniversal != Universal || Size != Set.size();
3085 }
3086
3087 private:
3088 /// Indicates if this set is "universal", containing every possible element.
3089 bool Universal;
3090
3091 /// The set of currently active assumptions.
3092 DenseSet<BaseTy> Set;
3093 };
3094
3095 SetState() : Known(false), Assumed(true), IsAtFixedpoint(false) {}
3096
3097 /// Initializes the known state with an initial set and initializes the
3098 /// assumed state as universal.
3100 : Known(Known), Assumed(true), IsAtFixedpoint(false) {}
3101
3102 /// See AbstractState::isValidState()
3103 bool isValidState() const override { return !Assumed.empty(); }
3104
3105 /// See AbstractState::isAtFixpoint()
3106 bool isAtFixpoint() const override { return IsAtFixedpoint; }
3107
3108 /// See AbstractState::indicateOptimisticFixpoint(...)
3110 IsAtFixedpoint = true;
3111 Known = Assumed;
3113 }
3114
3115 /// See AbstractState::indicatePessimisticFixpoint(...)
3117 IsAtFixedpoint = true;
3118 Assumed = Known;
3119 return ChangeStatus::CHANGED;
3120 }
3121
3122 /// Return the known state encoding.
3123 const SetContents &getKnown() const { return Known; }
3124
3125 /// Return the assumed state encoding.
3126 const SetContents &getAssumed() const { return Assumed; }
3127
3128 /// Returns if the set state contains the element.
3129 bool setContains(const BaseTy &Elem) const {
3130 return Assumed.getSet().contains(Elem) || Known.getSet().contains(Elem);
3131 }
3132
3133 /// Performs the set intersection between this set and \p RHS. Returns true if
3134 /// changes were made.
3136 bool IsUniversal = Assumed.isUniversal();
3137 unsigned SizeBefore = Assumed.getSet().size();
3138
3139 // Get intersection and make sure that the known set is still a proper
3140 // subset of the assumed set. A := K u (A ^ R).
3141 Assumed.getIntersection(RHS);
3142 Assumed.getUnion(Known);
3143
3144 return SizeBefore != Assumed.getSet().size() ||
3145 IsUniversal != Assumed.isUniversal();
3146 }
3147
3148 /// Performs the set union between this set and \p RHS. Returns true if
3149 /// changes were made.
3150 bool getUnion(const SetContents &RHS) { return Assumed.getUnion(RHS); }
3151
3152private:
3153 /// The set of values known for this state.
3154 SetContents Known;
3155
3156 /// The set of assumed values for this state.
3157 SetContents Assumed;
3158
3159 bool IsAtFixedpoint;
3160};
3161
3162/// Helper to tie a abstract state implementation to an abstract attribute.
3163template <typename StateTy, typename BaseType, class... Ts>
3164struct StateWrapper : public BaseType, public StateTy {
3165 /// Provide static access to the type of the state.
3167
3168 StateWrapper(const IRPosition &IRP, Ts... Args)
3169 : BaseType(IRP), StateTy(Args...) {}
3170
3171 /// See AbstractAttribute::getState(...).
3172 StateType &getState() override { return *this; }
3173
3174 /// See AbstractAttribute::getState(...).
3175 const StateType &getState() const override { return *this; }
3176};
3177
3178/// Helper class that provides common functionality to manifest IR attributes.
3179template <Attribute::AttrKind AK, typename BaseType, typename AAType>
3180struct IRAttribute : public BaseType {
3181 IRAttribute(const IRPosition &IRP) : BaseType(IRP) {}
3182
3183 /// Most boolean IRAttribute AAs don't do anything non-trivial
3184 /// in their initializers while non-boolean ones often do. Subclasses can
3185 /// change this.
3187
3188 /// Compile time access to the IR attribute kind.
3190
3191 /// Return true if the IR attribute(s) associated with this AA are implied for
3192 /// an undef value.
3193 static bool isImpliedByUndef() { return true; }
3194
3195 /// Return true if the IR attribute(s) associated with this AA are implied for
3196 /// an poison value.
3197 static bool isImpliedByPoison() { return true; }
3198
3199 static bool isImpliedByIR(Attributor &A, const IRPosition &IRP,
3200 Attribute::AttrKind ImpliedAttributeKind = AK,
3201 bool IgnoreSubsumingPositions = false) {
3202 if (AAType::isImpliedByUndef() && isa<UndefValue>(IRP.getAssociatedValue()))
3203 return true;
3204 if (AAType::isImpliedByPoison() &&
3205 isa<PoisonValue>(IRP.getAssociatedValue()))
3206 return true;
3207 return A.hasAttr(IRP, {ImpliedAttributeKind}, IgnoreSubsumingPositions,
3208 ImpliedAttributeKind);
3209 }
3210
3211 /// See AbstractAttribute::manifest(...).
3213 if (isa<UndefValue>(this->getIRPosition().getAssociatedValue()))
3215 SmallVector<Attribute, 4> DeducedAttrs;
3216 getDeducedAttributes(A, this->getAnchorValue().getContext(), DeducedAttrs);
3217 if (DeducedAttrs.empty())
3219 return A.manifestAttrs(this->getIRPosition(), DeducedAttrs);
3220 }
3221
3222 /// Return the kind that identifies the abstract attribute implementation.
3223 Attribute::AttrKind getAttrKind() const { return AK; }
3224
3225 /// Return the deduced attributes in \p Attrs.
3227 SmallVectorImpl<Attribute> &Attrs) const {
3228 Attrs.emplace_back(Attribute::get(Ctx, getAttrKind()));
3229 }
3230};
3231
3232/// Base struct for all "concrete attribute" deductions.
3233///
3234/// The abstract attribute is a minimal interface that allows the Attributor to
3235/// orchestrate the abstract/fixpoint analysis. The design allows to hide away
3236/// implementation choices made for the subclasses but also to structure their
3237/// implementation and simplify the use of other abstract attributes in-flight.
3238///
3239/// To allow easy creation of new attributes, most methods have default
3240/// implementations. The ones that do not are generally straight forward, except
3241/// `AbstractAttribute::updateImpl` which is the location of most reasoning
3242/// associated with the abstract attribute. The update is invoked by the
3243/// Attributor in case the situation used to justify the current optimistic
3244/// state might have changed. The Attributor determines this automatically
3245/// by monitoring the `Attributor::getAAFor` calls made by abstract attributes.
3246///
3247/// The `updateImpl` method should inspect the IR and other abstract attributes
3248/// in-flight to justify the best possible (=optimistic) state. The actual
3249/// implementation is, similar to the underlying abstract state encoding, not
3250/// exposed. In the most common case, the `updateImpl` will go through a list of
3251/// reasons why its optimistic state is valid given the current information. If
3252/// any combination of them holds and is sufficient to justify the current
3253/// optimistic state, the method shall return UNCHAGED. If not, the optimistic
3254/// state is adjusted to the situation and the method shall return CHANGED.
3255///
3256/// If the manifestation of the "concrete attribute" deduced by the subclass
3257/// differs from the "default" behavior, which is a (set of) LLVM-IR
3258/// attribute(s) for an argument, call site argument, function return value, or
3259/// function, the `AbstractAttribute::manifest` method should be overloaded.
3260///
3261/// NOTE: If the state obtained via getState() is INVALID, thus if
3262/// AbstractAttribute::getState().isValidState() returns false, no
3263/// information provided by the methods of this class should be used.
3264/// NOTE: The Attributor currently has certain limitations to what we can do.
3265/// As a general rule of thumb, "concrete" abstract attributes should *for
3266/// now* only perform "backward" information propagation. That means
3267/// optimistic information obtained through abstract attributes should
3268/// only be used at positions that precede the origin of the information
3269/// with regards to the program flow. More practically, information can
3270/// *now* be propagated from instructions to their enclosing function, but
3271/// *not* from call sites to the called function. The mechanisms to allow
3272/// both directions will be added in the future.
3273/// NOTE: The mechanics of adding a new "concrete" abstract attribute are
3274/// described in the file comment.
3277
3279
3280 /// Virtual destructor.
3281 virtual ~AbstractAttribute() = default;
3282
3283 /// Compile time access to the IR attribute kind.
3285
3286 /// This function is used to identify if an \p DGN is of type
3287 /// AbstractAttribute so that the dyn_cast and cast can use such information
3288 /// to cast an AADepGraphNode to an AbstractAttribute.
3289 ///
3290 /// We eagerly return true here because all AADepGraphNodes except for the
3291 /// Synthethis Node are of type AbstractAttribute
3292 static bool classof(const AADepGraphNode *DGN) { return true; }
3293
3294 /// Return false if this AA does anything non-trivial (hence not done by
3295 /// default) in its initializer.
3296 static bool hasTrivialInitializer() { return false; }
3297
3298 /// Return true if this AA requires a "callee" (or an associted function) for
3299 /// a call site positon. Default is optimistic to minimize AAs.
3300 static bool requiresCalleeForCallBase() { return false; }
3301
3302 /// Return true if this AA requires non-asm "callee" for a call site positon.
3303 static bool requiresNonAsmForCallBase() { return true; }
3304
3305 /// Return true if this AA requires all callees for an argument or function
3306 /// positon.
3307 static bool requiresCallersForArgOrFunction() { return false; }
3308
3309 /// Return false if an AA should not be created for \p IRP.
3311 return true;
3312 }
3313
3314 /// Return false if an AA should not be updated for \p IRP.
3316 Function *AssociatedFn = IRP.getAssociatedFunction();
3317 bool IsFnInterface = IRP.isFnInterfaceKind();
3318 assert((!IsFnInterface || AssociatedFn) &&
3319 "Function interface without a function?");
3320
3321 // TODO: Not all attributes require an exact definition. Find a way to
3322 // enable deduction for some but not all attributes in case the
3323 // definition might be changed at runtime, see also
3324 // http://lists.llvm.org/pipermail/llvm-dev/2018-February/121275.html.
3325 // TODO: We could always determine abstract attributes and if sufficient
3326 // information was found we could duplicate the functions that do not
3327 // have an exact definition.
3328 return !IsFnInterface || A.isFunctionIPOAmendable(*AssociatedFn);
3329 }
3330
3331 /// Initialize the state with the information in the Attributor \p A.
3332 ///
3333 /// This function is called by the Attributor once all abstract attributes
3334 /// have been identified. It can and shall be used for task like:
3335 /// - identify existing knowledge in the IR and use it for the "known state"
3336 /// - perform any work that is not going to change over time, e.g., determine
3337 /// a subset of the IR, or attributes in-flight, that have to be looked at
3338 /// in the `updateImpl` method.
3339 virtual void initialize(Attributor &A) {}
3340
3341 /// A query AA is always scheduled as long as we do updates because it does
3342 /// lazy computation that cannot be determined to be done from the outside.
3343 /// However, while query AAs will not be fixed if they do not have outstanding
3344 /// dependences, we will only schedule them like other AAs. If a query AA that
3345 /// received a new query it needs to request an update via
3346 /// `Attributor::requestUpdateForAA`.
3347 virtual bool isQueryAA() const { return false; }
3348
3349 /// Return the internal abstract state for inspection.
3350 virtual StateType &getState() = 0;
3351 virtual const StateType &getState() const = 0;
3352
3353 /// Return an IR position, see struct IRPosition.
3354 const IRPosition &getIRPosition() const { return *this; };
3355 IRPosition &getIRPosition() { return *this; };
3356
3357 /// Helper functions, for debug purposes only.
3358 ///{
3359 void print(raw_ostream &OS) const { print(nullptr, OS); }
3360 void print(Attributor *, raw_ostream &OS) const override;
3361 virtual void printWithDeps(raw_ostream &OS) const;
3362 void dump() const { this->print(dbgs()); }
3363
3364 /// This function should return the "summarized" assumed state as string.
3365 virtual const std::string getAsStr(Attributor *A) const = 0;
3366
3367 /// This function should return the name of the AbstractAttribute
3368 virtual const std::string getName() const = 0;
3369
3370 /// This function should return the address of the ID of the AbstractAttribute
3371 virtual const char *getIdAddr() const = 0;
3372 ///}
3373
3374 /// Allow the Attributor access to the protected methods.
3375 friend struct Attributor;
3376
3377protected:
3378 /// Hook for the Attributor to trigger an update of the internal state.
3379 ///
3380 /// If this attribute is already fixed, this method will return UNCHANGED,
3381 /// otherwise it delegates to `AbstractAttribute::updateImpl`.
3382 ///
3383 /// \Return CHANGED if the internal state changed, otherwise UNCHANGED.
3385
3386 /// Hook for the Attributor to trigger the manifestation of the information
3387 /// represented by the abstract attribute in the LLVM-IR.
3388 ///
3389 /// \Return CHANGED if the IR was altered, otherwise UNCHANGED.
3392 }
3393
3394 /// Hook to enable custom statistic tracking, called after manifest that
3395 /// resulted in a change if statistics are enabled.
3396 ///
3397 /// We require subclasses to provide an implementation so we remember to
3398 /// add statistics for them.
3399 virtual void trackStatistics() const = 0;
3400
3401 /// The actual update/transfer function which has to be implemented by the
3402 /// derived classes.
3403 ///
3404 /// If it is called, the environment has changed and we have to determine if
3405 /// the current information is still valid or adjust it otherwise.
3406 ///
3407 /// \Return CHANGED if the internal state changed, otherwise UNCHANGED.
3409};
3410
3411/// Forward declarations of output streams for debug purposes.
3412///
3413///{
3419template <typename base_ty, base_ty BestState, base_ty WorstState>
3423 return OS << "(" << S.getKnown() << "-" << S.getAssumed() << ")"
3424 << static_cast<const AbstractState &>(S);
3425}
3426raw_ostream &operator<<(raw_ostream &OS, const IntegerRangeState &State);
3427///}
3428
3429struct AttributorPass : public PassInfoMixin<AttributorPass> {
3431};
3432struct AttributorCGSCCPass : public PassInfoMixin<AttributorCGSCCPass> {
3435};
3436
3437/// A more lightweight version of the Attributor which only runs attribute
3438/// inference but no simplifications.
3439struct AttributorLightPass : public PassInfoMixin<AttributorLightPass> {
3441};
3442
3443/// A more lightweight version of the Attributor which only runs attribute
3444/// inference but no simplifications.
3446 : public PassInfoMixin<AttributorLightCGSCCPass> {
3449};
3450
3451/// Helper function to clamp a state \p S of type \p StateType with the
3452/// information in \p R and indicate/return if \p S did change (as-in update is
3453/// required to be run again).
3454template <typename StateType>
3455ChangeStatus clampStateAndIndicateChange(StateType &S, const StateType &R) {
3456 auto Assumed = S.getAssumed();
3457 S ^= R;
3458 return Assumed == S.getAssumed() ? ChangeStatus::UNCHANGED
3460}
3461
3462/// ----------------------------------------------------------------------------
3463/// Abstract Attribute Classes
3464/// ----------------------------------------------------------------------------
3465
3467 : public IRAttribute<Attribute::NoUnwind,
3468 StateWrapper<BooleanState, AbstractAttribute>,
3469 AANoUnwind> {
3471
3472 /// Returns true if nounwind is assumed.
3473 bool isAssumedNoUnwind() const { return getAssumed(); }
3474
3475 /// Returns true if nounwind is known.
3476 bool isKnownNoUnwind() const { return getKnown(); }
3477
3478 /// Create an abstract attribute view for the position \p IRP.
3480
3481 /// See AbstractAttribute::getName()
3482 const std::string getName() const override { return "AANoUnwind"; }
3483
3484 /// See AbstractAttribute::getIdAddr()
3485 const char *getIdAddr() const override { return &ID; }
3486
3487 /// This function should return true if the type of the \p AA is AANoUnwind
3488 static bool classof(const AbstractAttribute *AA) {
3489 return (AA->getIdAddr() == &ID);
3490 }
3491
3492 /// Unique ID (due to the unique address)
3493 static const char ID;
3494};
3495
3497 : public IRAttribute<Attribute::NoSync,
3498 StateWrapper<BooleanState, AbstractAttribute>,
3499 AANoSync> {
3501
3502 static bool isImpliedByIR(Attributor &A, const IRPosition &IRP,
3503 Attribute::AttrKind ImpliedAttributeKind,
3504 bool IgnoreSubsumingPositions = false) {
3505 // Note: This is also run for non-IPO amendable functions.
3506 assert(ImpliedAttributeKind == Attribute::NoSync);
3507 if (A.hasAttr(IRP, {Attribute::NoSync}, IgnoreSubsumingPositions,
3508 Attribute::NoSync))
3509 return true;
3510
3511 // Check for readonly + non-convergent.
3512 // TODO: We should be able to use hasAttr for Attributes, not only
3513 // AttrKinds.
3515 if (!F || F->isConvergent())
3516 return false;
3517
3519 A.getAttrs(IRP, {Attribute::Memory}, Attrs, IgnoreSubsumingPositions);
3520
3522 for (const Attribute &Attr : Attrs)
3523 ME &= Attr.getMemoryEffects();
3524
3525 if (!ME.onlyReadsMemory())
3526 return false;
3527
3528 A.manifestAttrs(IRP, Attribute::get(F->getContext(), Attribute::NoSync));
3529 return true;
3530 }
3531
3532 /// See AbstractAttribute::isValidIRPositionForInit
3534 if (!IRP.isFunctionScope() &&
3536 return false;
3537 return IRAttribute::isValidIRPositionForInit(A, IRP);
3538 }
3539
3540 /// Returns true if "nosync" is assumed.
3541 bool isAssumedNoSync() const { return getAssumed(); }
3542
3543 /// Returns true if "nosync" is known.
3544 bool isKnownNoSync() const { return getKnown(); }
3545
3546 /// Helper function used to determine whether an instruction is non-relaxed
3547 /// atomic. In other words, if an atomic instruction does not have unordered
3548 /// or monotonic ordering
3549 static bool isNonRelaxedAtomic(const Instruction *I);
3550
3551 /// Helper function specific for intrinsics which are potentially volatile.
3552 static bool isNoSyncIntrinsic(const Instruction *I);
3553
3554 /// Helper function to determine if \p CB is an aligned (GPU) barrier. Aligned
3555 /// barriers have to be executed by all threads. The flag \p ExecutedAligned
3556 /// indicates if the call is executed by all threads in a (thread) block in an
3557 /// aligned way. If that is the case, non-aligned barriers are effectively
3558 /// aligned barriers.
3559 static bool isAlignedBarrier(const CallBase &CB, bool ExecutedAligned);
3560
3561 /// Create an abstract attribute view for the position \p IRP.
3563
3564 /// See AbstractAttribute::getName()
3565 const std::string getName() const override { return "AANoSync"; }
3566
3567 /// See AbstractAttribute::getIdAddr()
3568 const char *getIdAddr() const override { return &ID; }
3569
3570 /// This function should return true if the type of the \p AA is AANoSync
3571 static bool classof(const AbstractAttribute *AA) {
3572 return (AA->getIdAddr() == &ID);
3573 }
3574
3575 /// Unique ID (due to the unique address)
3576 static const char ID;
3577};
3578
3579/// An abstract interface for all nonnull attributes.
3581 : public IRAttribute<Attribute::MustProgress,
3582 StateWrapper<BooleanState, AbstractAttribute>,
3583 AAMustProgress> {
3585
3586 static bool isImpliedByIR(Attributor &A, const IRPosition &IRP,
3587 Attribute::AttrKind ImpliedAttributeKind,
3588 bool IgnoreSubsumingPositions = false) {
3589 // Note: This is also run for non-IPO amendable functions.
3590 assert(ImpliedAttributeKind == Attribute::MustProgress);
3591 return A.hasAttr(IRP, {Attribute::MustProgress, Attribute::WillReturn},
3592 IgnoreSubsumingPositions, Attribute::MustProgress);
3593 }
3594
3595 /// Return true if we assume that the underlying value is nonnull.
3596 bool isAssumedMustProgress() const { return getAssumed(); }
3597
3598 /// Return true if we know that underlying value is nonnull.
3599 bool isKnownMustProgress() const { return getKnown(); }
3600
3601 /// Create an abstract attribute view for the position \p IRP.
3603 Attributor &A);
3604
3605 /// See AbstractAttribute::getName()
3606 const std::string getName() const override { return "AAMustProgress"; }
3607
3608 /// See AbstractAttribute::getIdAddr()
3609 const char *getIdAddr() const override { return &ID; }
3610
3611 /// This function should return true if the type of the \p AA is
3612 /// AAMustProgress
3613 static bool classof(const AbstractAttribute *AA) {
3614 return (AA->getIdAddr() == &ID);
3615 }
3616
3617 /// Unique ID (due to the unique address)
3618 static const char ID;
3619};
3620
3621/// An abstract interface for all nonnull attributes.
3623 : public IRAttribute<Attribute::NonNull,
3624 StateWrapper<BooleanState, AbstractAttribute>,
3625 AANonNull> {
3627
3628 /// See AbstractAttribute::hasTrivialInitializer.
3629 static bool hasTrivialInitializer() { return false; }
3630
3631 /// See IRAttribute::isImpliedByUndef.
3632 /// Undef is not necessarily nonnull as nonnull + noundef would cause poison.
3633 /// Poison implies nonnull though.
3634 static bool isImpliedByUndef() { return false; }
3635
3636 /// See AbstractAttribute::isValidIRPositionForInit
3639 return false;
3640 return IRAttribute::isValidIRPositionForInit(A, IRP);
3641 }
3642
3643 /// See AbstractAttribute::isImpliedByIR(...).
3644 static bool isImpliedByIR(Attributor &A, const IRPosition &IRP,
3645 Attribute::AttrKind ImpliedAttributeKind,
3646 bool IgnoreSubsumingPositions = false);
3647
3648 /// Return true if we assume that the underlying value is nonnull.
3649 bool isAssumedNonNull() const { return getAssumed(); }
3650
3651 /// Return true if we know that underlying value is nonnull.
3652 bool isKnownNonNull() const { return getKnown(); }
3653
3654 /// Create an abstract attribute view for the position \p IRP.
3656
3657 /// See AbstractAttribute::getName()
3658 const std::string getName() const override { return "AANonNull"; }
3659
3660 /// See AbstractAttribute::getIdAddr()
3661 const char *getIdAddr() const override { return &ID; }
3662
3663 /// This function should return true if the type of the \p AA is AANonNull
3664 static bool classof(const AbstractAttribute *AA) {
3665 return (AA->getIdAddr() == &ID);
3666 }
3667
3668 /// Unique ID (due to the unique address)
3669 static const char ID;
3670};
3671
3672/// An abstract attribute for norecurse.
3674 : public IRAttribute<Attribute::NoRecurse,
3675 StateWrapper<BooleanState, AbstractAttribute>,
3676 AANoRecurse> {
3678
3679 /// Return true if "norecurse" is assumed.
3680 bool isAssumedNoRecurse() const { return getAssumed(); }
3681
3682 /// Return true if "norecurse" is known.
3683 bool isKnownNoRecurse() const { return getKnown(); }
3684
3685 /// Create an abstract attribute view for the position \p IRP.
3687
3688 /// See AbstractAttribute::getName()
3689 const std::string getName() const override { return "AANoRecurse"; }
3690
3691 /// See AbstractAttribute::getIdAddr()
3692 const char *getIdAddr() const override { return &ID; }
3693
3694 /// This function should return true if the type of the \p AA is AANoRecurse
3695 static bool classof(const AbstractAttribute *AA) {
3696 return (AA->getIdAddr() == &ID);
3697 }
3698
3699 /// Unique ID (due to the unique address)
3700 static const char ID;
3701};
3702
3703/// An abstract attribute for willreturn.
3705 : public IRAttribute<Attribute::WillReturn,
3706 StateWrapper<BooleanState, AbstractAttribute>,
3707 AAWillReturn> {
3709
3710 static bool isImpliedByIR(Attributor &A, const IRPosition &IRP,
3711 Attribute::AttrKind ImpliedAttributeKind,
3712 bool IgnoreSubsumingPositions = false) {
3713 // Note: This is also run for non-IPO amendable functions.
3714 assert(ImpliedAttributeKind == Attribute::WillReturn);
3715 if (IRAttribute::isImpliedByIR(A, IRP, ImpliedAttributeKind,
3716 IgnoreSubsumingPositions))
3717 return true;
3719 return false;
3720 A.manifestAttrs(IRP, Attribute::get(IRP.getAnchorValue().getContext(),
3721 Attribute::WillReturn));
3722 return true;
3723 }
3724
3725 /// Check for `mustprogress` and `readonly` as they imply `willreturn`.
3727 const IRPosition &IRP) {
3728 // Check for `mustprogress` in the scope and the associated function which
3729 // might be different if this is a call site.
3730 if (!A.hasAttr(IRP, {Attribute::MustProgress}))
3731 return false;
3732
3734 A.getAttrs(IRP, {Attribute::Memory}, Attrs,
3735 /* IgnoreSubsumingPositions */ false);
3736
3738 for (const Attribute &Attr : Attrs)
3739 ME &= Attr.getMemoryEffects();
3740 return ME.onlyReadsMemory();
3741 }
3742
3743 /// Return true if "willreturn" is assumed.
3744 bool isAssumedWillReturn() const { return getAssumed(); }
3745
3746 /// Return true if "willreturn" is known.
3747 bool isKnownWillReturn() const { return getKnown(); }
3748
3749 /// Create an abstract attribute view for the position \p IRP.
3751
3752 /// See AbstractAttribute::getName()
3753 const std::string getName() const override { return "AAWillReturn"; }
3754
3755 /// See AbstractAttribute::getIdAddr()
3756 const char *getIdAddr() const override { return &ID; }
3757
3758 /// This function should return true if the type of the \p AA is AAWillReturn
3759 static bool classof(const AbstractAttribute *AA) {
3760 return (AA->getIdAddr() == &ID);
3761 }
3762
3763 /// Unique ID (due to the unique address)
3764 static const char ID;
3765};
3766
3767/// An abstract attribute for undefined behavior.
3769 : public StateWrapper<BooleanState, AbstractAttribute> {
3772
3773 /// Return true if "undefined behavior" is assumed.
3774 bool isAssumedToCauseUB() const { return getAssumed(); }
3775
3776 /// Return true if "undefined behavior" is assumed for a specific instruction.
3777 virtual bool isAssumedToCauseUB(Instruction *I) const = 0;
3778
3779 /// Return true if "undefined behavior" is known.
3780 bool isKnownToCauseUB() const { return getKnown(); }
3781
3782 /// Return true if "undefined behavior" is known for a specific instruction.
3783 virtual bool isKnownToCauseUB(Instruction *I) const = 0;
3784
3785 /// Create an abstract attribute view for the position \p IRP.
3787 Attributor &A);
3788
3789 /// See AbstractAttribute::getName()
3790 const std::string getName() const override { return "AAUndefinedBehavior"; }
3791
3792 /// See AbstractAttribute::getIdAddr()
3793 const char *getIdAddr() const override { return &ID; }
3794
3795 /// This function should return true if the type of the \p AA is
3796 /// AAUndefineBehavior
3797 static bool classof(const AbstractAttribute *AA) {
3798 return (AA->getIdAddr() == &ID);
3799 }
3800
3801 /// Unique ID (due to the unique address)
3802 static const char ID;
3803};
3804
3805/// An abstract interface to determine reachability of point A to B.
3807 : public StateWrapper<BooleanState, AbstractAttribute> {
3810
3811 /// Returns true if 'From' instruction is assumed to reach, 'To' instruction.
3812 /// Users should provide two positions they are interested in, and the class
3813 /// determines (and caches) reachability.
3815 Attributor &A, const Instruction &From, const Instruction &To,
3816 const AA::InstExclusionSetTy *ExclusionSet = nullptr) const = 0;
3817
3818 /// Create an abstract attribute view for the position \p IRP.
3820 Attributor &A);
3821
3822 /// See AbstractAttribute::getName()
3823 const std::string getName() const override { return "AAIntraFnReachability"; }
3824
3825 /// See AbstractAttribute::getIdAddr()
3826 const char *getIdAddr() const override { return &ID; }
3827
3828 /// This function should return true if the type of the \p AA is
3829 /// AAIntraFnReachability
3830 static bool classof(const AbstractAttribute *AA) {
3831 return (AA->getIdAddr() == &ID);
3832 }
3833
3834 /// Unique ID (due to the unique address)
3835 static const char ID;
3836};
3837
3838/// An abstract interface for all noalias attributes.
3840 : public IRAttribute<Attribute::NoAlias,
3841 StateWrapper<BooleanState, AbstractAttribute>,
3842 AANoAlias> {
3844
3845 /// See AbstractAttribute::isValidIRPositionForInit
3848 return false;
3849 return IRAttribute::isValidIRPositionForInit(A, IRP);
3850 }
3851
3852 /// See IRAttribute::isImpliedByIR
3853 static bool isImpliedByIR(Attributor &A, const IRPosition &IRP,
3854 Attribute::AttrKind ImpliedAttributeKind,
3855 bool IgnoreSubsumingPositions = false);
3856
3857 /// See AbstractAttribute::requiresCallersForArgOrFunction
3858 static bool requiresCallersForArgOrFunction() { return true; }
3859
3860 /// Return true if we assume that the underlying value is alias.
3861 bool isAssumedNoAlias() const { return getAssumed(); }
3862
3863 /// Return true if we know that underlying value is noalias.
3864 bool isKnownNoAlias() const { return getKnown(); }
3865
3866 /// Create an abstract attribute view for the position \p IRP.
3868
3869 /// See AbstractAttribute::getName()
3870 const std::string getName() const override { return "AANoAlias"; }
3871
3872 /// See AbstractAttribute::getIdAddr()
3873 const char *getIdAddr() const override { return &ID; }
3874
3875 /// This function should return true if the type of the \p AA is AANoAlias
3876 static bool classof(const AbstractAttribute *AA) {
3877 return (AA->getIdAddr() == &ID);
3878 }
3879
3880 /// Unique ID (due to the unique address)
3881 static const char ID;
3882};
3883
3884/// An AbstractAttribute for nofree.
3886 : public IRAttribute<Attribute::NoFree,
3887 StateWrapper<BooleanState, AbstractAttribute>,
3888 AANoFree> {
3890
3891 /// See IRAttribute::isImpliedByIR
3892 static bool isImpliedByIR(Attributor &A, const IRPosition &IRP,
3893 Attribute::AttrKind ImpliedAttributeKind,
3894 bool IgnoreSubsumingPositions = false) {
3895 // Note: This is also run for non-IPO amendable functions.
3896 assert(ImpliedAttributeKind == Attribute::NoFree);
3897 return A.hasAttr(
3898 IRP, {Attribute::ReadNone, Attribute::ReadOnly, Attribute::NoFree},
3899 IgnoreSubsumingPositions, Attribute::NoFree);
3900 }
3901
3902 /// See AbstractAttribute::isValidIRPositionForInit
3904 if (!IRP.isFunctionScope() &&
3906 return false;
3907 return IRAttribute::isValidIRPositionForInit(A, IRP);
3908 }
3909
3910 /// Return true if "nofree" is assumed.
3911 bool isAssumedNoFree() const { return getAssumed(); }
3912
3913 /// Return true if "nofree" is known.
3914 bool isKnownNoFree() const { return getKnown(); }
3915
3916 /// Create an abstract attribute view for the position \p IRP.
3918
3919 /// See AbstractAttribute::getName()
3920 const std::string getName() const override { return "AANoFree"; }
3921
3922 /// See AbstractAttribute::getIdAddr()
3923 const char *getIdAddr() const override { return &ID; }
3924
3925 /// This function should return true if the type of the \p AA is AANoFree
3926 static bool classof(const AbstractAttribute *AA) {
3927 return (AA->getIdAddr() == &ID);
3928 }
3929
3930 /// Unique ID (due to the unique address)
3931 static const char ID;
3932};
3933
3934/// An AbstractAttribute for noreturn.
3936 : public IRAttribute<Attribute::NoReturn,
3937 StateWrapper<BooleanState, AbstractAttribute>,
3938 AANoReturn> {
3940
3941 /// Return true if the underlying object is assumed to never return.
3942 bool isAssumedNoReturn() const { return getAssumed(); }
3943
3944 /// Return true if the underlying object is known to never return.
3945 bool isKnownNoReturn() const { return getKnown(); }
3946
3947 /// Create an abstract attribute view for the position \p IRP.
3949
3950 /// See AbstractAttribute::getName()
3951 const std::string getName() const override { return "AANoReturn"; }
3952
3953 /// See AbstractAttribute::getIdAddr()
3954 const char *getIdAddr() const override { return &ID; }
3955
3956 /// This function should return true if the type of the \p AA is AANoReturn
3957 static bool classof(const AbstractAttribute *AA) {
3958 return (AA->getIdAddr() == &ID);
3959 }
3960
3961 /// Unique ID (due to the unique address)
3962 static const char ID;
3963};
3964
3965/// An abstract interface for liveness abstract attribute.
3967 : public StateWrapper<BitIntegerState<uint8_t, 3, 0>, AbstractAttribute> {
3969 AAIsDead(const IRPosition &IRP, Attributor &A) : Base(IRP) {}
3970
3971 /// See AbstractAttribute::isValidIRPositionForInit
3974 return isa<Function>(IRP.getAnchorValue()) &&
3975 !cast<Function>(IRP.getAnchorValue()).isDeclaration();
3976 return true;
3977 }
3978
3979 /// State encoding bits. A set bit in the state means the property holds.
3980 enum {
3983
3985 };
3986 static_assert(IS_DEAD == getBestState(), "Unexpected BEST_STATE value");
3987
3988protected:
3989 /// The query functions are protected such that other attributes need to go
3990 /// through the Attributor interfaces: `Attributor::isAssumedDead(...)`
3991
3992 /// Returns true if the underlying value is assumed dead.
3993 virtual bool isAssumedDead() const = 0;
3994
3995 /// Returns true if the underlying value is known dead.
3996 virtual bool isKnownDead() const = 0;
3997
3998 /// Returns true if \p BB is known dead.
3999 virtual bool isKnownDead(const BasicBlock *BB) const = 0;
4000
4001 /// Returns true if \p I is assumed dead.
4002 virtual bool isAssumedDead(const Instruction *I) const = 0;
4003
4004 /// Returns true if \p I is known dead.
4005 virtual bool isKnownDead(const Instruction *I) const = 0;
4006
4007 /// Return true if the underlying value is a store that is known to be
4008 /// removable. This is different from dead stores as the removable store
4009 /// can have an effect on live values, especially loads, but that effect
4010 /// is propagated which allows us to remove the store in turn.
4011 virtual bool isRemovableStore() const { return false; }
4012
4013 /// This method is used to check if at least one instruction in a collection
4014 /// of instructions is live.
4015 template <typename T> bool isLiveInstSet(T begin, T end) const {
4016 for (const auto &I : llvm::make_range(begin, end)) {
4017 assert(I->getFunction() == getIRPosition().getAssociatedFunction() &&
4018 "Instruction must be in the same anchor scope function.");
4019
4020 if (!isAssumedDead(I))
4021 return true;
4022 }
4023
4024 return false;
4025 }
4026
4027public:
4028 /// Create an abstract attribute view for the position \p IRP.
4030
4031 /// Determine if \p F might catch asynchronous exceptions.
4033 return F.hasPersonalityFn() && !canSimplifyInvokeNoUnwind(&F);
4034 }
4035
4036 /// Returns true if \p BB is assumed dead.
4037 virtual bool isAssumedDead(const BasicBlock *BB) const = 0;
4038
4039 /// Return if the edge from \p From BB to \p To BB is assumed dead.
4040 /// This is specifically useful in AAReachability.
4041 virtual bool isEdgeDead(const BasicBlock *From, const BasicBlock *To) const {
4042 return false;
4043 }
4044
4045 /// See AbstractAttribute::getName()
4046 const std::string getName() const override { return "AAIsDead"; }
4047
4048 /// See AbstractAttribute::getIdAddr()
4049 const char *getIdAddr() const override { return &ID; }
4050
4051 /// This function should return true if the type of the \p AA is AAIsDead
4052 static bool classof(const AbstractAttribute *AA) {
4053 return (AA->getIdAddr() == &ID);
4054 }
4055
4056 /// Unique ID (due to the unique address)
4057 static const char ID;
4058
4059 friend struct Attributor;
4060};
4061
4062/// State for dereferenceable attribute
4064
4065 static DerefState getBestState() { return DerefState(); }
4066 static DerefState getBestState(const DerefState &) { return getBestState(); }
4067
4068 /// Return the worst possible representable state.
4070 DerefState DS;
4071 DS.indicatePessimisticFixpoint();
4072 return DS;
4073 }
4075 return getWorstState();
4076 }
4077
4078 /// State representing for dereferenceable bytes.
4080
4081 /// Map representing for accessed memory offsets and sizes.
4082 /// A key is Offset and a value is size.
4083 /// If there is a load/store instruction something like,
4084 /// p[offset] = v;
4085 /// (offset, sizeof(v)) will be inserted to this map.
4086 /// std::map is used because we want to iterate keys in ascending order.
4087 std::map<int64_t, uint64_t> AccessedBytesMap;
4088
4089 /// Helper function to calculate dereferenceable bytes from current known
4090 /// bytes and accessed bytes.
4091 ///
4092 /// int f(int *A){
4093 /// *A = 0;
4094 /// *(A+2) = 2;
4095 /// *(A+1) = 1;
4096 /// *(A+10) = 10;
4097 /// }
4098 /// ```
4099 /// In that case, AccessedBytesMap is `{0:4, 4:4, 8:4, 40:4}`.
4100 /// AccessedBytesMap is std::map so it is iterated in accending order on
4101 /// key(Offset). So KnownBytes will be updated like this:
4102 ///
4103 /// |Access | KnownBytes
4104 /// |(0, 4)| 0 -> 4
4105 /// |(4, 4)| 4 -> 8
4106 /// |(8, 4)| 8 -> 12
4107 /// |(40, 4) | 12 (break)
4108 void computeKnownDerefBytesFromAccessedMap() {
4109 int64_t KnownBytes = DerefBytesState.getKnown();
4110 for (auto &Access : AccessedBytesMap) {
4111 if (KnownBytes < Access.first)
4112 break;
4113 KnownBytes = std::max(KnownBytes, Access.first + (int64_t)Access.second);
4114 }
4115
4117 }
4118
4119 /// State representing that whether the value is globaly dereferenceable.
4120 BooleanState GlobalState;
4121
4122 /// See AbstractState::isValidState()
4123 bool isValidState() const override { return DerefBytesState.isValidState(); }
4124
4125 /// See AbstractState::isAtFixpoint()
4126 bool isAtFixpoint() const override {
4127 return !isValidState() ||
4128 (DerefBytesState.isAtFixpoint() && GlobalState.isAtFixpoint());
4129 }
4130
4131 /// See AbstractState::indicateOptimisticFixpoint(...)
4134 GlobalState.indicateOptimisticFixpoint();
4136 }
4137
4138 /// See AbstractState::indicatePessimisticFixpoint(...)
4141 GlobalState.indicatePessimisticFixpoint();
4142 return ChangeStatus::CHANGED;
4143 }
4144
4145 /// Update known dereferenceable bytes.
4146 void takeKnownDerefBytesMaximum(uint64_t Bytes) {
4148
4149 // Known bytes might increase.
4150 computeKnownDerefBytesFromAccessedMap();
4151 }
4152
4153 /// Update assumed dereferenceable bytes.
4154 void takeAssumedDerefBytesMinimum(uint64_t Bytes) {
4156 }
4157
4158 /// Add accessed bytes to the map.
4159 void addAccessedBytes(int64_t Offset, uint64_t Size) {
4160 uint64_t &AccessedBytes = AccessedBytesMap[Offset];
4161 AccessedBytes = std::max(AccessedBytes, Size);
4162
4163 // Known bytes might increase.
4164 computeKnownDerefBytesFromAccessedMap();
4165 }
4166
4167 /// Equality for DerefState.
4168 bool operator==(const DerefState &R) const {
4169 return this->DerefBytesState == R.DerefBytesState &&
4170 this->GlobalState == R.GlobalState;
4171 }
4172
4173 /// Inequality for DerefState.
4174 bool operator!=(const DerefState &R) const { return !(*this == R); }
4175
4176 /// See IntegerStateBase::operator^=
4177 DerefState operator^=(const DerefState &R) {
4178 DerefBytesState ^= R.DerefBytesState;
4179 GlobalState ^= R.GlobalState;
4180 return *this;
4181 }
4182
4183 /// See IntegerStateBase::operator+=
4184 DerefState operator+=(const DerefState &R) {
4185 DerefBytesState += R.DerefBytesState;
4186 GlobalState += R.GlobalState;
4187 return *this;
4188 }
4189
4190 /// See IntegerStateBase::operator&=
4191 DerefState operator&=(const DerefState &R) {
4192 DerefBytesState &= R.DerefBytesState;
4193 GlobalState &= R.GlobalState;
4194 return *this;
4195 }
4196
4197 /// See IntegerStateBase::operator|=
4198 DerefState operator|=(const DerefState &R) {
4199 DerefBytesState |= R.DerefBytesState;
4200 GlobalState |= R.GlobalState;
4201 return *this;
4202 }
4203};
4204
4205/// An abstract interface for all dereferenceable attribute.
4207 : public IRAttribute<Attribute::Dereferenceable,
4208 StateWrapper<DerefState, AbstractAttribute>,
4209 AADereferenceable> {
4211
4212 /// See AbstractAttribute::isValidIRPositionForInit
4215 return false;
4216 return IRAttribute::isValidIRPositionForInit(A, IRP);
4217 }
4218
4219 /// Return true if we assume that underlying value is
4220 /// dereferenceable(_or_null) globally.
4221 bool isAssumedGlobal() const { return GlobalState.getAssumed(); }
4222
4223 /// Return true if we know that underlying value is
4224 /// dereferenceable(_or_null) globally.
4225 bool isKnownGlobal() const { return GlobalState.getKnown(); }
4226
4227 /// Return assumed dereferenceable bytes.
4229 return DerefBytesState.getAssumed();
4230 }
4231
4232 /// Return known dereferenceable bytes.
4234 return DerefBytesState.getKnown();
4235 }
4236
4237 /// Create an abstract attribute view for the position \p IRP.
4239 Attributor &A);
4240
4241 /// See AbstractAttribute::getName()
4242 const std::string getName() const override { return "AADereferenceable"; }
4243
4244 /// See AbstractAttribute::getIdAddr()
4245 const char *getIdAddr() const override { return &ID; }
4246
4247 /// This function should return true if the type of the \p AA is
4248 /// AADereferenceable
4249 static bool classof(const AbstractAttribute *AA) {
4250 return (AA->getIdAddr() == &ID);
4251 }
4252
4253 /// Unique ID (due to the unique address)
4254 static const char ID;
4255};
4256
4259/// An abstract interface for all align attributes.
4261 : public IRAttribute<Attribute::Alignment,
4262 StateWrapper<AAAlignmentStateType, AbstractAttribute>,
4263 AAAlign> {
4265
4266 /// See AbstractAttribute::isValidIRPositionForInit
4269 return false;
4270 return IRAttribute::isValidIRPositionForInit(A, IRP);
4271 }
4272
4273 /// Return assumed alignment.
4274 Align getAssumedAlign() const { return Align(getAssumed()); }
4275
4276 /// Return known alignment.
4277 Align getKnownAlign() const { return Align(getKnown()); }
4278
4279 /// See AbstractAttribute::getName()
4280 const std::string getName() const override { return "AAAlign"; }
4281
4282 /// See AbstractAttribute::getIdAddr()
4283 const char *getIdAddr() const override { return &ID; }
4284
4285 /// This function should return true if the type of the \p AA is AAAlign
4286 static bool classof(const AbstractAttribute *AA) {
4287 return (AA->getIdAddr() == &ID);
4288 }
4289
4290 /// Create an abstract attribute view for the position \p IRP.
4292
4293 /// Unique ID (due to the unique address)
4294 static const char ID;
4295};
4296
4297/// An abstract interface to track if a value leaves it's defining function
4298/// instance.
4299/// TODO: We should make it a ternary AA tracking uniqueness, and uniqueness
4300/// wrt. the Attributor analysis separately.
4301struct AAInstanceInfo : public StateWrapper<BooleanState, AbstractAttribute> {
4304
4305 /// Return true if we know that the underlying value is unique in its scope
4306 /// wrt. the Attributor analysis. That means it might not be unique but we can
4307 /// still use pointer equality without risking to represent two instances with
4308 /// one `llvm::Value`.
4309 bool isKnownUniqueForAnalysis() const { return isKnown(); }
4310
4311 /// Return true if we assume that the underlying value is unique in its scope
4312 /// wrt. the Attributor analysis. That means it might not be unique but we can
4313 /// still use pointer equality without risking to represent two instances with
4314 /// one `llvm::Value`.
4315 bool isAssumedUniqueForAnalysis() const { return isAssumed(); }
4316
4317 /// Create an abstract attribute view for the position \p IRP.
4319 Attributor &A);
4320
4321 /// See AbstractAttribute::getName()
4322 const std::string getName() const override { return "AAInstanceInfo"; }
4323
4324 /// See AbstractAttribute::getIdAddr()
4325 const char *getIdAddr() const override { return &ID; }
4326
4327 /// This function should return true if the type of the \p AA is
4328 /// AAInstanceInfo
4329 static bool classof(const AbstractAttribute *AA) {
4330 return (AA->getIdAddr() == &ID);
4331 }
4332
4333 /// Unique ID (due to the unique address)
4334 static const char ID;
4335};
4336
4337/// An abstract interface for all nocapture attributes.
4339 : public IRAttribute<
4340 Attribute::NoCapture,
4341 StateWrapper<BitIntegerState<uint16_t, 7, 0>, AbstractAttribute>,
4342 AANoCapture> {
4344
4345 /// See IRAttribute::isImpliedByIR
4346 static bool isImpliedByIR(Attributor &A, const IRPosition &IRP,
4347 Attribute::AttrKind ImpliedAttributeKind,
4348 bool IgnoreSubsumingPositions = false);
4349
4350 /// Update \p State according to the capture capabilities of \p F for position
4351 /// \p IRP.
4352 static void determineFunctionCaptureCapabilities(const IRPosition &IRP,
4353 const Function &F,
4354 BitIntegerState &State);
4355
4356 /// See AbstractAttribute::isValidIRPositionForInit
4359 return false;
4360 return IRAttribute::isValidIRPositionForInit(A, IRP);
4361 }
4362
4363 /// State encoding bits. A set bit in the state means the property holds.
4364 /// NO_CAPTURE is the best possible state, 0 the worst possible state.
4365 enum {
4369
4370 /// If we do not capture the value in memory or through integers we can only
4371 /// communicate it back as a derived pointer.
4373
4374 /// If we do not capture the value in memory, through integers, or as a
4375 /// derived pointer we know it is not captured.
4376 NO_CAPTURE =
4378 };
4379
4380 /// Return true if we know that the underlying value is not captured in its
4381 /// respective scope.
4382 bool isKnownNoCapture() const { return isKnown(NO_CAPTURE); }
4383
4384 /// Return true if we assume that the underlying value is not captured in its
4385 /// respective scope.
4386 bool isAssumedNoCapture() const { return isAssumed(NO_CAPTURE); }
4387
4388 /// Return true if we know that the underlying value is not captured in its
4389 /// respective scope but we allow it to escape through a "return".
4392 }
4393
4394 /// Return true if we assume that the underlying value is not captured in its
4395 /// respective scope but we allow it to escape through a "return".
4398 }
4399
4400 /// Create an abstract attribute view for the position \p IRP.
4402
4403 /// See AbstractAttribute::getName()
4404 const std::string getName() const override { return "AANoCapture"; }
4405
4406 /// See AbstractAttribute::getIdAddr()
4407 const char *getIdAddr() const override { return &ID; }
4408
4409 /// This function should return true if the type of the \p AA is AANoCapture
4410 static bool classof(const AbstractAttribute *AA) {
4411 return (AA->getIdAddr() == &ID);
4412 }
4413
4414 /// Unique ID (due to the unique address)
4415 static const char ID;
4416};
4417
4419
4421
4423 return ValueSimplifyStateType(Ty);
4424 }
4426 return getBestState(VS.Ty);
4427 }
4428
4429 /// Return the worst possible representable state.
4432 DS.indicatePessimisticFixpoint();
4433 return DS;
4434 }
4437 return getWorstState(VS.Ty);
4438 }
4439
4440 /// See AbstractState::isValidState(...)
4441 bool isValidState() const override { return BS.isValidState(); }
4442
4443 /// See AbstractState::isAtFixpoint(...)
4444 bool isAtFixpoint() const override { return BS.isAtFixpoint(); }
4445
4446 /// Return the assumed state encoding.
4448 const ValueSimplifyStateType &getAssumed() const { return *this; }
4449
4450 /// See AbstractState::indicatePessimisticFixpoint(...)
4453 }
4454
4455 /// See AbstractState::indicateOptimisticFixpoint(...)
4458 }
4459
4460 /// "Clamp" this state with \p PVS.
4462 BS ^= VS.BS;
4463 unionAssumed(VS.SimplifiedAssociatedValue);
4464 return *this;
4465 }
4466
4468 if (isValidState() != RHS.isValidState())
4469 return false;
4470 if (!isValidState() && !RHS.isValidState())
4471 return true;
4472 return SimplifiedAssociatedValue == RHS.SimplifiedAssociatedValue;
4473 }
4474
4475protected:
4476 /// The type of the original value.
4478
4479 /// Merge \p Other into the currently assumed simplified value
4480 bool unionAssumed(std::optional<Value *> Other);
4481
4482 /// Helper to track validity and fixpoint
4484
4485 /// An assumed simplified value. Initially, it is set to std::nullopt, which
4486 /// means that the value is not clear under current assumption. If in the
4487 /// pessimistic state, getAssumedSimplifiedValue doesn't return this value but
4488 /// returns orignal associated value.
4489 std::optional<Value *> SimplifiedAssociatedValue;
4490};
4491
4492/// An abstract interface for value simplify abstract attribute.
4494 : public StateWrapper<ValueSimplifyStateType, AbstractAttribute, Type *> {
4497 : Base(IRP, IRP.getAssociatedType()) {}
4498
4499 /// Create an abstract attribute view for the position \p IRP.
4501 Attributor &A);
4502
4503 /// See AbstractAttribute::getName()
4504 const std::string getName() const override { return "AAValueSimplify"; }
4505
4506 /// See AbstractAttribute::getIdAddr()
4507 const char *getIdAddr() const override { return &ID; }
4508
4509 /// This function should return true if the type of the \p AA is
4510 /// AAValueSimplify
4511 static bool classof(const AbstractAttribute *AA) {
4512 return (AA->getIdAddr() == &ID);
4513 }
4514
4515 /// Unique ID (due to the unique address)
4516 static const char ID;
4517
4518private:
4519 /// Return an assumed simplified value if a single candidate is found. If
4520 /// there cannot be one, return original value. If it is not clear yet, return
4521 /// std::nullopt.
4522 ///
4523 /// Use `Attributor::getAssumedSimplified` for value simplification.
4524 virtual std::optional<Value *>
4525 getAssumedSimplifiedValue(Attributor &A) const = 0;
4526
4527 friend struct Attributor;
4528};
4529
4530struct AAHeapToStack : public StateWrapper<BooleanState, AbstractAttribute> {
4532 AAHeapToStack(const IRPosition &IRP, Attributor &A) : Base(IRP) {}
4533
4534 /// Returns true if HeapToStack conversion is assumed to be possible.
4535 virtual bool isAssumedHeapToStack(const CallBase &CB) const = 0;
4536
4537 /// Returns true if HeapToStack conversion is assumed and the CB is a
4538 /// callsite to a free operation to be removed.
4539 virtual bool isAssumedHeapToStackRemovedFree(CallBase &CB) const = 0;
4540
4541 /// Create an abstract attribute view for the position \p IRP.
4543
4544 /// See AbstractAttribute::getName()
4545 const std::string getName() const override { return "AAHeapToStack"; }
4546
4547 /// See AbstractAttribute::getIdAddr()
4548 const char *getIdAddr() const override { return &ID; }
4549
4550 /// This function should return true if the type of the \p AA is AAHeapToStack
4551 static bool classof(const AbstractAttribute *AA) {
4552 return (AA->getIdAddr() == &ID);
4553 }
4554
4555 /// Unique ID (due to the unique address)
4556 static const char ID;
4557};
4558
4559/// An abstract interface for privatizability.
4560///
4561/// A pointer is privatizable if it can be replaced by a new, private one.
4562/// Privatizing pointer reduces the use count, interaction between unrelated
4563/// code parts.
4564///
4565/// In order for a pointer to be privatizable its value cannot be observed
4566/// (=nocapture), it is (for now) not written (=readonly & noalias), we know
4567/// what values are necessary to make the private copy look like the original
4568/// one, and the values we need can be loaded (=dereferenceable).
4570 : public StateWrapper<BooleanState, AbstractAttribute> {
4573
4574 /// See AbstractAttribute::isValidIRPositionForInit
4577 return false;
4579 }
4580
4581 /// Returns true if pointer privatization is assumed to be possible.
4582 bool isAssumedPrivatizablePtr() const { return getAssumed(); }
4583
4584 /// Returns true if pointer privatization is known to be possible.
4585 bool isKnownPrivatizablePtr() const { return getKnown(); }
4586
4587 /// See AbstractAttribute::requiresCallersForArgOrFunction
4588 static bool requiresCallersForArgOrFunction() { return true; }
4589
4590 /// Return the type we can choose for a private copy of the underlying
4591 /// value. std::nullopt means it is not clear yet, nullptr means there is
4592 /// none.
4593 virtual std::optional<Type *> getPrivatizableType() const = 0;
4594
4595 /// Create an abstract attribute view for the position \p IRP.
4597 Attributor &A);
4598
4599 /// See AbstractAttribute::getName()
4600 const std::string getName() const override { return "AAPrivatizablePtr"; }
4601
4602 /// See AbstractAttribute::getIdAddr()
4603 const char *getIdAddr() const override { return &ID; }
4604
4605 /// This function should return true if the type of the \p AA is
4606 /// AAPricatizablePtr
4607 static bool classof(const AbstractAttribute *AA) {
4608 return (AA->getIdAddr() == &ID);
4609 }
4610
4611 /// Unique ID (due to the unique address)
4612 static const char ID;
4613};
4614
4615/// An abstract interface for memory access kind related attributes
4616/// (readnone/readonly/writeonly).
4618 : public IRAttribute<
4619 Attribute::None,
4620 StateWrapper<BitIntegerState<uint8_t, 3>, AbstractAttribute>,
4621 AAMemoryBehavior> {
4623
4624 /// See AbstractAttribute::hasTrivialInitializer.
4625 static bool hasTrivialInitializer() { return false; }
4626
4627 /// See AbstractAttribute::isValidIRPositionForInit
4629 if (!IRP.isFunctionScope() &&
4631 return false;
4632 return IRAttribute::isValidIRPositionForInit(A, IRP);
4633 }
4634
4635 /// State encoding bits. A set bit in the state means the property holds.
4636 /// BEST_STATE is the best possible state, 0 the worst possible state.
4637 enum {
4638 NO_READS = 1 << 0,
4639 NO_WRITES = 1 << 1,
4641
4643 };
4644 static_assert(BEST_STATE == getBestState(), "Unexpected BEST_STATE value");
4645
4646 /// Return true if we know that the underlying value is not read or accessed
4647 /// in its respective scope.
4648 bool isKnownReadNone() const { return isKnown(NO_ACCESSES); }
4649
4650 /// Return true if we assume that the underlying value is not read or accessed
4651 /// in its respective scope.
4652 bool isAssumedReadNone() const { return isAssumed(NO_ACCESSES); }
4653
4654 /// Return true if we know that the underlying value is not accessed
4655 /// (=written) in its respective scope.
4656 bool isKnownReadOnly() const { return isKnown(NO_WRITES); }
4657
4658 /// Return true if we assume that the underlying value is not accessed
4659 /// (=written) in its respective scope.
4660 bool isAssumedReadOnly() const { return isAssumed(NO_WRITES); }
4661
4662 /// Return true if we know that the underlying value is not read in its
4663 /// respective scope.
4664 bool isKnownWriteOnly() const { return isKnown(NO_READS); }
4665
4666 /// Return true if we assume that the underlying value is not read in its
4667 /// respective scope.
4668 bool isAssumedWriteOnly() const { return isAssumed(NO_READS); }
4669
4670 /// Create an abstract attribute view for the position \p IRP.
4672 Attributor &A);
4673
4674 /// See AbstractAttribute::getName()
4675 const std::string getName() const override { return "AAMemoryBehavior"; }
4676
4677 /// See AbstractAttribute::getIdAddr()
4678 const char *getIdAddr() const override { return &ID; }
4679
4680 /// This function should return true if the type of the \p AA is
4681 /// AAMemoryBehavior
4682 static bool classof(const AbstractAttribute *AA) {
4683 return (AA->getIdAddr() == &ID);
4684 }
4685
4686 /// Unique ID (due to the unique address)
4687 static const char ID;
4688};
4689
4690/// An abstract interface for all memory location attributes
4691/// (readnone/argmemonly/inaccessiblememonly/inaccessibleorargmemonly).
4693 : public IRAttribute<
4694 Attribute::None,
4695 StateWrapper<BitIntegerState<uint32_t, 511>, AbstractAttribute>,
4696 AAMemoryLocation> {
4698
4700
4701 /// See AbstractAttribute::requiresCalleeForCallBase.
4702 static bool requiresCalleeForCallBase() { return true; }
4703
4704 /// See AbstractAttribute::hasTrivialInitializer.
4705 static bool hasTrivialInitializer() { return false; }
4706
4707 /// See AbstractAttribute::isValidIRPositionForInit
4709 if (!IRP.isFunctionScope() &&
4711 return false;
4712 return IRAttribute::isValidIRPositionForInit(A, IRP);
4713 }
4714
4715 /// Encoding of different locations that could be accessed by a memory
4716 /// access.
4717 enum {
4731
4732 // Helper bit to track if we gave up or not.
4734
4736 };
4737 static_assert(BEST_STATE == getBestState(), "Unexpected BEST_STATE value");
4738
4739 /// Return true if we know that the associated functions has no observable
4740 /// accesses.
4741 bool isKnownReadNone() const { return isKnown(NO_LOCATIONS); }
4742
4743 /// Return true if we assume that the associated functions has no observable
4744 /// accesses.
4745 bool isAssumedReadNone() const {
4747 }
4748
4749 /// Return true if we know that the associated functions has at most
4750 /// local/stack accesses.
4751 bool isKnowStackOnly() const {
4752 return isKnown(inverseLocation(NO_LOCAL_MEM, true, true));
4753 }
4754
4755 /// Return true if we assume that the associated functions has at most
4756 /// local/stack accesses.
4757 bool isAssumedStackOnly() const {
4758 return isAssumed(inverseLocation(NO_LOCAL_MEM, true, true));
4759 }
4760
4761 /// Return true if we know that the underlying value will only access
4762 /// inaccesible memory only (see Attribute::InaccessibleMemOnly).
4764 return isKnown(inverseLocation(NO_INACCESSIBLE_MEM, true, true));
4765 }
4766
4767 /// Return true if we assume that the underlying value will only access
4768 /// inaccesible memory only (see Attribute::InaccessibleMemOnly).
4770 return isAssumed(inverseLocation(NO_INACCESSIBLE_MEM, true, true));
4771 }
4772
4773 /// Return true if we know that the underlying value will only access
4774 /// argument pointees (see Attribute::ArgMemOnly).
4775 bool isKnownArgMemOnly() const {
4776 return isKnown(inverseLocation(NO_ARGUMENT_MEM, true, true));
4777 }
4778
4779 /// Return true if we assume that the underlying value will only access
4780 /// argument pointees (see Attribute::ArgMemOnly).
4781 bool isAssumedArgMemOnly() const {
4782 return isAssumed(inverseLocation(NO_ARGUMENT_MEM, true, true));
4783 }
4784
4785 /// Return true if we know that the underlying value will only access
4786 /// inaccesible memory or argument pointees (see
4787 /// Attribute::InaccessibleOrArgMemOnly).
4789 return isKnown(
4791 }
4792
4793 /// Return true if we assume that the underlying value will only access
4794 /// inaccesible memory or argument pointees (see
4795 /// Attribute::InaccessibleOrArgMemOnly).
4797 return isAssumed(
4799 }
4800
4801 /// Return true if the underlying value may access memory through arguement
4802 /// pointers of the associated function, if any.
4803 bool mayAccessArgMem() const { return !isAssumed(NO_ARGUMENT_MEM); }
4804
4805 /// Return true if only the memory locations specififed by \p MLK are assumed
4806 /// to be accessed by the associated function.
4808 return isAssumed(MLK);
4809 }
4810
4811 /// Return the locations that are assumed to be not accessed by the associated
4812 /// function, if any.
4814 return getAssumed();
4815 }
4816
4817 /// Return the inverse of location \p Loc, thus for NO_XXX the return
4818 /// describes ONLY_XXX. The flags \p AndLocalMem and \p AndConstMem determine
4819 /// if local (=stack) and constant memory are allowed as well. Most of the
4820 /// time we do want them to be included, e.g., argmemonly allows accesses via
4821 /// argument pointers or local or constant memory accesses.
4822 static MemoryLocationsKind
4823 inverseLocation(MemoryLocationsKind Loc, bool AndLocalMem, bool AndConstMem) {
4824 return NO_LOCATIONS & ~(Loc | (AndLocalMem ? NO_LOCAL_MEM : 0) |
4825 (AndConstMem ? NO_CONST_MEM : 0));
4826 };
4827
4828 /// Return the locations encoded by \p MLK as a readable string.
4829 static std::string getMemoryLocationsAsStr(MemoryLocationsKind MLK);
4830
4831 /// Simple enum to distinguish read/write/read-write accesses.
4833 NONE = 0,
4834 READ = 1 << 0,
4835 WRITE = 1 << 1,
4837 };
4838
4839 /// Check \p Pred on all accesses to the memory kinds specified by \p MLK.
4840 ///
4841 /// This method will evaluate \p Pred on all accesses (access instruction +
4842 /// underlying accessed memory pointer) and it will return true if \p Pred
4843 /// holds every time.
4845 function_ref<bool(const Instruction *, const Value *, AccessKind,
4847 Pred,
4848 MemoryLocationsKind MLK) const = 0;
4849
4850 /// Create an abstract attribute view for the position \p IRP.
4852 Attributor &A);
4853
4854 /// See AbstractState::getAsStr(Attributor).
4855 const std::string getAsStr(Attributor *A) const override {
4857 }
4858
4859 /// See AbstractAttribute::getName()
4860 const std::string getName() const override { return "AAMemoryLocation"; }
4861
4862 /// See AbstractAttribute::getIdAddr()
4863 const char *getIdAddr() const override { return &ID; }
4864
4865 /// This function should return true if the type of the \p AA is
4866 /// AAMemoryLocation
4867 static bool classof(const AbstractAttribute *AA) {
4868 return (AA->getIdAddr() == &ID);
4869 }
4870
4871 /// Unique ID (due to the unique address)
4872 static const char ID;
4873};
4874
4875/// An abstract interface for range value analysis.
4877 : public StateWrapper<IntegerRangeState, AbstractAttribute, uint32_t> {
4880 : Base(IRP, IRP.getAssociatedType()->getIntegerBitWidth()) {}
4881
4882 /// See AbstractAttribute::isValidIRPositionForInit
4884 if (!IRP.getAssociatedType()->isIntegerTy())
4885 return false;
4887 }
4888
4889 /// See AbstractAttribute::requiresCallersForArgOrFunction
4890 static bool requiresCallersForArgOrFunction() { return true; }
4891
4892 /// See AbstractAttribute::getState(...).
4893 IntegerRangeState &getState() override { return *this; }
4894 const IntegerRangeState &getState() const override { return *this; }
4895
4896 /// Create an abstract attribute view for the position \p IRP.
4898 Attributor &A);
4899
4900 /// Return an assumed range for the associated value a program point \p CtxI.
4901 /// If \p I is nullptr, simply return an assumed range.
4902 virtual ConstantRange
4904 const Instruction *CtxI = nullptr) const = 0;
4905
4906 /// Return a known range for the associated value at a program point \p CtxI.
4907 /// If \p I is nullptr, simply return a known range.
4908 virtual ConstantRange
4910 const Instruction *CtxI = nullptr) const = 0;
4911
4912 /// Return an assumed constant for the associated value a program point \p
4913 /// CtxI.
4914 std::optional<Constant *>
4915 getAssumedConstant(Attributor &A, const Instruction *CtxI = nullptr) const {
4916 ConstantRange RangeV = getAssumedConstantRange(A, CtxI);
4917 if (auto *C = RangeV.getSingleElement()) {
4919 return cast_or_null<Constant>(
4920 AA::getWithType(*ConstantInt::get(Ty->getContext(), *C), *Ty));
4921 }
4922 if (RangeV.isEmptySet())
4923 return std::nullopt;
4924 return nullptr;
4925 }
4926
4927 /// See AbstractAttribute::getName()
4928 const std::string getName() const override { return "AAValueConstantRange"; }
4929
4930 /// See AbstractAttribute::getIdAddr()
4931 const char *getIdAddr() const override { return &ID; }
4932
4933 /// This function should return true if the type of the \p AA is
4934 /// AAValueConstantRange
4935 static bool classof(const AbstractAttribute *AA) {
4936 return (AA->getIdAddr() == &ID);
4937 }
4938
4939 /// Unique ID (due to the unique address)
4940 static const char ID;
4941};
4942
4943/// A class for a set state.
4944/// The assumed boolean state indicates whether the corresponding set is full
4945/// set or not. If the assumed state is false, this is the worst state. The
4946/// worst state (invalid state) of set of potential values is when the set
4947/// contains every possible value (i.e. we cannot in any way limit the value
4948/// that the target position can take). That never happens naturally, we only
4949/// force it. As for the conditions under which we force it, see
4950/// AAPotentialConstantValues.
4951template <typename MemberTy> struct PotentialValuesState : AbstractState {
4953
4954 PotentialValuesState() : IsValidState(true), UndefIsContained(false) {}
4955
4957 : IsValidState(IsValid), UndefIsContained(false) {}
4958
4959 /// See AbstractState::isValidState(...)
4960 bool isValidState() const override { return IsValidState.isValidState(); }
4961
4962 /// See AbstractState::isAtFixpoint(...)
4963 bool isAtFixpoint() const override { return IsValidState.isAtFixpoint(); }
4964
4965 /// See AbstractState::indicatePessimisticFixpoint(...)
4967 return IsValidState.indicatePessimisticFixpoint();
4968 }
4969
4970 /// See AbstractState::indicateOptimisticFixpoint(...)
4972 return IsValidState.indicateOptimisticFixpoint();
4973 }
4974
4975 /// Return the assumed state
4977 const PotentialValuesState &getAssumed() const { return *this; }
4978
4979 /// Return this set. We should check whether this set is valid or not by
4980 /// isValidState() before calling this function.
4981 const SetTy &getAssumedSet() const {
4982 assert(isValidState() && "This set shoud not be used when it is invalid!");
4983 return Set;
4984 }
4985
4986 /// Returns whether this state contains an undef value or not.
4987 bool undefIsContained() const {
4988 assert(isValidState() && "This flag shoud not be used when it is invalid!");
4989 return UndefIsContained;
4990 }
4991
4993 if (isValidState() != RHS.isValidState())
4994 return false;
4995 if (!isValidState() && !RHS.isValidState())
4996 return true;
4997 if (undefIsContained() != RHS.undefIsContained())
4998 return false;
4999 return Set == RHS.getAssumedSet();
5000 }
5001
5002 /// Maximum number of potential values to be tracked.
5003 /// This is set by -attributor-max-potential-values command line option
5004 static unsigned MaxPotentialValues;
5005
5006 /// Return empty set as the best state of potential values.
5008 return PotentialValuesState(true);
5009 }
5010
5012 return getBestState();
5013 }
5014
5015 /// Return full set as the worst state of potential values.
5017 return PotentialValuesState(false);
5018 }
5019
5020 /// Union assumed set with the passed value.
5021 void unionAssumed(const MemberTy &C) { insert(C); }
5022
5023 /// Union assumed set with assumed set of the passed state \p PVS.
5024 void unionAssumed(const PotentialValuesState &PVS) { unionWith(PVS); }
5025
5026 /// Union assumed set with an undef value.
5027 void unionAssumedWithUndef() { unionWithUndef(); }
5028
5029 /// "Clamp" this state with \p PVS.
5031 IsValidState ^= PVS.IsValidState;
5032 unionAssumed(PVS);
5033 return *this;
5034 }
5035
5037 IsValidState &= PVS.IsValidState;
5038 unionAssumed(PVS);
5039 return *this;
5040 }
5041
5042 bool contains(const MemberTy &V) const {
5043 return !isValidState() ? true : Set.contains(V);
5044 }
5045
5046protected:
5048 assert(isValidState() && "This set shoud not be used when it is invalid!");
5049 return Set;
5050 }
5051
5052private:
5053 /// Check the size of this set, and invalidate when the size is no
5054 /// less than \p MaxPotentialValues threshold.
5055 void checkAndInvalidate() {
5056 if (Set.size() >= MaxPotentialValues)
5058 else
5059 reduceUndefValue();
5060 }
5061
5062 /// If this state contains both undef and not undef, we can reduce
5063 /// undef to the not undef value.
5064 void reduceUndefValue() { UndefIsContained = UndefIsContained & Set.empty(); }
5065
5066 /// Insert an element into this set.
5067 void insert(const MemberTy &C) {
5068 if (!isValidState())
5069 return;
5070 Set.insert(C);
5071 checkAndInvalidate();
5072 }
5073
5074 /// Take union with R.
5075 void unionWith(const PotentialValuesState &R) {
5076 /// If this is a full set, do nothing.
5077 if (!isValidState())
5078 return;
5079 /// If R is full set, change L to a full set.
5080 if (!R.isValidState()) {
5082 return;
5083 }
5084 for (const MemberTy &C : R.Set)
5085 Set.insert(C);
5086 UndefIsContained |= R.undefIsContained();
5087 checkAndInvalidate();
5088 }
5089
5090 /// Take union with an undef value.
5091 void unionWithUndef() {
5092 UndefIsContained = true;
5093 reduceUndefValue();
5094 }
5095
5096 /// Take intersection with R.
5097 void intersectWith(const PotentialValuesState &R) {
5098 /// If R is a full set, do nothing.
5099 if (!R.isValidState())
5100 return;
5101 /// If this is a full set, change this to R.
5102 if (!isValidState()) {
5103 *this = R;
5104 return;
5105 }
5106 SetTy IntersectSet;
5107 for (const MemberTy &C : Set) {
5108 if (R.Set.count(C))
5109 IntersectSet.insert(C);
5110 }
5111 Set = IntersectSet;
5112 UndefIsContained &= R.undefIsContained();
5113 reduceUndefValue();
5114 }
5115
5116 /// A helper state which indicate whether this state is valid or not.
5117 BooleanState IsValidState;
5118
5119 /// Container for potential values
5120 SetTy Set;
5121
5122 /// Flag for undef value
5123 bool UndefIsContained;
5124};
5125
5130
5131 bool operator==(const DenormalState Other) const {
5132 return Mode == Other.Mode && ModeF32 == Other.ModeF32;
5133 }
5134
5135 bool operator!=(const DenormalState Other) const {
5136 return Mode != Other.Mode || ModeF32 != Other.ModeF32;
5137 }
5138
5139 bool isValid() const { return Mode.isValid() && ModeF32.isValid(); }
5140
5144 if (Caller == Callee)
5145 return Caller;
5146 if (Callee == DenormalMode::Dynamic)
5147 return Caller;
5148 if (Caller == DenormalMode::Dynamic)
5149 return Callee;
5150 return DenormalMode::Invalid;
5151 }
5152
5154 return DenormalMode{unionDenormalKind(Callee.Output, Caller.Output),
5155 unionDenormalKind(Callee.Input, Caller.Input)};
5156 }
5157
5159 DenormalState Callee(*this);
5160 Callee.Mode = unionAssumed(Callee.Mode, Caller.Mode);
5161 Callee.ModeF32 = unionAssumed(Callee.ModeF32, Caller.ModeF32);
5162 return Callee;
5163 }
5164 };
5165
5167
5168 /// Explicitly track whether we've hit a fixed point.
5169 bool IsAtFixedpoint = false;
5170
5172
5173 DenormalState getKnown() const { return Known; }
5174
5175 // There's only really known or unknown, there's no speculatively assumable
5176 // state.
5177 DenormalState getAssumed() const { return Known; }
5178
5179 bool isValidState() const override { return Known.isValid(); }
5180
5181 /// Return true if there are no dynamic components to the denormal mode worth
5182 /// specializing.
5183 bool isModeFixed() const {
5188 }
5189
5190 bool isAtFixpoint() const override { return IsAtFixedpoint; }
5191
5193 bool Changed = !IsAtFixedpoint;
5194 IsAtFixedpoint = true;
5196 }
5197
5199 return indicateFixpoint();
5200 }
5201
5203 return indicateFixpoint();
5204 }
5205
5207 Known = Known.unionWith(Caller.getKnown());
5208 return *this;
5209 }
5210};
5211
5215
5219
5220/// An abstract interface for potential values analysis.
5221///
5222/// This AA collects potential values for each IR position.
5223/// An assumed set of potential values is initialized with the empty set (the
5224/// best state) and it will grow monotonically as we find more potential values
5225/// for this position.
5226/// The set might be forced to the worst state, that is, to contain every
5227/// possible value for this position in 2 cases.
5228/// 1. We surpassed the \p MaxPotentialValues threshold. This includes the
5229/// case that this position is affected (e.g. because of an operation) by a
5230/// Value that is in the worst state.
5231/// 2. We tried to initialize on a Value that we cannot handle (e.g. an
5232/// operator we do not currently handle).
5233///
5234/// For non constant integers see AAPotentialValues.
5236 : public StateWrapper<PotentialConstantIntValuesState, AbstractAttribute> {
5239
5240 /// See AbstractAttribute::isValidIRPositionForInit
5242 if (!IRP.getAssociatedType()->isIntegerTy())
5243 return false;
5245 }
5246
5247 /// See AbstractAttribute::requiresCallersForArgOrFunction
5248 static bool requiresCallersForArgOrFunction() { return true; }
5249
5250 /// See AbstractAttribute::getState(...).
5251 PotentialConstantIntValuesState &getState() override { return *this; }
5253 return *this;
5254 }
5255
5256 /// Create an abstract attribute view for the position \p IRP.
5258 Attributor &A);
5259
5260 /// Return assumed constant for the associated value
5261 std::optional<Constant *>
5262 getAssumedConstant(Attributor &A, const Instruction *CtxI = nullptr) const {
5263 if (!isValidState())
5264 return nullptr;
5265 if (getAssumedSet().size() == 1) {
5267 return cast_or_null<Constant>(AA::getWithType(
5268 *ConstantInt::get(Ty->getContext(), *(getAssumedSet().begin())),
5269 *Ty));
5270 }
5271 if (getAssumedSet().size() == 0) {
5272 if (undefIsContained())
5274 return std::nullopt;
5275 }
5276
5277 return nullptr;
5278 }
5279
5280 /// See AbstractAttribute::getName()
5281 const std::string getName() const override {
5282 return "AAPotentialConstantValues";
5283 }
5284
5285 /// See AbstractAttribute::getIdAddr()
5286 const char *getIdAddr() const override { return &ID; }
5287
5288 /// This function should return true if the type of the \p AA is
5289 /// AAPotentialConstantValues
5290 static bool classof(const AbstractAttribute *AA) {
5291 return (AA->getIdAddr() == &ID);
5292 }
5293
5294 /// Unique ID (due to the unique address)
5295 static const char ID;
5296};
5297
5299 : public StateWrapper<PotentialLLVMValuesState, AbstractAttribute> {
5302
5303 /// See AbstractAttribute::requiresCallersForArgOrFunction
5304 static bool requiresCallersForArgOrFunction() { return true; }
5305
5306 /// See AbstractAttribute::getState(...).
5307 PotentialLLVMValuesState &getState() override { return *this; }
5308 const PotentialLLVMValuesState &getState() const override { return *this; }
5309
5310 /// Create an abstract attribute view for the position \p IRP.
5312 Attributor &A);
5313
5314 /// Extract the single value in \p Values if any.
5316 const IRPosition &IRP,
5318
5319 /// See AbstractAttribute::getName()
5320 const std::string getName() const override { return "AAPotentialValues"; }
5321
5322 /// See AbstractAttribute::getIdAddr()
5323 const char *getIdAddr() const override { return &ID; }
5324
5325 /// This function should return true if the type of the \p AA is
5326 /// AAPotentialValues
5327 static bool classof(const AbstractAttribute *AA) {
5328 return (AA->getIdAddr() == &ID);
5329 }
5330
5331 /// Unique ID (due to the unique address)
5332 static const char ID;
5333
5334private:
5335 virtual bool getAssumedSimplifiedValues(
5337 AA::ValueScope, bool RecurseForSelectAndPHI = false) const = 0;
5338
5339 friend struct Attributor;
5340};
5341
5342/// An abstract interface for all noundef attributes.
5344 : public IRAttribute<Attribute::NoUndef,
5345 StateWrapper<BooleanState, AbstractAttribute>,
5346 AANoUndef> {
5348
5349 /// See IRAttribute::isImpliedByUndef
5350 static bool isImpliedByUndef() { return false; }
5351
5352 /// See IRAttribute::isImpliedByPoison
5353 static bool isImpliedByPoison() { return false; }
5354
5355 /// See IRAttribute::isImpliedByIR
5356 static bool isImpliedByIR(Attributor &A, const IRPosition &IRP,
5357 Attribute::AttrKind ImpliedAttributeKind,
5358 bool IgnoreSubsumingPositions = false);
5359
5360 /// Return true if we assume that the underlying value is noundef.
5361 bool isAssumedNoUndef() const { return getAssumed(); }
5362
5363 /// Return true if we know that underlying value is noundef.
5364 bool isKnownNoUndef() const { return getKnown(); }
5365
5366 /// Create an abstract attribute view for the position \p IRP.
5368
5369 /// See AbstractAttribute::getName()
5370 const std::string getName() const override { return "AANoUndef"; }
5371
5372 /// See AbstractAttribute::getIdAddr()
5373 const char *getIdAddr() const override { return &ID; }
5374
5375 /// This function should return true if the type of the \p AA is AANoUndef
5376 static bool classof(const AbstractAttribute *AA) {
5377 return (AA->getIdAddr() == &ID);
5378 }
5379
5380 /// Unique ID (due to the unique address)
5381 static const char ID;
5382};
5383
5385 : public IRAttribute<
5386 Attribute::NoFPClass,
5387 StateWrapper<BitIntegerState<uint32_t, fcAllFlags, fcNone>,
5388 AbstractAttribute>,
5389 AANoFPClass> {
5392
5394
5395 /// See AbstractAttribute::isValidIRPositionForInit
5397 Type *Ty = IRP.getAssociatedType();
5398 do {
5399 if (Ty->isFPOrFPVectorTy())
5400 return IRAttribute::isValidIRPositionForInit(A, IRP);
5401 if (!Ty->isArrayTy())
5402 break;
5403 Ty = Ty->getArrayElementType();
5404 } while (true);
5405 return false;
5406 }
5407
5408 /// Return the underlying assumed nofpclass.
5410 return static_cast<FPClassTest>(getAssumed());
5411 }
5412 /// Return the underlying known nofpclass.
5414 return static_cast<FPClassTest>(getKnown());
5415 }
5416
5417 /// Create an abstract attribute view for the position \p IRP.
5419
5420 /// See AbstractAttribute::getName()
5421 const std::string getName() const override { return "AANoFPClass"; }
5422
5423 /// See AbstractAttribute::getIdAddr()
5424 const char *getIdAddr() const override { return &ID; }
5425
5426 /// This function should return true if the type of the \p AA is AANoFPClass
5427 static bool classof(const AbstractAttribute *AA) {
5428 return (AA->getIdAddr() == &ID);
5429 }
5430
5431 /// Unique ID (due to the unique address)
5432 static const char ID;
5433};
5434
5435struct AACallGraphNode;
5436struct AACallEdges;
5437
5438/// An Iterator for call edges, creates AACallEdges attributes in a lazy way.
5439/// This iterator becomes invalid if the underlying edge list changes.
5440/// So This shouldn't outlive a iteration of Attributor.
5442 : public iterator_adaptor_base<AACallEdgeIterator,
5443 SetVector<Function *>::iterator> {
5445 : iterator_adaptor_base(Begin), A(A) {}
5446
5447public:
5448 AACallGraphNode *operator*() const;
5449
5450private:
5451 Attributor &A;
5452 friend AACallEdges;
5453 friend AttributorCallGraph;
5454};
5455
5458 virtual ~AACallGraphNode() = default;
5459
5462
5463 /// Iterator range for exploring the call graph.
5467 }
5468
5469protected:
5470 /// Reference to Attributor needed for GraphTraits implementation.
5472};
5473
5474/// An abstract state for querying live call edges.
5475/// This interface uses the Attributor's optimistic liveness
5476/// information to compute the edges that are alive.
5477struct AACallEdges : public StateWrapper<BooleanState, AbstractAttribute>,
5480
5482 : Base(IRP), AACallGraphNode(A) {}
5483
5484 /// See AbstractAttribute::requiresNonAsmForCallBase.
5485 static bool requiresNonAsmForCallBase() { return false; }
5486
5487 /// Get the optimistic edges.
5488 virtual const SetVector<Function *> &getOptimisticEdges() const = 0;
5489
5490 /// Is there any call with a unknown callee.
5491 virtual bool hasUnknownCallee() const = 0;
5492
5493 /// Is there any call with a unknown callee, excluding any inline asm.
5494 virtual bool hasNonAsmUnknownCallee() const = 0;
5495
5496 /// Iterator for exploring the call graph.
5499 }
5500
5501 /// Iterator for exploring the call graph.
5504 }
5505
5506 /// Create an abstract attribute view for the position \p IRP.
5508
5509 /// See AbstractAttribute::getName()
5510 const std::string getName() const override { return "AACallEdges"; }
5511
5512 /// See AbstractAttribute::getIdAddr()
5513 const char *getIdAddr() const override { return &ID; }
5514
5515 /// This function should return true if the type of the \p AA is AACallEdges.
5516 static bool classof(const AbstractAttribute *AA) {
5517 return (AA->getIdAddr() == &ID);
5518 }
5519
5520 /// Unique ID (due to the unique address)
5521 static const char ID;
5522};
5523
5524// Synthetic root node for the Attributor's internal call graph.
5527 virtual ~AttributorCallGraph() = default;
5528
5530 return AACallEdgeIterator(A, A.Functions.begin());
5531 }
5532
5534 return AACallEdgeIterator(A, A.Functions.end());
5535 }
5536
5537 /// Force populate the entire call graph.
5538 void populateAll() const {
5539 for (const AACallGraphNode *AA : optimisticEdgesRange()) {
5540 // Nothing else to do here.
5541 (void)AA;
5542 }
5543 }
5544
5545 void print();
5546};
5547
5548template <> struct GraphTraits<AACallGraphNode *> {
5551
5553 return Node->optimisticEdgesBegin();
5554 }
5555
5557 return Node->optimisticEdgesEnd();
5558 }
5559};
5560
5561template <>
5565
5567 return static_cast<AACallGraphNode *>(G);
5568 }
5569
5571 return G->optimisticEdgesBegin();
5572 }
5573
5575 return G->optimisticEdgesEnd();
5576 }
5577};
5578
5579template <>
5582
5584 const AttributorCallGraph *Graph) {
5585 const AACallEdges *AACE = static_cast<const AACallEdges *>(Node);
5586 return AACE->getAssociatedFunction()->getName().str();
5587 }
5588
5590 const AttributorCallGraph *Graph) {
5591 // Hide the synth root.
5592 return static_cast<const AACallGraphNode *>(Graph) == Node;
5593 }
5594};
5595
5597 : public StateWrapper<BooleanState, AbstractAttribute> {
5600
5601 /// Summary about the execution domain of a block or instruction.
5605
5608 }
5609
5612 }
5613
5617 }
5618
5625 };
5626
5627 /// Create an abstract attribute view for the position \p IRP.
5629 Attributor &A);
5630
5631 /// See AbstractAttribute::getName().
5632 const std::string getName() const override { return "AAExecutionDomain"; }
5633
5634 /// See AbstractAttribute::getIdAddr().
5635 const char *getIdAddr() const override { return &ID; }
5636
5637 /// Check if an instruction is executed only by the initial thread.
5639 return isExecutedByInitialThreadOnly(*I.getParent());
5640 }
5641
5642 /// Check if a basic block is executed only by the initial thread.
5643 virtual bool isExecutedByInitialThreadOnly(const BasicBlock &) const = 0;
5644
5645 /// Check if the instruction \p I is executed in an aligned region, that is,
5646 /// the synchronizing effects before and after \p I are both aligned barriers.
5647 /// This effectively means all threads execute \p I together.
5649 const Instruction &I) const = 0;
5650
5652 /// Return the execution domain with which the call \p CB is entered and the
5653 /// one with which it is left.
5654 virtual std::pair<ExecutionDomainTy, ExecutionDomainTy>
5655 getExecutionDomain(const CallBase &CB) const = 0;
5657
5658 /// Helper function to determine if \p FI is a no-op given the information
5659 /// about its execution from \p ExecDomainAA.
5660 virtual bool isNoOpFence(const FenceInst &FI) const = 0;
5661
5662 /// This function should return true if the type of the \p AA is
5663 /// AAExecutionDomain.
5664 static bool classof(const AbstractAttribute *AA) {
5665 return (AA->getIdAddr() == &ID);
5666 }
5667
5668 /// Unique ID (due to the unique address)
5669 static const char ID;
5670};
5671
5672/// An abstract Attribute for computing reachability between functions.
5674 : public StateWrapper<BooleanState, AbstractAttribute> {
5676
5678
5679 /// If the function represented by this possition can reach \p Fn.
5680 bool canReach(Attributor &A, const Function &Fn) const {
5681 Function *Scope = getAnchorScope();
5682 if (!Scope || Scope->isDeclaration())
5683 return true;
5684 return instructionCanReach(A, Scope->getEntryBlock().front(), Fn);
5685 }
5686
5687 /// Can \p Inst reach \p Fn.
5688 /// See also AA::isPotentiallyReachable.
5690 Attributor &A, const Instruction &Inst, const Function &Fn,
5691 const AA::InstExclusionSetTy *ExclusionSet = nullptr) const = 0;
5692
5693 /// Create an abstract attribute view for the position \p IRP.
5695 Attributor &A);
5696
5697 /// See AbstractAttribute::getName()
5698 const std::string getName() const override { return "AAInterFnReachability"; }
5699
5700 /// See AbstractAttribute::getIdAddr()
5701 const char *getIdAddr() const override { return &ID; }
5702
5703 /// This function should return true if the type of the \p AA is AACallEdges.
5704 static bool classof(const AbstractAttribute *AA) {
5705 return (AA->getIdAddr() == &ID);
5706 }
5707
5708 /// Unique ID (due to the unique address)
5709 static const char ID;
5710};
5711
5712/// An abstract Attribute for determining the necessity of the convergent
5713/// attribute.
5714struct AANonConvergent : public StateWrapper<BooleanState, AbstractAttribute> {
5716
5718
5719 /// Create an abstract attribute view for the position \p IRP.
5721 Attributor &A);
5722
5723 /// Return true if "non-convergent" is assumed.
5724 bool isAssumedNotConvergent() const { return getAssumed(); }
5725
5726 /// Return true if "non-convergent" is known.
5727 bool isKnownNotConvergent() const { return getKnown(); }
5728
5729 /// See AbstractAttribute::getName()
5730 const std::string getName() const override { return "AANonConvergent"; }
5731
5732 /// See AbstractAttribute::getIdAddr()
5733 const char *getIdAddr() const override { return &ID; }
5734
5735 /// This function should return true if the type of the \p AA is
5736 /// AANonConvergent.
5737 static bool classof(const AbstractAttribute *AA) {
5738 return (AA->getIdAddr() == &ID);
5739 }
5740
5741 /// Unique ID (due to the unique address)
5742 static const char ID;
5743};
5744
5745/// An abstract interface for struct information.
5748
5749 /// See AbstractAttribute::isValidIRPositionForInit
5752 return false;
5754 }
5755
5757 // First two bits to distinguish may and must accesses.
5758 AK_MUST = 1 << 0,
5759 AK_MAY = 1 << 1,
5760
5761 // Then two bits for read and write. These are not exclusive.
5762 AK_R = 1 << 2,
5763 AK_W = 1 << 3,
5765
5766 // One special case for assumptions about memory content. These
5767 // are neither reads nor writes. They are however always modeled
5768 // as read to avoid using them for write removal.
5770
5771 // Helper for easy access.
5778 };
5779
5780 /// A container for a list of ranges.
5781 struct RangeList {
5782 // The set of ranges rarely contains more than one element, and is unlikely
5783 // to contain more than say four elements. So we find the middle-ground with
5784 // a sorted vector. This avoids hard-coding a rarely used number like "four"
5785 // into every instance of a SmallSet.
5791
5794 Ranges.reserve(Offsets.size());
5795 for (unsigned i = 0, e = Offsets.size(); i != e; ++i) {
5796 assert(((i + 1 == e) || Offsets[i] < Offsets[i + 1]) &&
5797 "Expected strictly ascending offsets.");
5798 Ranges.emplace_back(Offsets[i], Size);
5799 }
5800 }
5801 RangeList() = default;
5802
5803 iterator begin() { return Ranges.begin(); }
5804 iterator end() { return Ranges.end(); }
5805 const_iterator begin() const { return Ranges.begin(); }
5806 const_iterator end() const { return Ranges.end(); }
5807
5808 // Helpers required for std::set_difference
5810 void push_back(const RangeTy &R) {
5812 "Ensure the last element is the greatest.");
5813 Ranges.push_back(R);
5814 }
5815
5816 /// Copy ranges from \p L that are not in \p R, into \p D.
5817 static void set_difference(const RangeList &L, const RangeList &R,
5818 RangeList &D) {
5819 std::set_difference(L.begin(), L.end(), R.begin(), R.end(),
5820 std::back_inserter(D), RangeTy::OffsetLessThan);
5821 }
5822
5823 unsigned size() const { return Ranges.size(); }
5824
5825 bool operator==(const RangeList &OI) const { return Ranges == OI.Ranges; }
5826
5827 /// Merge the ranges in \p RHS into the current ranges.
5828 /// - Merging a list of unknown ranges makes the current list unknown.
5829 /// - Ranges with the same offset are merged according to RangeTy::operator&
5830 /// \return true if the current RangeList changed.
5831 bool merge(const RangeList &RHS) {
5832 if (isUnknown())
5833 return false;
5834 if (RHS.isUnknown()) {
5835 setUnknown();
5836 return true;
5837 }
5838
5839 if (Ranges.empty()) {
5840 Ranges = RHS.Ranges;
5841 return true;
5842 }
5843
5844 bool Changed = false;
5845 auto LPos = Ranges.begin();
5846 for (auto &R : RHS.Ranges) {
5847 auto Result = insert(LPos, R);
5848 if (isUnknown())
5849 return true;
5850 LPos = Result.first;
5851 Changed |= Result.second;
5852 }
5853 return Changed;
5854 }
5855
5856 /// Insert \p R at the given iterator \p Pos, and merge if necessary.
5857 ///
5858 /// This assumes that all ranges before \p Pos are OffsetLessThan \p R, and
5859 /// then maintains the sorted order for the suffix list.
5860 ///
5861 /// \return The place of insertion and true iff anything changed.
5862 std::pair<iterator, bool> insert(iterator Pos, const RangeTy &R) {
5863 if (isUnknown())
5864 return std::make_pair(Ranges.begin(), false);
5865 if (R.offsetOrSizeAreUnknown()) {
5866 return std::make_pair(setUnknown(), true);
5867 }
5868
5869 // Maintain this as a sorted vector of unique entries.
5870 auto LB = std::lower_bound(Pos, Ranges.end(), R, RangeTy::OffsetLessThan);
5871 if (LB == Ranges.end() || LB->Offset != R.Offset)
5872 return std::make_pair(Ranges.insert(LB, R), true);
5873 bool Changed = *LB != R;
5874 *LB &= R;
5875 if (LB->offsetOrSizeAreUnknown())
5876 return std::make_pair(setUnknown(), true);
5877 return std::make_pair(LB, Changed);
5878 }
5879
5880 /// Insert the given range \p R, maintaining sorted order.
5881 ///
5882 /// \return The place of insertion and true iff anything changed.
5883 std::pair<iterator, bool> insert(const RangeTy &R) {
5884 return insert(Ranges.begin(), R);
5885 }
5886
5887 /// Add the increment \p Inc to the offset of every range.
5888 void addToAllOffsets(int64_t Inc) {
5889 assert(!isUnassigned() &&
5890 "Cannot increment if the offset is not yet computed!");
5891 if (isUnknown())
5892 return;
5893 for (auto &R : Ranges) {
5894 R.Offset += Inc;
5895 }
5896 }
5897
5898 /// Return true iff there is exactly one range and it is known.
5899 bool isUnique() const {
5900 return Ranges.size() == 1 && !Ranges.front().offsetOrSizeAreUnknown();
5901 }
5902
5903 /// Return the unique range, assuming it exists.
5904 const RangeTy &getUnique() const {
5905 assert(isUnique() && "No unique range to return!");
5906 return Ranges.front();
5907 }
5908
5909 /// Return true iff the list contains an unknown range.
5910 bool isUnknown() const {
5911 if (isUnassigned())
5912 return false;
5913 if (Ranges.front().offsetOrSizeAreUnknown()) {
5914 assert(Ranges.size() == 1 && "Unknown is a singleton range.");
5915 return true;
5916 }
5917 return false;
5918 }
5919
5920 /// Discard all ranges and insert a single unknown range.
5922 Ranges.clear();
5924 return Ranges.begin();
5925 }
5926
5927 /// Return true if no ranges have been inserted.
5928 bool isUnassigned() const { return Ranges.size() == 0; }
5929 };
5930
5931 /// An access description.
5932 struct Access {
5933 Access(Instruction *I, int64_t Offset, int64_t Size,
5934 std::optional<Value *> Content, AccessKind Kind, Type *Ty)
5935 : LocalI(I), RemoteI(I), Content(Content), Ranges(Offset, Size),
5936 Kind(Kind), Ty(Ty) {
5937 verify();
5938 }
5939 Access(Instruction *LocalI, Instruction *RemoteI, const RangeList &Ranges,
5940 std::optional<Value *> Content, AccessKind K, Type *Ty)
5941 : LocalI(LocalI), RemoteI(RemoteI), Content(Content), Ranges(Ranges),
5942 Kind(K), Ty(Ty) {
5943 if (Ranges.size() > 1) {
5946 }
5947 verify();
5948 }
5949 Access(Instruction *LocalI, Instruction *RemoteI, int64_t Offset,
5950 int64_t Size, std::optional<Value *> Content, AccessKind Kind,
5951 Type *Ty)
5952 : LocalI(LocalI), RemoteI(RemoteI), Content(Content),
5953 Ranges(Offset, Size), Kind(Kind), Ty(Ty) {
5954 verify();
5955 }
5956 Access(const Access &Other) = default;
5957
5958 Access &operator=(const Access &Other) = default;
5959 bool operator==(const Access &R) const {
5960 return LocalI == R.LocalI && RemoteI == R.RemoteI && Ranges == R.Ranges &&
5961 Content == R.Content && Kind == R.Kind;
5962 }
5963 bool operator!=(const Access &R) const { return !(*this == R); }
5964
5966 assert(RemoteI == R.RemoteI && "Expected same instruction!");
5967 assert(LocalI == R.LocalI && "Expected same instruction!");
5968
5969 // Note that every Access object corresponds to a unique Value, and only
5970 // accesses to the same Value are merged. Hence we assume that all ranges
5971 // are the same size. If ranges can be different size, then the contents
5972 // must be dropped.
5973 Ranges.merge(R.Ranges);
5974 Content =
5975 AA::combineOptionalValuesInAAValueLatice(Content, R.Content, Ty);
5976
5977 // Combine the access kind, which results in a bitwise union.
5978 // If there is more than one range, then this must be a MAY.
5979 // If we combine a may and a must access we clear the must bit.
5980 Kind = AccessKind(Kind | R.Kind);
5981 if ((Kind & AK_MAY) || Ranges.size() > 1) {
5984 }
5985 verify();
5986 return *this;
5987 }
5988
5989 void verify() {
5990 assert(isMustAccess() + isMayAccess() == 1 &&
5991 "Expect must or may access, not both.");
5992 assert(isAssumption() + isWrite() <= 1 &&
5993 "Expect assumption access or write access, never both.");
5994 assert((isMayAccess() || Ranges.size() == 1) &&
5995 "Cannot be a must access if there are multiple ranges.");
5996 }
5997
5998 /// Return the access kind.
5999 AccessKind getKind() const { return Kind; }
6000
6001 /// Return true if this is a read access.
6002 bool isRead() const { return Kind & AK_R; }
6003
6004 /// Return true if this is a write access.
6005 bool isWrite() const { return Kind & AK_W; }
6006
6007 /// Return true if this is a write access.
6008 bool isWriteOrAssumption() const { return isWrite() || isAssumption(); }
6009
6010 /// Return true if this is an assumption access.
6011 bool isAssumption() const { return Kind == AK_ASSUMPTION; }
6012
6013 bool isMustAccess() const {
6014 bool MustAccess = Kind & AK_MUST;
6015 assert((!MustAccess || Ranges.size() < 2) &&
6016 "Cannot be a must access if there are multiple ranges.");
6017 return MustAccess;
6018 }
6019
6020 bool isMayAccess() const {
6021 bool MayAccess = Kind & AK_MAY;
6022 assert((MayAccess || Ranges.size() < 2) &&
6023 "Cannot be a must access if there are multiple ranges.");
6024 return MayAccess;
6025 }
6026
6027 /// Return the instruction that causes the access with respect to the local
6028 /// scope of the associated attribute.
6029 Instruction *getLocalInst() const { return LocalI; }
6030
6031 /// Return the actual instruction that causes the access.
6032 Instruction *getRemoteInst() const { return RemoteI; }
6033
6034 /// Return true if the value written is not known yet.
6035 bool isWrittenValueYetUndetermined() const { return !Content; }
6036
6037 /// Return true if the value written cannot be determined at all.
6039 return Content.has_value() && !*Content;
6040 }
6041
6042 /// Set the value written to nullptr, i.e., unknown.
6043 void setWrittenValueUnknown() { Content = nullptr; }
6044
6045 /// Return the type associated with the access, if known.
6046 Type *getType() const { return Ty; }
6047
6048 /// Return the value writen, if any.
6051 "Value needs to be determined before accessing it.");
6052 return *Content;
6053 }
6054
6055 /// Return the written value which can be `llvm::null` if it is not yet
6056 /// determined.
6057 std::optional<Value *> getContent() const { return Content; }
6058
6059 bool hasUniqueRange() const { return Ranges.isUnique(); }
6060 const AA::RangeTy &getUniqueRange() const { return Ranges.getUnique(); }
6061
6062 /// Add a range accessed by this Access.
6063 ///
6064 /// If there are multiple ranges, then this is a "may access".
6065 void addRange(int64_t Offset, int64_t Size) {
6066 Ranges.insert({Offset, Size});
6067 if (!hasUniqueRange()) {
6070 }
6071 }
6072
6073 const RangeList &getRanges() const { return Ranges; }
6074
6076 const_iterator begin() const { return Ranges.begin(); }
6077 const_iterator end() const { return Ranges.end(); }
6078
6079 private:
6080 /// The instruction responsible for the access with respect to the local
6081 /// scope of the associated attribute.
6082 Instruction *LocalI;
6083
6084 /// The instruction responsible for the access.
6085 Instruction *RemoteI;
6086
6087 /// The value written, if any. `std::nullopt` means "not known yet",
6088 /// `nullptr` cannot be determined.
6089 std::optional<Value *> Content;
6090
6091 /// Set of potential ranges accessed from the base pointer.
6092 RangeList Ranges;
6093
6094 /// The access kind, e.g., READ, as bitset (could be more than one).
6096
6097 /// The type of the content, thus the type read/written, can be null if not
6098 /// available.
6099 Type *Ty;
6100 };
6101
6102 /// Create an abstract attribute view for the position \p IRP.
6104
6105 /// See AbstractAttribute::getName()
6106 const std::string getName() const override { return "AAPointerInfo"; }
6107
6108 /// See AbstractAttribute::getIdAddr()
6109 const char *getIdAddr() const override { return &ID; }
6110
6113 virtual const_bin_iterator begin() const = 0;
6114 virtual const_bin_iterator end() const = 0;
6115 virtual int64_t numOffsetBins() const = 0;
6116
6117 /// Call \p CB on all accesses that might interfere with \p Range and return
6118 /// true if all such accesses were known and the callback returned true for
6119 /// all of them, false otherwise. An access interferes with an offset-size
6120 /// pair if it might read or write that memory region.
6122 AA::RangeTy Range, function_ref<bool(const Access &, bool)> CB) const = 0;
6123
6124 /// Call \p CB on all accesses that might interfere with \p I and
6125 /// return true if all such accesses were known and the callback returned true
6126 /// for all of them, false otherwise. In contrast to forallInterferingAccesses
6127 /// this function will perform reasoning to exclude write accesses that cannot
6128 /// affect the load even if they on the surface look as if they would. The
6129 /// flag \p HasBeenWrittenTo will be set to true if we know that \p I does not
6130 /// read the initial value of the underlying memory. If \p SkipCB is given and
6131 /// returns false for a potentially interfering access, that access is not
6132 /// checked for actual interference.
6134 Attributor &A, const AbstractAttribute &QueryingAA, Instruction &I,
6135 bool FindInterferingWrites, bool FindInterferingReads,
6136 function_ref<bool(const Access &, bool)> CB, bool &HasBeenWrittenTo,
6138 function_ref<bool(const Access &)> SkipCB = nullptr) const = 0;
6139
6140 /// This function should return true if the type of the \p AA is AAPointerInfo
6141 static bool classof(const AbstractAttribute *AA) {
6142 return (AA->getIdAddr() == &ID);
6143 }
6144
6145 /// Unique ID (due to the unique address)
6146 static const char ID;
6147};
6148
6150
6151/// An abstract attribute for getting assumption information.
6153 : public StateWrapper<SetState<StringRef>, AbstractAttribute,
6154 DenseSet<StringRef>> {
6155 using Base =
6157
6159 const DenseSet<StringRef> &Known)
6160 : Base(IRP, Known) {}
6161
6162 /// Returns true if the assumption set contains the assumption \p Assumption.
6163 virtual bool hasAssumption(const StringRef Assumption) const = 0;
6164
6165 /// Create an abstract attribute view for the position \p IRP.
6167 Attributor &A);
6168
6169 /// See AbstractAttribute::getName()
6170 const std::string getName() const override { return "AAAssumptionInfo"; }
6171
6172 /// See AbstractAttribute::getIdAddr()
6173 const char *getIdAddr() const override { return &ID; }
6174
6175 /// This function should return true if the type of the \p AA is
6176 /// AAAssumptionInfo
6177 static bool classof(const AbstractAttribute *AA) {
6178 return (AA->getIdAddr() == &ID);
6179 }
6180
6181 /// Unique ID (due to the unique address)
6182 static const char ID;
6183};
6184
6185/// An abstract attribute for getting all assumption underlying objects.
6188
6189 /// See AbstractAttribute::isValidIRPositionForInit
6192 return false;
6194 }
6195
6196 /// See AbstractAttribute::requiresCallersForArgOrFunction
6197 static bool requiresCallersForArgOrFunction() { return true; }
6198
6199 /// Create an abstract attribute biew for the position \p IRP.
6201 Attributor &A);
6202
6203 /// See AbstractAttribute::getName()
6204 const std::string getName() const override { return "AAUnderlyingObjects"; }
6205
6206 /// See AbstractAttribute::getIdAddr()
6207 const char *getIdAddr() const override { return &ID; }
6208
6209 /// This function should return true if the type of the \p AA is
6210 /// AAUnderlyingObjects.
6211 static bool classof(const AbstractAttribute *AA) {
6212 return (AA->getIdAddr() == &ID);
6213 }
6214
6215 /// Unique ID (due to the unique address)
6216 static const char ID;
6217
6218 /// Check \p Pred on all underlying objects in \p Scope collected so far.
6219 ///
6220 /// This method will evaluate \p Pred on all underlying objects in \p Scope
6221 /// collected so far and return true if \p Pred holds on all of them.
6222 virtual bool
6224 AA::ValueScope Scope = AA::Interprocedural) const = 0;
6225};
6226
6227/// An abstract interface for address space information.
6228struct AAAddressSpace : public StateWrapper<BooleanState, AbstractAttribute> {
6231
6232 /// See AbstractAttribute::isValidIRPositionForInit
6235 return false;
6237 }
6238
6239 /// See AbstractAttribute::requiresCallersForArgOrFunction
6240 static bool requiresCallersForArgOrFunction() { return true; }
6241
6242 /// Return the address space of the associated value. \p NoAddressSpace is
6243 /// returned if the associated value is dead. This functions is not supposed
6244 /// to be called if the AA is invalid.
6245 virtual int32_t getAddressSpace() const = 0;
6246
6247 /// Create an abstract attribute view for the position \p IRP.
6249 Attributor &A);
6250
6251 /// See AbstractAttribute::getName()
6252 const std::string getName() const override { return "AAAddressSpace"; }
6253
6254 /// See AbstractAttribute::getIdAddr()
6255 const char *getIdAddr() const override { return &ID; }
6256
6257 /// This function should return true if the type of the \p AA is
6258 /// AAAssumptionInfo
6259 static bool classof(const AbstractAttribute *AA) {
6260 return (AA->getIdAddr() == &ID);
6261 }
6262
6263 // No address space which indicates the associated value is dead.
6264 static const int32_t NoAddressSpace = -1;
6265
6266 /// Unique ID (due to the unique address)
6267 static const char ID;
6268};
6269
6270struct AAAllocationInfo : public StateWrapper<BooleanState, AbstractAttribute> {
6273
6274 /// See AbstractAttribute::isValidIRPositionForInit
6277 return false;
6279 }
6280
6281 /// Create an abstract attribute view for the position \p IRP.
6283 Attributor &A);
6284
6285 virtual std::optional<TypeSize> getAllocatedSize() const = 0;
6286
6287 /// See AbstractAttribute::getName()
6288 const std::string getName() const override { return "AAAllocationInfo"; }
6289
6290 /// See AbstractAttribute::getIdAddr()
6291 const char *getIdAddr() const override { return &ID; }
6292
6293 /// This function should return true if the type of the \p AA is
6294 /// AAAllocationInfo
6295 static bool classof(const AbstractAttribute *AA) {
6296 return (AA->getIdAddr() == &ID);
6297 }
6298
6299 constexpr static const std::optional<TypeSize> HasNoAllocationSize =
6300 std::optional<TypeSize>(TypeSize(-1, true));
6301
6302 static const char ID;
6303};
6304
6305/// An abstract interface for llvm::GlobalValue information interference.
6307 : public StateWrapper<BooleanState, AbstractAttribute> {
6310
6311 /// See AbstractAttribute::isValidIRPositionForInit
6314 return false;
6315 auto *GV = dyn_cast<GlobalValue>(&IRP.getAnchorValue());
6316 if (!GV)
6317 return false;
6318 return GV->hasLocalLinkage();
6319 }
6320
6321 /// Create an abstract attribute view for the position \p IRP.
6323 Attributor &A);
6324
6325 /// Return true iff \p U is a potential use of the associated global value.
6326 virtual bool isPotentialUse(const Use &U) const = 0;
6327
6328 /// See AbstractAttribute::getName()
6329 const std::string getName() const override { return "AAGlobalValueInfo"; }
6330
6331 /// See AbstractAttribute::getIdAddr()
6332 const char *getIdAddr() const override { return &ID; }
6333
6334 /// This function should return true if the type of the \p AA is
6335 /// AAGlobalValueInfo
6336 static bool classof(const AbstractAttribute *AA) {
6337 return (AA->getIdAddr() == &ID);
6338 }
6339
6340 /// Unique ID (due to the unique address)
6341 static const char ID;
6342};
6343
6344/// An abstract interface for indirect call information interference.
6346 : public StateWrapper<BooleanState, AbstractAttribute> {
6349
6350 /// See AbstractAttribute::isValidIRPositionForInit
6353 return false;
6354 auto *CB = cast<CallBase>(IRP.getCtxI());
6355 return CB->getOpcode() == Instruction::Call && CB->isIndirectCall() &&
6356 !CB->isMustTailCall();
6357 }
6358
6359 /// Create an abstract attribute view for the position \p IRP.
6361 Attributor &A);
6362
6363 /// Call \CB on each potential callee value and return true if all were known
6364 /// and \p CB returned true on all of them. Otherwise, return false.
6365 virtual bool foreachCallee(function_ref<bool(Function *)> CB) const = 0;
6366
6367 /// See AbstractAttribute::getName()
6368 const std::string getName() const override { return "AAIndirectCallInfo"; }
6369
6370 /// See AbstractAttribute::getIdAddr()
6371 const char *getIdAddr() const override { return &ID; }
6372
6373 /// This function should return true if the type of the \p AA is
6374 /// AAIndirectCallInfo
6375 /// This function should return true if the type of the \p AA is
6376 /// AADenormalFPMath.
6377 static bool classof(const AbstractAttribute *AA) {
6378 return (AA->getIdAddr() == &ID);
6379 }
6380
6381 /// Unique ID (due to the unique address)
6382 static const char ID;
6383};
6384
6385/// An abstract Attribute for specializing "dynamic" components of
6386/// "denormal-fp-math" and "denormal-fp-math-f32" to a known denormal mode.
6388 : public StateWrapper<DenormalFPMathState, AbstractAttribute> {
6390
6392
6393 /// Create an abstract attribute view for the position \p IRP.
6395 Attributor &A);
6396
6397 /// See AbstractAttribute::getName()
6398 const std::string getName() const override { return "AADenormalFPMath"; }
6399
6400 /// See AbstractAttribute::getIdAddr()
6401 const char *getIdAddr() const override { return &ID; }
6402
6403 /// This function should return true if the type of the \p AA is
6404 /// AADenormalFPMath.
6405 static bool classof(const AbstractAttribute *AA) {
6406 return (AA->getIdAddr() == &ID);
6407 }
6408
6409 /// Unique ID (due to the unique address)
6410 static const char ID;
6411};
6412
6414
6415/// Run options, used by the pass manager.
6417 NONE = 0,
6418 MODULE = 1 << 0,
6419 CGSCC = 1 << 1,
6420 ALL = MODULE | CGSCC
6422
6423namespace AA {
6424/// Helper to avoid creating an AA for IR Attributes that might already be set.
6425template <Attribute::AttrKind AK, typename AAType = AbstractAttribute>
6427 const IRPosition &IRP, DepClassTy DepClass, bool &IsKnown,
6428 bool IgnoreSubsumingPositions = false,
6429 const AAType **AAPtr = nullptr) {
6430 IsKnown = false;
6431 switch (AK) {
6432#define CASE(ATTRNAME, AANAME, ...) \
6433 case Attribute::ATTRNAME: { \
6434 if (AANAME::isImpliedByIR(A, IRP, AK, IgnoreSubsumingPositions)) \
6435 return IsKnown = true; \
6436 if (!QueryingAA) \
6437 return false; \
6438 const auto *AA = A.getAAFor<AANAME>(*QueryingAA, IRP, DepClass); \
6439 if (AAPtr) \
6440 *AAPtr = reinterpret_cast<const AAType *>(AA); \
6441 if (!AA || !AA->isAssumed(__VA_ARGS__)) \
6442 return false; \
6443 IsKnown = AA->isKnown(__VA_ARGS__); \
6444 return true; \
6445 }
6446 CASE(NoUnwind, AANoUnwind, );
6447 CASE(WillReturn, AAWillReturn, );
6448 CASE(NoFree, AANoFree, );
6449 CASE(NoCapture, AANoCapture, );
6450 CASE(NoRecurse, AANoRecurse, );
6451 CASE(NoReturn, AANoReturn, );
6452 CASE(NoSync, AANoSync, );
6453 CASE(NoAlias, AANoAlias, );
6454 CASE(NonNull, AANonNull, );
6455 CASE(MustProgress, AAMustProgress, );
6456 CASE(NoUndef, AANoUndef, );
6460#undef CASE
6461 default:
6462 llvm_unreachable("hasAssumedIRAttr not available for this attribute kind");
6463 };
6464}
6465} // namespace AA
6466
6467} // end namespace llvm
6468
6469#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:5443
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.
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:42
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:420
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:719
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:174
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:290
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:215
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:250
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:1833
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:694
LLVMContext & getContext() const
All values hold a context through their type.
Definition: Value.cpp:1075
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:6426
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:2072
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:58
bool operator!=(uint64_t V1, const APInt &V2)
Definition: APInt.h:2062
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:516
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:6416
@ MODULE
Definition: Attributor.h:6418
@ NONE
Definition: Attributor.h:6417
@ CGSCC
Definition: Attributor.h:6419
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:43
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:3455
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:2092
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:6228
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
Definition: Attributor.h:6255
static bool requiresCallersForArgOrFunction()
See AbstractAttribute::requiresCallersForArgOrFunction.
Definition: Attributor.h:6240
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAAssumptionInfo.
Definition: Attributor.h:6259
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
See AbstractAttribute::isValidIRPositionForInit.
Definition: Attributor.h:6233
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:6267
const std::string getName() const override
See AbstractAttribute::getName()
Definition: Attributor.h:6252
AAAddressSpace(const IRPosition &IRP, Attributor &A)
Definition: Attributor.h:6229
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:6264
An abstract interface for all align attributes.
Definition: Attributor.h:4263
AAAlign(const IRPosition &IRP, Attributor &A)
Definition: Attributor.h:4264
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:4294
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
Definition: Attributor.h:4283
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
See AbstractAttribute::isValidIRPositionForInit.
Definition: Attributor.h:4267
const std::string getName() const override
See AbstractAttribute::getName()
Definition: Attributor.h:4280
Align getAssumedAlign() const
Return assumed alignment.
Definition: Attributor.h:4274
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAAlign.
Definition: Attributor.h:4286
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:4277
static const char ID
Definition: Attributor.h:6302
virtual std::optional< TypeSize > getAllocatedSize() const =0
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
See AbstractAttribute::isValidIRPositionForInit.
Definition: Attributor.h:6275
const std::string getName() const override
See AbstractAttribute::getName()
Definition: Attributor.h:6288
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
Definition: Attributor.h:6291
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:6271
static constexpr const std::optional< TypeSize > HasNoAllocationSize
Definition: Attributor.h:6299
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAAllocationInfo.
Definition: Attributor.h:6295
An abstract attribute for getting assumption information.
Definition: Attributor.h:6154
AAAssumptionInfo(const IRPosition &IRP, Attributor &A, const DenseSet< StringRef > &Known)
Definition: Attributor.h:6158
const std::string getName() const override
See AbstractAttribute::getName()
Definition: Attributor.h:6170
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:6182
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:6173
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAAssumptionInfo.
Definition: Attributor.h:6177
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:5478
AACallEdges(const IRPosition &IRP, Attributor &A)
Definition: Attributor.h:5481
virtual const SetVector< Function * > & getOptimisticEdges() const =0
Get the optimistic edges.
static bool requiresNonAsmForCallBase()
See AbstractAttribute::requiresNonAsmForCallBase.
Definition: Attributor.h:5485
AACallEdgeIterator optimisticEdgesBegin() const override
Iterator for exploring the call graph.
Definition: Attributor.h:5497
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:5521
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:5502
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:5516
const std::string getName() const override
See AbstractAttribute::getName()
Definition: Attributor.h:5510
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
Definition: Attributor.h:5513
iterator_range< AACallEdgeIterator > optimisticEdgesRange() const
Iterator range for exploring the call graph.
Definition: Attributor.h:5464
virtual AACallEdgeIterator optimisticEdgesBegin() const =0
AACallGraphNode(Attributor &A)
Definition: Attributor.h:5457
virtual AACallEdgeIterator optimisticEdgesEnd() const =0
virtual ~AACallGraphNode()=default
Attributor & A
Reference to Attributor needed for GraphTraits implementation.
Definition: Attributor.h:5471
An abstract Attribute for specializing "dynamic" components of "denormal-fp-math" and "denormal-fp-ma...
Definition: Attributor.h:6388
const std::string getName() const override
See AbstractAttribute::getName()
Definition: Attributor.h:6398
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
Definition: Attributor.h:6401
AADenormalFPMath(const IRPosition &IRP, Attributor &A)
Definition: Attributor.h:6391
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:6410
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AADenormalFPMath.
Definition: Attributor.h:6405
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:4209
uint32_t getKnownDereferenceableBytes() const
Return known dereferenceable bytes.
Definition: Attributor.h:4233
const std::string getName() const override
See AbstractAttribute::getName()
Definition: Attributor.h:4242
bool isAssumedGlobal() const
Return true if we assume that underlying value is dereferenceable(_or_null) globally.
Definition: Attributor.h:4221
bool isKnownGlobal() const
Return true if we know that underlying value is dereferenceable(_or_null) globally.
Definition: Attributor.h:4225
AADereferenceable(const IRPosition &IRP, Attributor &A)
Definition: Attributor.h:4210
uint32_t getAssumedDereferenceableBytes() const
Return assumed dereferenceable bytes.
Definition: Attributor.h:4228
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:4254
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AADereferenceable.
Definition: Attributor.h:4249
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
Definition: Attributor.h:4245
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
See AbstractAttribute::isValidIRPositionForInit.
Definition: Attributor.h:4213
Summary about the execution domain of a block or instruction.
Definition: Attributor.h:5602
void addAssumeInst(Attributor &A, AssumeInst &AI)
Definition: Attributor.h:5606
void addAlignedBarrier(Attributor &A, CallBase &CB)
Definition: Attributor.h:5610
const std::string getName() const override
See AbstractAttribute::getName().
Definition: Attributor.h:5632
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:5638
static AAExecutionDomain & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
Definition: OpenMPOpt.cpp:5630
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAExecutionDomain.
Definition: Attributor.h:5664
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr().
Definition: Attributor.h:5635
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:5599
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:5669
An abstract interface for llvm::GlobalValue information interference.
Definition: Attributor.h:6307
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:6336
AAGlobalValueInfo(const IRPosition &IRP, Attributor &A)
Definition: Attributor.h:6308
const std::string getName() const override
See AbstractAttribute::getName()
Definition: Attributor.h:6329
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
See AbstractAttribute::isValidIRPositionForInit.
Definition: Attributor.h:6312
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
Definition: Attributor.h:6332
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:6341
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:4545
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
Definition: Attributor.h:4548
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAHeapToStack.
Definition: Attributor.h:4551
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:4556
AAHeapToStack(const IRPosition &IRP, Attributor &A)
Definition: Attributor.h:4532
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:6346
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:6368
AAIndirectCallInfo(const IRPosition &IRP, Attributor &A)
Definition: Attributor.h:6347
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
Definition: Attributor.h:6371
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:6377
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:6382
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
See AbstractAttribute::isValidIRPositionForInit.
Definition: Attributor.h:6351
An abstract interface to track if a value leaves it's defining function instance.
Definition: Attributor.h:4301
const std::string getName() const override
See AbstractAttribute::getName()
Definition: Attributor.h:4322
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:4334
bool isKnownUniqueForAnalysis() const
Return true if we know that the underlying value is unique in its scope wrt.
Definition: Attributor.h:4309
AAInstanceInfo(const IRPosition &IRP, Attributor &A)
Definition: Attributor.h:4302
bool isAssumedUniqueForAnalysis() const
Return true if we assume that the underlying value is unique in its scope wrt.
Definition: Attributor.h:4315
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:4329
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
Definition: Attributor.h:4325
An abstract Attribute for computing reachability between functions.
Definition: Attributor.h:5674
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AACallEdges.
Definition: Attributor.h:5704
const std::string getName() const override
See AbstractAttribute::getName()
Definition: Attributor.h:5698
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:5709
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
Definition: Attributor.h:5701
bool canReach(Attributor &A, const Function &Fn) const
If the function represented by this possition can reach Fn.
Definition: Attributor.h:5680
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:5677
An abstract interface to determine reachability of point A to B.
Definition: Attributor.h:3807
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAIntraFnReachability.
Definition: Attributor.h:3830
AAIntraFnReachability(const IRPosition &IRP, Attributor &A)
Definition: Attributor.h:3809
const std::string getName() const override
See AbstractAttribute::getName()
Definition: Attributor.h:3823
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:3835
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
Definition: Attributor.h:3826
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:3967
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:4052
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:4057
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:4015
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:4041
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:3972
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:4011
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:4049
const std::string getName() const override
See AbstractAttribute::getName()
Definition: Attributor.h:4046
static bool mayCatchAsynchronousExceptions(const Function &F)
Determine if F might catch asynchronous exceptions.
Definition: Attributor.h:4032
AAIsDead(const IRPosition &IRP, Attributor &A)
Definition: Attributor.h:3969
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:4621
bool isAssumedReadOnly() const
Return true if we assume that the underlying value is not accessed (=written) in its respective scope...
Definition: Attributor.h:4660
static bool hasTrivialInitializer()
See AbstractAttribute::hasTrivialInitializer.
Definition: Attributor.h:4625
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAMemoryBehavior.
Definition: Attributor.h:4682
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
See AbstractAttribute::isValidIRPositionForInit.
Definition: Attributor.h:4628
const std::string getName() const override
See AbstractAttribute::getName()
Definition: Attributor.h:4675
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:4648
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:4687
bool isKnownWriteOnly() const
Return true if we know that the underlying value is not read in its respective scope.
Definition: Attributor.h:4664
bool isAssumedReadNone() const
Return true if we assume that the underlying value is not read or accessed in its respective scope.
Definition: Attributor.h:4652
bool isAssumedWriteOnly() const
Return true if we assume that the underlying value is not read in its respective scope.
Definition: Attributor.h:4668
AAMemoryBehavior(const IRPosition &IRP, Attributor &A)
Definition: Attributor.h:4622
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
Definition: Attributor.h:4678
bool isKnownReadOnly() const
Return true if we know that the underlying value is not accessed (=written) in its respective scope.
Definition: Attributor.h:4656
An abstract interface for all memory location attributes (readnone/argmemonly/inaccessiblememonly/ina...
Definition: Attributor.h:4696
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
Definition: Attributor.h:4863
bool isAssumedStackOnly() const
Return true if we assume that the associated functions has at most local/stack accesses.
Definition: Attributor.h:4757
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:4775
bool isKnownInaccessibleOrArgMemOnly() const
Return true if we know that the underlying value will only access inaccesible memory or argument poin...
Definition: Attributor.h:4788
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:4872
AAMemoryLocation(const IRPosition &IRP, Attributor &A)
Definition: Attributor.h:4699
bool isKnownReadNone() const
Return true if we know that the associated functions has no observable accesses.
Definition: Attributor.h:4741
const std::string getName() const override
See AbstractAttribute::getName()
Definition: Attributor.h:4860
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:4807
bool isAssumedInaccessibleMemOnly() const
Return true if we assume that the underlying value will only access inaccesible memory only (see Attr...
Definition: Attributor.h:4769
bool isKnownInaccessibleMemOnly() const
Return true if we know that the underlying value will only access inaccesible memory only (see Attrib...
Definition: Attributor.h:4763
bool isAssumedInaccessibleOrArgMemOnly() const
Return true if we assume that the underlying value will only access inaccesible memory or argument po...
Definition: Attributor.h:4796
bool isKnowStackOnly() const
Return true if we know that the associated functions has at most local/stack accesses.
Definition: Attributor.h:4751
static bool requiresCalleeForCallBase()
See AbstractAttribute::requiresCalleeForCallBase.
Definition: Attributor.h:4702
AccessKind
Simple enum to distinguish read/write/read-write accesses.
Definition: Attributor.h:4832
StateType::base_t MemoryLocationsKind
Definition: Attributor.h:4697
MemoryLocationsKind getAssumedNotAccessedLocation() const
Return the locations that are assumed to be not accessed by the associated function,...
Definition: Attributor.h:4813
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAMemoryLocation.
Definition: Attributor.h:4867
static bool hasTrivialInitializer()
See AbstractAttribute::hasTrivialInitializer.
Definition: Attributor.h:4705
bool isAssumedReadNone() const
Return true if we assume that the associated functions has no observable accesses.
Definition: Attributor.h:4745
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
See AbstractAttribute::isValidIRPositionForInit.
Definition: Attributor.h:4708
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:4855
bool mayAccessArgMem() const
Return true if the underlying value may access memory through arguement pointers of the associated fu...
Definition: Attributor.h:4803
bool isAssumedArgMemOnly() const
Return true if we assume that the underlying value will only access argument pointees (see Attribute:...
Definition: Attributor.h:4781
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:4823
An abstract interface for all nonnull attributes.
Definition: Attributor.h:3583
bool isKnownMustProgress() const
Return true if we know that underlying value is nonnull.
Definition: Attributor.h:3599
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAMustProgress.
Definition: Attributor.h:3613
bool isAssumedMustProgress() const
Return true if we assume that the underlying value is nonnull.
Definition: Attributor.h:3596
static bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
Definition: Attributor.h:3586
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
Definition: Attributor.h:3609
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:3618
const std::string getName() const override
See AbstractAttribute::getName()
Definition: Attributor.h:3606
AAMustProgress(const IRPosition &IRP, Attributor &A)
Definition: Attributor.h:3584
An abstract interface for all noalias attributes.
Definition: Attributor.h:3842
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:3876
static bool requiresCallersForArgOrFunction()
See AbstractAttribute::requiresCallersForArgOrFunction.
Definition: Attributor.h:3858
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
Definition: Attributor.h:3873
bool isKnownNoAlias() const
Return true if we know that underlying value is noalias.
Definition: Attributor.h:3864
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:3881
bool isAssumedNoAlias() const
Return true if we assume that the underlying value is alias.
Definition: Attributor.h:3861
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:3870
AANoAlias(const IRPosition &IRP, Attributor &A)
Definition: Attributor.h:3843
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
See AbstractAttribute::isValidIRPositionForInit.
Definition: Attributor.h:3846
An abstract interface for all nocapture attributes.
Definition: Attributor.h:4342
@ 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:4372
@ 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:4376
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
See AbstractAttribute::isValidIRPositionForInit.
Definition: Attributor.h:4357
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
Definition: Attributor.h:4407
AANoCapture(const IRPosition &IRP, Attributor &A)
Definition: Attributor.h:4343
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:4404
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:4415
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:4396
bool isKnownNoCapture() const
Return true if we know that the underlying value is not captured in its respective scope.
Definition: Attributor.h:4382
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AANoCapture.
Definition: Attributor.h:4410
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:4390
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:4386
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:5409
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
See AbstractAttribute::isValidIRPositionForInit.
Definition: Attributor.h:5396
AANoFPClass(const IRPosition &IRP, Attributor &A)
Definition: Attributor.h:5393
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:5427
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:5432
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
Definition: Attributor.h:5424
const std::string getName() const override
See AbstractAttribute::getName()
Definition: Attributor.h:5421
FPClassTest getKnownNoFPClass() const
Return the underlying known nofpclass.
Definition: Attributor.h:5413
An AbstractAttribute for nofree.
Definition: Attributor.h:3888
bool isKnownNoFree() const
Return true if "nofree" is known.
Definition: Attributor.h:3914
AANoFree(const IRPosition &IRP, Attributor &A)
Definition: Attributor.h:3889
static bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
See IRAttribute::isImpliedByIR.
Definition: Attributor.h:3892
bool isAssumedNoFree() const
Return true if "nofree" is assumed.
Definition: Attributor.h:3911
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:3931
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
See AbstractAttribute::isValidIRPositionForInit.
Definition: Attributor.h:3903
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AANoFree.
Definition: Attributor.h:3926
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:3923
const std::string getName() const override
See AbstractAttribute::getName()
Definition: Attributor.h:3920
An abstract attribute for norecurse.
Definition: Attributor.h:3676
const std::string getName() const override
See AbstractAttribute::getName()
Definition: Attributor.h:3689
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AANoRecurse.
Definition: Attributor.h:3695
AANoRecurse(const IRPosition &IRP, Attributor &A)
Definition: Attributor.h:3677
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
Definition: Attributor.h:3692
bool isAssumedNoRecurse() const
Return true if "norecurse" is assumed.
Definition: Attributor.h:3680
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:3683
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:3700
An AbstractAttribute for noreturn.
Definition: Attributor.h:3938
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AANoReturn.
Definition: Attributor.h:3957
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:3962
bool isAssumedNoReturn() const
Return true if the underlying object is assumed to never return.
Definition: Attributor.h:3942
const std::string getName() const override
See AbstractAttribute::getName()
Definition: Attributor.h:3951
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:3939
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
Definition: Attributor.h:3954
bool isKnownNoReturn() const
Return true if the underlying object is known to never return.
Definition: Attributor.h:3945
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
See AbstractAttribute::isValidIRPositionForInit.
Definition: Attributor.h:3533
AANoSync(const IRPosition &IRP, Attributor &A)
Definition: Attributor.h:3500
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
Definition: Attributor.h:3568
static bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
Definition: Attributor.h:3502
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:3576
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:3541
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:3544
const std::string getName() const override
See AbstractAttribute::getName()
Definition: Attributor.h:3565
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:3571
An abstract interface for all noundef attributes.
Definition: Attributor.h:5346
bool isKnownNoUndef() const
Return true if we know that underlying value is noundef.
Definition: Attributor.h:5364
static bool isImpliedByUndef()
See IRAttribute::isImpliedByUndef.
Definition: Attributor.h:5350
bool isAssumedNoUndef() const
Return true if we assume that the underlying value is noundef.
Definition: Attributor.h:5361
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AANoUndef.
Definition: Attributor.h:5376
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:5373
AANoUndef(const IRPosition &IRP, Attributor &A)
Definition: Attributor.h:5347
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:5381
static bool isImpliedByPoison()
See IRAttribute::isImpliedByPoison.
Definition: Attributor.h:5353
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:5370
const std::string getName() const override
See AbstractAttribute::getName()
Definition: Attributor.h:3482
AANoUnwind(const IRPosition &IRP, Attributor &A)
Definition: Attributor.h:3470
bool isAssumedNoUnwind() const
Returns true if nounwind is assumed.
Definition: Attributor.h:3473
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AANoUnwind.
Definition: Attributor.h:3488
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:3493
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:3476
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
Definition: Attributor.h:3485
An abstract Attribute for determining the necessity of the convergent attribute.
Definition: Attributor.h:5714
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:5742
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
Definition: Attributor.h:5733
const std::string getName() const override
See AbstractAttribute::getName()
Definition: Attributor.h:5730
bool isAssumedNotConvergent() const
Return true if "non-convergent" is assumed.
Definition: Attributor.h:5724
bool isKnownNotConvergent() const
Return true if "non-convergent" is known.
Definition: Attributor.h:5727
AANonConvergent(const IRPosition &IRP, Attributor &A)
Definition: Attributor.h:5717
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:5737
An abstract interface for all nonnull attributes.
Definition: Attributor.h:3625
static bool isImpliedByUndef()
See IRAttribute::isImpliedByUndef.
Definition: Attributor.h:3634
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:3637
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:3669
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
Definition: Attributor.h:3661
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AANonNull.
Definition: Attributor.h:3664
const std::string getName() const override
See AbstractAttribute::getName()
Definition: Attributor.h:3658
AANonNull(const IRPosition &IRP, Attributor &A)
Definition: Attributor.h:3626
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:3649
bool isKnownNonNull() const
Return true if we know that underlying value is nonnull.
Definition: Attributor.h:3652
static bool hasTrivialInitializer()
See AbstractAttribute::hasTrivialInitializer.
Definition: Attributor.h:3629
An access description.
Definition: Attributor.h:5932
bool isWrittenValueUnknown() const
Return true if the value written cannot be determined at all.
Definition: Attributor.h:6038
const_iterator end() const
Definition: Attributor.h:6077
bool operator!=(const Access &R) const
Definition: Attributor.h:5963
std::optional< Value * > getContent() const
Return the written value which can be llvm::null if it is not yet determined.
Definition: Attributor.h:6057
Access & operator=(const Access &Other)=default
bool isAssumption() const
Return true if this is an assumption access.
Definition: Attributor.h:6011
void setWrittenValueUnknown()
Set the value written to nullptr, i.e., unknown.
Definition: Attributor.h:6043
const RangeList & getRanges() const
Definition: Attributor.h:6073
bool isWriteOrAssumption() const
Return true if this is a write access.
Definition: Attributor.h:6008
bool isRead() const
Return true if this is a read access.
Definition: Attributor.h:6002
bool isWrite() const
Return true if this is a write access.
Definition: Attributor.h:6005
Value * getWrittenValue() const
Return the value writen, if any.
Definition: Attributor.h:6049
Instruction * getLocalInst() const
Return the instruction that causes the access with respect to the local scope of the associated attri...
Definition: Attributor.h:6029
Access(Instruction *LocalI, Instruction *RemoteI, const RangeList &Ranges, std::optional< Value * > Content, AccessKind K, Type *Ty)
Definition: Attributor.h:5939
Access(Instruction *LocalI, Instruction *RemoteI, int64_t Offset, int64_t Size, std::optional< Value * > Content, AccessKind Kind, Type *Ty)
Definition: Attributor.h:5949
Access(Instruction *I, int64_t Offset, int64_t Size, std::optional< Value * > Content, AccessKind Kind, Type *Ty)
Definition: Attributor.h:5933
Access(const Access &Other)=default
Type * getType() const
Return the type associated with the access, if known.
Definition: Attributor.h:6046
Access & operator&=(const Access &R)
Definition: Attributor.h:5965
const_iterator begin() const
Definition: Attributor.h:6076
void addRange(int64_t Offset, int64_t Size)
Add a range accessed by this Access.
Definition: Attributor.h:6065
Instruction * getRemoteInst() const
Return the actual instruction that causes the access.
Definition: Attributor.h:6032
const AA::RangeTy & getUniqueRange() const
Definition: Attributor.h:6060
bool operator==(const Access &R) const
Definition: Attributor.h:5959
bool isWrittenValueYetUndetermined() const
Return true if the value written is not known yet.
Definition: Attributor.h:6035
AccessKind getKind() const
Return the access kind.
Definition: Attributor.h:5999
A container for a list of ranges.
Definition: Attributor.h:5781
const_iterator end() const
Definition: Attributor.h:5806
void addToAllOffsets(int64_t Inc)
Add the increment Inc to the offset of every range.
Definition: Attributor.h:5888
bool operator==(const RangeList &OI) const
Definition: Attributor.h:5825
RangeList(ArrayRef< int64_t > Offsets, int64_t Size)
Definition: Attributor.h:5793
bool isUnique() const
Return true iff there is exactly one range and it is known.
Definition: Attributor.h:5899
std::pair< iterator, bool > insert(iterator Pos, const RangeTy &R)
Insert R at the given iterator Pos, and merge if necessary.
Definition: Attributor.h:5862
RangeList(const RangeTy &R)
Definition: Attributor.h:5792
bool isUnknown() const
Return true iff the list contains an unknown range.
Definition: Attributor.h:5910
VecTy::const_iterator const_iterator
Definition: Attributor.h:5789
const_iterator begin() const
Definition: Attributor.h:5805
bool isUnassigned() const
Return true if no ranges have been inserted.
Definition: Attributor.h:5928
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:5817
const RangeTy & getUnique() const
Return the unique range, assuming it exists.
Definition: Attributor.h:5904
bool merge(const RangeList &RHS)
Merge the ranges in RHS into the current ranges.
Definition: Attributor.h:5831
std::pair< iterator, bool > insert(const RangeTy &R)
Insert the given range R, maintaining sorted order.
Definition: Attributor.h:5883
iterator setUnknown()
Discard all ranges and insert a single unknown range.
Definition: Attributor.h:5921
void push_back(const RangeTy &R)
Definition: Attributor.h:5810
An abstract interface for struct information.
Definition: Attributor.h:5746
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
See AbstractAttribute::isValidIRPositionForInit.
Definition: Attributor.h:5750
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:6141
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
Definition: Attributor.h:6109
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:6106
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:6146
AAPointerInfo(const IRPosition &IRP)
Definition: Attributor.h:5747
virtual int64_t numOffsetBins() const =0
An abstract interface for potential values analysis.
Definition: Attributor.h:5236
PotentialConstantIntValuesState & getState() override
See AbstractAttribute::getState(...).
Definition: Attributor.h:5251
const PotentialConstantIntValuesState & getState() const override
Definition: Attributor.h:5252
AAPotentialConstantValues(const IRPosition &IRP, Attributor &A)
Definition: Attributor.h:5238
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:5295
const std::string getName() const override
See AbstractAttribute::getName()
Definition: Attributor.h:5281
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:5290
static bool requiresCallersForArgOrFunction()
See AbstractAttribute::requiresCallersForArgOrFunction.
Definition: Attributor.h:5248
std::optional< Constant * > getAssumedConstant(Attributor &A, const Instruction *CtxI=nullptr) const
Return assumed constant for the associated value.
Definition: Attributor.h:5262
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
Definition: Attributor.h:5286
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
See AbstractAttribute::isValidIRPositionForInit.
Definition: Attributor.h:5241
const std::string getName() const override
See AbstractAttribute::getName()
Definition: Attributor.h:5320
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAPotentialValues.
Definition: Attributor.h:5327
PotentialLLVMValuesState & getState() override
See AbstractAttribute::getState(...).
Definition: Attributor.h:5307
AAPotentialValues(const IRPosition &IRP, Attributor &A)
Definition: Attributor.h:5301
static bool requiresCallersForArgOrFunction()
See AbstractAttribute::requiresCallersForArgOrFunction.
Definition: Attributor.h:5304
const PotentialLLVMValuesState & getState() const override
Definition: Attributor.h:5308
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
Definition: Attributor.h:5323
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:5332
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:4570
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
See AbstractAttribute::isValidIRPositionForInit.
Definition: Attributor.h:4575
bool isAssumedPrivatizablePtr() const
Returns true if pointer privatization is assumed to be possible.
Definition: Attributor.h:4582
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:4612
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAPricatizablePtr.
Definition: Attributor.h:4607
const std::string getName() const override
See AbstractAttribute::getName()
Definition: Attributor.h:4600
static bool requiresCallersForArgOrFunction()
See AbstractAttribute::requiresCallersForArgOrFunction.
Definition: Attributor.h:4588
AAPrivatizablePtr(const IRPosition &IRP, Attributor &A)
Definition: Attributor.h:4572
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
Definition: Attributor.h:4603
bool isKnownPrivatizablePtr() const
Returns true if pointer privatization is known to be possible.
Definition: Attributor.h:4585
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:3769
bool isKnownToCauseUB() const
Return true if "undefined behavior" is known.
Definition: Attributor.h:3780
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
Definition: Attributor.h:3793
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:3802
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:3771
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAUndefineBehavior.
Definition: Attributor.h:3797
bool isAssumedToCauseUB() const
Return true if "undefined behavior" is assumed.
Definition: Attributor.h:3774
const std::string getName() const override
See AbstractAttribute::getName()
Definition: Attributor.h:3790
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:6186
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
See AbstractAttribute::isValidIRPositionForInit.
Definition: Attributor.h:6190
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:6204
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
Definition: Attributor.h:6207
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAUnderlyingObjects.
Definition: Attributor.h:6211
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:6216
static AAUnderlyingObjects & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute biew for the position IRP.
AAUnderlyingObjects(const IRPosition &IRP)
Definition: Attributor.h:6187
static bool requiresCallersForArgOrFunction()
See AbstractAttribute::requiresCallersForArgOrFunction.
Definition: Attributor.h:6197
An abstract interface for range value analysis.
Definition: Attributor.h:4877
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
See AbstractAttribute::isValidIRPositionForInit.
Definition: Attributor.h:4883
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:4915
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:4940
static bool requiresCallersForArgOrFunction()
See AbstractAttribute::requiresCallersForArgOrFunction.
Definition: Attributor.h:4890
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAValueConstantRange.
Definition: Attributor.h:4935
AAValueConstantRange(const IRPosition &IRP, Attributor &A)
Definition: Attributor.h:4879
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
Definition: Attributor.h:4931
const std::string getName() const override
See AbstractAttribute::getName()
Definition: Attributor.h:4928
IntegerRangeState & getState() override
See AbstractAttribute::getState(...).
Definition: Attributor.h:4893
const IntegerRangeState & getState() const override
Definition: Attributor.h:4894
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:4494
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAValueSimplify.
Definition: Attributor.h:4511
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:4504
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:4516
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
Definition: Attributor.h:4507
AAValueSimplify(const IRPosition &IRP, Attributor &A)
Definition: Attributor.h:4496
An abstract attribute for willreturn.
Definition: Attributor.h:3707
bool isKnownWillReturn() const
Return true if "willreturn" is known.
Definition: Attributor.h:3747
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
Definition: Attributor.h:3756
static const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:3764
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:3759
const std::string getName() const override
See AbstractAttribute::getName()
Definition: Attributor.h:3753
AAWillReturn(const IRPosition &IRP, Attributor &A)
Definition: Attributor.h:3708
static bool isImpliedByMustprogressAndReadonly(Attributor &A, const IRPosition &IRP)
Check for mustprogress and readonly as they imply willreturn.
Definition: Attributor.h:3726
static bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
Definition: Attributor.h:3710
bool isAssumedWillReturn() const
Return true if "willreturn" is assumed.
Definition: Attributor.h:3744
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:3275
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:3310
virtual ChangeStatus manifest(Attributor &A)
Hook for the Attributor to trigger the manifestation of the information represented by the abstract a...
Definition: Attributor.h:3390
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:3292
static bool requiresCalleeForCallBase()
Return true if this AA requires a "callee" (or an associted function) for a call site positon.
Definition: Attributor.h:3300
void print(raw_ostream &OS) const
Helper functions, for debug purposes only.
Definition: Attributor.h:3359
IRPosition & getIRPosition()
Definition: Attributor.h:3355
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:3339
static bool isValidIRPositionForUpdate(Attributor &A, const IRPosition &IRP)
Return false if an AA should not be updated for IRP.
Definition: Attributor.h:3315
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:3284
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:3347
virtual const StateType & getState() const =0
AbstractAttribute(const IRPosition &IRP)
Definition: Attributor.h:3278
static bool requiresNonAsmForCallBase()
Return true if this AA requires non-asm "callee" for a call site positon.
Definition: Attributor.h:3303
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:3307
const IRPosition & getIRPosition() const
Return an IR position, see struct IRPosition.
Definition: Attributor.h:3354
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:3296
An interface to query the internal state of an abstract attribute.
Definition: Attributor.h:2595
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:5533
AttributorCallGraph(Attributor &A)
Definition: Attributor.h:5526
AACallEdgeIterator optimisticEdgesBegin() const override
Definition: Attributor.h:5529
virtual ~AttributorCallGraph()=default
void populateAll() const
Force populate the entire call graph.
Definition: Attributor.h:5538
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:3446
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:3439
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:2203
std::function< void(const ArgumentReplacementInfo &, AbstractCallSite, SmallVectorImpl< Value * > &)> ACSRepairCBTy
Abstract call site (ACS) repair callback type.
Definition: Attributor.h:2226
const SmallVectorImpl< Type * > & getReplacementTypes() const
Definition: Attributor.h:2235
const Argument & getReplacedArg() const
Definition: Attributor.h:2233
Attributor & getAttributor() const
Simple getters, see the corresponding members for details.
Definition: Attributor.h:2231
std::function< void(const ArgumentReplacementInfo &, Function &, Function::arg_iterator)> CalleeRepairCBTy
Callee repair callback type.
Definition: Attributor.h:2212
const Function & getReplacedFn() const
Definition: Attributor.h:2232
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:1875
void registerSimplificationCallback(const IRPosition &IRP, const SimplifictionCallbackTy &CB)
Definition: Attributor.h:2009
bool changeAfterManifest(const IRPosition IRP, Value &NV, bool ChangeDroppable=true)
Helper function to replace all uses associated with IRP with NV.
Definition: Attributor.h:1847
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:2159
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:2040
void deleteAfterManifest(Function &F)
Record that F is deleted after information was manifested.
Definition: Attributor.h:1894
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:1966
void emitRemark(Function *F, StringRef RemarkName, RemarkCallBack &&RemarkCB) const
Emit a remark on a function.
Definition: Attributor.h:2180
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:2439
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:1868
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:2032
std::function< std::optional< Constant * >(const GlobalVariable &, const AbstractAttribute *, bool &)> GlobalVariableSimplifictionCallbackTy
Register CB as a simplification callback.
Definition: Attributor.h:2024
std::optional< Constant * > getAssumedConstant(const Value &V, const AbstractAttribute &AA, bool &UsedAssumedInformation)
Definition: Attributor.h:1958
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:2015
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:2025
const DataLayout & getDataLayout() const
Return the data layout associated with the anchor scope.
Definition: Attributor.h:2434
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:1833
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:1889
void registerVirtualUseCallback(const Value &V, const VirtualUseCallbackTy &CB)
Definition: Attributor.h:2055
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:1881
void deleteAfterManifest(BasicBlock &BB)
Record that BB is deleted after information was manifested.
Definition: Attributor.h:1885
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:2437
std::function< bool(Attributor &, const AbstractAttribute *)> VirtualUseCallbackTy
Definition: Attributor.h:2054
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:2361
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:1972
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:2008
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:2736
BitIntegerState & removeKnownBits(base_t BitsEncoding)
Remove the bits in BitsEncoding from the "known bits".
Definition: Attributor.h:2766
bool isAssumed(base_t BitsEncoding=BestState) const
Return true if the bits set in BitsEncoding are "assumed bits".
Definition: Attributor.h:2748
BitIntegerState(base_t Assumed)
Definition: Attributor.h:2740
BitIntegerState & removeAssumedBits(base_t BitsEncoding)
Remove the bits in BitsEncoding from the "assumed bits" if not known.
Definition: Attributor.h:2761
BitIntegerState & intersectAssumedBits(base_t BitsEncoding)
Keep only "assumed bits" also set in BitsEncoding but all known ones.
Definition: Attributor.h:2772
bool isKnown(base_t BitsEncoding=BestState) const
Return true if the bits set in BitsEncoding are "known bits".
Definition: Attributor.h:2743
BitIntegerState & addKnownBits(base_t Bits)
Add the bits in BitsEncoding to the "known bits".
Definition: Attributor.h:2753
Simple wrapper for a single bit (boolean) state.
Definition: Attributor.h:2879
bool isKnown() const
Return true if the state is known to hold.
Definition: Attributor.h:2899
void setKnown(bool Value)
Set the known and asssumed value to Value.
Definition: Attributor.h:2890
IntegerStateBase::base_t base_t
Definition: Attributor.h:2881
BooleanState(base_t Assumed)
Definition: Attributor.h:2884
void setAssumed(bool Value)
Set the assumed value to Value but never below the known one.
Definition: Attributor.h:2887
BooleanState()=default
bool isAssumed() const
Return true if the state is assumed to hold.
Definition: Attributor.h:2896
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:5589
std::string getNodeLabel(const AACallGraphNode *Node, const AttributorCallGraph *Graph)
Definition: Attributor.h:5583
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:2845
DecIntegerState & takeKnownMinimum(base_t Value)
Take minimum of known and Value.
Definition: Attributor.h:2856
DecIntegerState & takeAssumedMaximum(base_t Value)
Take maximum of assumed and Value.
Definition: Attributor.h:2849
DefaultDOTGraphTraits - This class provides the default implementations of all of the DOTGraphTraits ...
static DenormalMode unionAssumed(DenormalMode Callee, DenormalMode Caller)
Definition: Attributor.h:5153
DenormalState unionWith(DenormalState Caller) const
Definition: Attributor.h:5158
bool operator!=(const DenormalState Other) const
Definition: Attributor.h:5135
bool operator==(const DenormalState Other) const
Definition: Attributor.h:5131
static DenormalMode::DenormalModeKind unionDenormalKind(DenormalMode::DenormalModeKind Callee, DenormalMode::DenormalModeKind Caller)
Definition: Attributor.h:5142
bool IsAtFixedpoint
Explicitly track whether we've hit a fixed point.
Definition: Attributor.h:5169
ChangeStatus indicateOptimisticFixpoint() override
Indicate that the abstract state should converge to the optimistic state.
Definition: Attributor.h:5198
DenormalState getKnown() const
Definition: Attributor.h:5173
DenormalState getAssumed() const
Definition: Attributor.h:5177
bool isValidState() const override
Return if this abstract state is in a valid state.
Definition: Attributor.h:5179
ChangeStatus indicatePessimisticFixpoint() override
Indicate that the abstract state should converge to the pessimistic state.
Definition: Attributor.h:5202
DenormalFPMathState operator^=(const DenormalFPMathState &Caller)
Definition: Attributor.h:5206
ChangeStatus indicateFixpoint()
Definition: Attributor.h:5192
bool isModeFixed() const
Return true if there are no dynamic components to the denormal mode worth specializing.
Definition: Attributor.h:5183
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:5190
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:4063
IncIntegerState DerefBytesState
State representing for dereferenceable bytes.
Definition: Attributor.h:4079
static DerefState getBestState(const DerefState &)
Definition: Attributor.h:4066
static DerefState getWorstState()
Return the worst possible representable state.
Definition: Attributor.h:4069
static DerefState getBestState()
Definition: Attributor.h:4065
static DerefState getWorstState(const DerefState &)
Definition: Attributor.h:4074
std::map< int64_t, uint64_t > AccessedBytesMap
Map representing for accessed memory offsets and sizes.
Definition: Attributor.h:4087
static AACallEdgeIterator child_end(AACallGraphNode *Node)
Definition: Attributor.h:5556
static AACallEdgeIterator child_begin(AACallGraphNode *Node)
Definition: Attributor.h:5552
static AACallGraphNode * getEntryNode(AttributorCallGraph *G)
Definition: Attributor.h:5566
static AACallEdgeIterator nodes_begin(const AttributorCallGraph *G)
Definition: Attributor.h:5570
static AACallEdgeIterator nodes_end(const AttributorCallGraph *G)
Definition: Attributor.h:5574
Helper class that provides common functionality to manifest IR attributes.
Definition: Attributor.h:3180
Attribute::AttrKind getAttrKind() const
Return the kind that identifies the abstract attribute implementation.
Definition: Attributor.h:3223
static constexpr Attribute::AttrKind IRAttributeKind
Compile time access to the IR attribute kind.
Definition: Attributor.h:3189
static bool hasTrivialInitializer()
Most boolean IRAttribute AAs don't do anything non-trivial in their initializers while non-boolean on...
Definition: Attributor.h:3186
static bool isImpliedByUndef()
Return true if the IR attribute(s) associated with this AA are implied for an undef value.
Definition: Attributor.h:3193
ChangeStatus manifest(Attributor &A) override
See AbstractAttribute::manifest(...).
Definition: Attributor.h:3212
static bool isImpliedByPoison()
Return true if the IR attribute(s) associated with this AA are implied for an poison value.
Definition: Attributor.h:3197
static bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind=AK, bool IgnoreSubsumingPositions=false)
Definition: Attributor.h:3199
IRAttribute(const IRPosition &IRP)
Definition: Attributor.h:3181
virtual void getDeducedAttributes(Attributor &A, LLVMContext &Ctx, SmallVectorImpl< Attribute > &Attrs) const
Return the deduced attributes in Attrs.
Definition: Attributor.h:3226
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:2798
static constexpr base_t getBestState(const IncIntegerState< base_ty, BestState, WorstState > &)
Definition: Attributor.h:2808
IncIntegerState(base_t Assumed)
Definition: Attributor.h:2803
static constexpr base_t getBestState()
Return the best possible representable state.
Definition: Attributor.h:2806
IncIntegerState & takeAssumedMinimum(base_t Value)
Take minimum of assumed and Value.
Definition: Attributor.h:2813
IncIntegerState & takeKnownMaximum(base_t Value)
Take maximum of known and Value.
Definition: Attributor.h:2820
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:2921
IntegerRangeState operator^=(const IntegerRangeState &R)
"Clamp" this state with R.
Definition: Attributor.h:3012
IntegerRangeState operator&=(const IntegerRangeState &R)
Definition: Attributor.h:3019
bool isAtFixpoint() const override
See AbstractState::isAtFixpoint()
Definition: Attributor.h:2962
void unionAssumed(const IntegerRangeState &R)
See IntegerRangeState::unionAssumed(..).
Definition: Attributor.h:2989
ConstantRange Assumed
State representing assumed range, initially set to empty.
Definition: Attributor.h:2927
IntegerRangeState(const ConstantRange &CR)
Definition: Attributor.h:2936
IntegerRangeState(uint32_t BitWidth)
Definition: Attributor.h:2932
bool operator==(const IntegerRangeState &R) const
Equality for IntegerRangeState.
Definition: Attributor.h:3005
void intersectKnown(const IntegerRangeState &R)
See IntegerRangeState::intersectKnown(..).
Definition: Attributor.h:3000
static ConstantRange getBestState(const IntegerRangeState &IRS)
Definition: Attributor.h:2949
bool isValidState() const override
See AbstractState::isValidState()
Definition: Attributor.h:2957
uint32_t BitWidth
Bitwidth of the associated value.
Definition: Attributor.h:2924
ConstantRange Known
State representing known range, initially set to [-inf, inf].
Definition: Attributor.h:2930
void unionAssumed(const ConstantRange &R)
Unite assumed range with the passed state.
Definition: Attributor.h:2983
ChangeStatus indicatePessimisticFixpoint() override
See AbstractState::indicatePessimisticFixpoint(...)
Definition: Attributor.h:2971
ConstantRange getKnown() const
Return the known state encoding.
Definition: Attributor.h:2977
void intersectKnown(const ConstantRange &R)
Intersect known range with the passed state.
Definition: Attributor.h:2994
ConstantRange getAssumed() const
Return the assumed state encoding.
Definition: Attributor.h:2980
uint32_t getBitWidth() const
Return associated values' bit width.
Definition: Attributor.h:2954
ChangeStatus indicateOptimisticFixpoint() override
See AbstractState::indicateOptimisticFixpoint(...)
Definition: Attributor.h:2965
static ConstantRange getWorstState(uint32_t BitWidth)
Return the worst possible representable state.
Definition: Attributor.h:2941
static ConstantRange getBestState(uint32_t BitWidth)
Return the best possible representable state.
Definition: Attributor.h:2946
Simple state with integers encoding.
Definition: Attributor.h:2634
bool isValidState() const override
See AbstractState::isValidState() NOTE: For now we simply pretend that the worst possible state is in...
Definition: Attributor.h:2654
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:2657
void operator|=(const IntegerStateBase< base_t, BestState, WorstState > &R)
Definition: Attributor.h:2704
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:2672
ChangeStatus indicateOptimisticFixpoint() override
See AbstractState::indicateOptimisticFixpoint(...)
Definition: Attributor.h:2660
void operator^=(const IntegerStateBase< base_t, BestState, WorstState > &R)
"Clamp" this state with R.
Definition: Attributor.h:2693
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:2638
void operator+=(const IntegerStateBase< base_t, BestState, WorstState > &R)
"Clamp" this state with R.
Definition: Attributor.h:2700
base_t getAssumed() const
Return the assumed state encoding.
Definition: Attributor.h:2675
static constexpr base_t getWorstState()
Return the worst possible representable state.
Definition: Attributor.h:2647
static constexpr base_t getBestState()
Return the best possible representable state.
Definition: Attributor.h:2641
ChangeStatus indicatePessimisticFixpoint() override
See AbstractState::indicatePessimisticFixpoint(...)
Definition: Attributor.h:2666
base_t Known
The known state encoding in an integer of type base_t.
Definition: Attributor.h:2726
static constexpr base_t getWorstState(const IntegerStateBase &)
Definition: Attributor.h:2648
bool operator!=(const IntegerStateBase< base_t, BestState, WorstState > &R) const
Inequality for IntegerStateBase.
Definition: Attributor.h:2686
bool operator==(const IntegerStateBase< base_t, BestState, WorstState > &R) const
Equality for IntegerStateBase.
Definition: Attributor.h:2679
void operator&=(const IntegerStateBase< base_t, BestState, WorstState > &R)
Definition: Attributor.h:2708
base_t Assumed
The assumed state encoding in an integer of type base_t.
Definition: Attributor.h:2729
static constexpr base_t getBestState(const IntegerStateBase &)
Definition: Attributor.h:2642
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:4951
static PotentialValuesState getBestState(const PotentialValuesState &PVS)
Definition: Attributor.h:5011
PotentialValuesState & getAssumed()
Return the assumed state.
Definition: Attributor.h:4976
static unsigned MaxPotentialValues
Maximum number of potential values to be tracked.
Definition: Attributor.h:5004
bool undefIsContained() const
Returns whether this state contains an undef value or not.
Definition: Attributor.h:4987
bool contains(const MemberTy &V) const
Definition: Attributor.h:5042
bool isAtFixpoint() const override
See AbstractState::isAtFixpoint(...)
Definition: Attributor.h:4963
void unionAssumed(const MemberTy &C)
Union assumed set with the passed value.
Definition: Attributor.h:5021
static PotentialValuesState getBestState()
Return empty set as the best state of potential values.
Definition: Attributor.h:5007
SmallSetVector< MemberTy, 8 > SetTy
Definition: Attributor.h:4952
ChangeStatus indicatePessimisticFixpoint() override
See AbstractState::indicatePessimisticFixpoint(...)
Definition: Attributor.h:4966
void unionAssumed(const PotentialValuesState &PVS)
Union assumed set with assumed set of the passed state PVS.
Definition: Attributor.h:5024
PotentialValuesState(bool IsValid)
Definition: Attributor.h:4956
bool operator==(const PotentialValuesState &RHS) const
Definition: Attributor.h:4992
bool isValidState() const override
See AbstractState::isValidState(...)
Definition: Attributor.h:4960
PotentialValuesState operator&=(const PotentialValuesState &PVS)
Definition: Attributor.h:5036
static PotentialValuesState getWorstState()
Return full set as the worst state of potential values.
Definition: Attributor.h:5016
const PotentialValuesState & getAssumed() const
Definition: Attributor.h:4977
ChangeStatus indicateOptimisticFixpoint() override
See AbstractState::indicateOptimisticFixpoint(...)
Definition: Attributor.h:4971
PotentialValuesState operator^=(const PotentialValuesState &PVS)
"Clamp" this state with PVS.
Definition: Attributor.h:5030
void unionAssumedWithUndef()
Union assumed set with an undef value.
Definition: Attributor.h:5027
const SetTy & getAssumedSet() const
Return this set.
Definition: Attributor.h:4981
A wrapper around a set that has semantics for handling unions and intersections with a "universal" se...
Definition: Attributor.h:3036
SetContents(bool Universal)
Creates a universal set with no concrete elements or an empty set.
Definition: Attributor.h:3038
SetContents(bool Universal, const DenseSet< BaseTy > &Assumptions)
Definition: Attributor.h:3044
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:3055
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:3075
const DenseSet< BaseTy > & getSet() const
Definition: Attributor.h:3047
SetContents(const DenseSet< BaseTy > &Assumptions)
Creates a non-universal set with concrete values.
Definition: Attributor.h:3041
Simple state for a set.
Definition: Attributor.h:3033
bool setContains(const BaseTy &Elem) const
Returns if the set state contains the element.
Definition: Attributor.h:3129
bool getIntersection(const SetContents &RHS)
Performs the set intersection between this set and RHS.
Definition: Attributor.h:3135
bool isValidState() const override
See AbstractState::isValidState()
Definition: Attributor.h:3103
bool isAtFixpoint() const override
See AbstractState::isAtFixpoint()
Definition: Attributor.h:3106
const SetContents & getAssumed() const
Return the assumed state encoding.
Definition: Attributor.h:3126
const SetContents & getKnown() const
Return the known state encoding.
Definition: Attributor.h:3123
ChangeStatus indicateOptimisticFixpoint() override
See AbstractState::indicateOptimisticFixpoint(...)
Definition: Attributor.h:3109
bool getUnion(const SetContents &RHS)
Performs the set union between this set and RHS.
Definition: Attributor.h:3150
SetState(const DenseSet< BaseTy > &Known)
Initializes the known state with an initial set and initializes the assumed state as universal.
Definition: Attributor.h:3099
ChangeStatus indicatePessimisticFixpoint() override
See AbstractState::indicatePessimisticFixpoint(...)
Definition: Attributor.h:3116
Helper to tie a abstract state implementation to an abstract attribute.
Definition: Attributor.h:3164
StateType & getState() override
See AbstractAttribute::getState(...).
Definition: Attributor.h:3172
StateWrapper(const IRPosition &IRP, Ts... Args)
Definition: Attributor.h:3168
const StateType & getState() const override
See AbstractAttribute::getState(...).
Definition: Attributor.h:3175
static ValueSimplifyStateType getWorstState(Type *Ty)
Return the worst possible representable state.
Definition: Attributor.h:4430
static ValueSimplifyStateType getBestState(const ValueSimplifyStateType &VS)
Definition: Attributor.h:4425
bool unionAssumed(std::optional< Value * > Other)
Merge Other into the currently assumed simplified value.
ChangeStatus indicateOptimisticFixpoint() override
See AbstractState::indicateOptimisticFixpoint(...)
Definition: Attributor.h:4456
ValueSimplifyStateType operator^=(const ValueSimplifyStateType &VS)
"Clamp" this state with PVS.
Definition: Attributor.h:4461
ChangeStatus indicatePessimisticFixpoint() override
See AbstractState::indicatePessimisticFixpoint(...)
Definition: Attributor.h:4451
static ValueSimplifyStateType getBestState(Type *Ty)
Definition: Attributor.h:4422
bool isAtFixpoint() const override
See AbstractState::isAtFixpoint(...)
Definition: Attributor.h:4444
bool isValidState() const override
See AbstractState::isValidState(...)
Definition: Attributor.h:4441
std::optional< Value * > SimplifiedAssociatedValue
An assumed simplified value.
Definition: Attributor.h:4489
static ValueSimplifyStateType getWorstState(const ValueSimplifyStateType &VS)
Definition: Attributor.h:4436
BooleanState BS
Helper to track validity and fixpoint.
Definition: Attributor.h:4483
Type * Ty
The type of the original value.
Definition: Attributor.h:4477
bool operator==(const ValueSimplifyStateType &RHS) const
Definition: Attributor.h:4467
ValueSimplifyStateType getAssumed()
Return the assumed state encoding.
Definition: Attributor.h:4447
const ValueSimplifyStateType & getAssumed() const
Definition: Attributor.h:4448