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