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