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