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