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