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.
745 Value &V = getAnchorValue();
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.
757 Value &V = getAnchorValue();
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.
2119 function_ref<bool(ArrayRef<const Function *> Callees)> Pred,
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
2438private:
2439 /// This method will do fixpoint iteration until fixpoint or the
2440 /// maximum iteration count is reached.
2441 ///
2442 /// If the maximum iteration count is reached, This method will
2443 /// indicate pessimistic fixpoint on attributes that transitively depend
2444 /// on attributes that were scheduled for an update.
2445 void runTillFixpoint();
2446
2447 /// Gets called after scheduling, manifests attributes to the LLVM IR.
2448 ChangeStatus manifestAttributes();
2449
2450 /// Gets called after attributes have been manifested, cleans up the IR.
2451 /// Deletes dead functions, blocks and instructions.
2452 /// Rewrites function signitures and updates the call graph.
2453 ChangeStatus cleanupIR();
2454
2455 /// Identify internal functions that are effectively dead, thus not reachable
2456 /// from a live entry point. The functions are added to ToBeDeletedFunctions.
2457 void identifyDeadInternalFunctions();
2458
2459 /// Run `::update` on \p AA and track the dependences queried while doing so.
2460 /// Also adjust the state if we know further updates are not necessary.
2462
2463 /// Remember the dependences on the top of the dependence stack such that they
2464 /// may trigger further updates. (\see DependenceStack)
2465 void rememberDependences();
2466
2467 /// Determine if CallBase context in \p IRP should be propagated.
2468 LLVM_ABI bool shouldPropagateCallBaseContext(const IRPosition &IRP);
2469
2470 /// Apply all requested function signature rewrites
2471 /// (\see registerFunctionSignatureRewrite) and return Changed if the module
2472 /// was altered.
2474 rewriteFunctionSignatures(SmallSetVector<Function *, 8> &ModifiedFns);
2475
2476 /// Check if the Attribute \p AA should be seeded.
2477 /// See getOrCreateAAFor.
2478 LLVM_ABI bool shouldSeedAttribute(AbstractAttribute &AA);
2479
2480 /// A nested map to lookup abstract attributes based on the argument position
2481 /// on the outer level, and the addresses of the static member (AAType::ID) on
2482 /// the inner level.
2483 ///{
2484 using AAMapKeyTy = std::pair<const char *, IRPosition>;
2486 ///}
2487
2488 /// Map to remember all requested signature changes (= argument replacements).
2489 /// A MapVector so the functions are rewritten in a deterministic order.
2492 ArgumentReplacementMap;
2493
2494 /// The set of functions we are deriving attributes for.
2495 SetVector<Function *> &Functions;
2496
2497 /// The information cache that holds pre-processed (LLVM-IR) information.
2498 InformationCache &InfoCache;
2499
2500 /// Abstract Attribute dependency graph
2501 AADepGraph DG;
2502
2503 /// Set of functions for which we modified the content such that it might
2504 /// impact the call graph.
2505 SmallSetVector<Function *, 8> CGModifiedFunctions;
2506
2507 /// Information about a dependence. If FromAA is changed ToAA needs to be
2508 /// updated as well.
2509 struct DepInfo {
2510 const AbstractAttribute *FromAA;
2511 const AbstractAttribute *ToAA;
2512 DepClassTy DepClass;
2513 };
2514
2515 /// The dependence stack is used to track dependences during an
2516 /// `AbstractAttribute::update` call. As `AbstractAttribute::update` can be
2517 /// recursive we might have multiple vectors of dependences in here. The stack
2518 /// size, should be adjusted according to the expected recursion depth and the
2519 /// inner dependence vector size to the expected number of dependences per
2520 /// abstract attribute. Since the inner vectors are actually allocated on the
2521 /// stack we can be generous with their size.
2522 using DependenceVector = SmallVector<DepInfo, 8>;
2524
2525 /// A set to remember the functions we already assume to be live and visited.
2526 DenseSet<const Function *> VisitedFunctions;
2527
2528 /// Uses we replace with a new value after manifest is done. We will remove
2529 /// then trivially dead instructions as well.
2530 SmallMapVector<Use *, Value *, 32> ToBeChangedUses;
2531
2532 /// Values we replace with a new value after manifest is done. We will remove
2533 /// then trivially dead instructions as well.
2534 SmallMapVector<Value *, PointerIntPair<Value *, 1, bool>, 32>
2535 ToBeChangedValues;
2536
2537 /// Instructions we replace with `unreachable` insts after manifest is done.
2538 SmallSetVector<WeakVH, 16> ToBeChangedToUnreachableInsts;
2539
2540 /// Invoke instructions with at least a single dead successor block.
2541 SmallSetVector<WeakVH, 16> InvokeWithDeadSuccessor;
2542
2543 /// A flag that indicates which stage of the process we are in. Initially, the
2544 /// phase is SEEDING. Phase is changed in `Attributor::run()`
2545 enum class AttributorPhase {
2546 SEEDING,
2547 UPDATE,
2548 MANIFEST,
2549 CLEANUP,
2550 } Phase = AttributorPhase::SEEDING;
2551
2552 /// The current initialization chain length. Tracked to avoid stack overflows.
2553 unsigned InitializationChainLength = 0;
2554
2555 /// Functions, blocks, and instructions we delete after manifest is done.
2556 ///
2557 ///{
2558 SmallPtrSet<BasicBlock *, 8> ManifestAddedBlocks;
2559 SmallSetVector<Function *, 8> ToBeDeletedFunctions;
2560 SmallSetVector<BasicBlock *, 8> ToBeDeletedBlocks;
2561 SmallSetVector<WeakVH, 8> ToBeDeletedInsts;
2562 ///}
2563
2564 /// Container with all the query AAs that requested an update via
2565 /// registerForUpdate.
2566 SmallSetVector<AbstractAttribute *, 16> QueryAAsAwaitingUpdate;
2567
2568 /// User provided configuration for this Attributor instance.
2569 const AttributorConfig Configuration;
2570
2571 friend AADepGraph;
2572 friend AttributorCallGraph;
2573};
2574
2575/// An interface to query the internal state of an abstract attribute.
2576///
2577/// The abstract state is a minimal interface that allows the Attributor to
2578/// communicate with the abstract attributes about their internal state without
2579/// enforcing or exposing implementation details, e.g., the (existence of an)
2580/// underlying lattice.
2581///
2582/// It is sufficient to be able to query if a state is (1) valid or invalid, (2)
2583/// at a fixpoint, and to indicate to the state that (3) an optimistic fixpoint
2584/// was reached or (4) a pessimistic fixpoint was enforced.
2585///
2586/// All methods need to be implemented by the subclass. For the common use case,
2587/// a single boolean state or a bit-encoded state, the BooleanState and
2588/// {Inc,Dec,Bit}IntegerState classes are already provided. An abstract
2589/// attribute can inherit from them to get the abstract state interface and
2590/// additional methods to directly modify the state based if needed. See the
2591/// class comments for help.
2593 virtual ~AbstractState() = default;
2594
2595 /// Return if this abstract state is in a valid state. If false, no
2596 /// information provided should be used.
2597 virtual bool isValidState() const = 0;
2598
2599 /// Return if this abstract state is fixed, thus does not need to be updated
2600 /// if information changes as it cannot change itself.
2601 virtual bool isAtFixpoint() const = 0;
2602
2603 /// Indicate that the abstract state should converge to the optimistic state.
2604 ///
2605 /// This will usually make the optimistically assumed state the known to be
2606 /// true state.
2607 ///
2608 /// \returns ChangeStatus::UNCHANGED as the assumed value should not change.
2610
2611 /// Indicate that the abstract state should converge to the pessimistic state.
2612 ///
2613 /// This will usually revert the optimistically assumed state to the known to
2614 /// be true state.
2615 ///
2616 /// \returns ChangeStatus::CHANGED as the assumed value may change.
2618};
2619
2620/// Simple state with integers encoding.
2621///
2622/// The interface ensures that the assumed bits are always a subset of the known
2623/// bits. Users can only add known bits and, except through adding known bits,
2624/// they can only remove assumed bits. This should guarantee monotonicity and
2625/// thereby the existence of a fixpoint (if used correctly). The fixpoint is
2626/// reached when the assumed and known state/bits are equal. Users can
2627/// force/inidicate a fixpoint. If an optimistic one is indicated, the known
2628/// state will catch up with the assumed one, for a pessimistic fixpoint it is
2629/// the other way around.
2630template <typename base_ty, base_ty BestState, base_ty WorstState>
2632 using base_t = base_ty;
2633
2634 IntegerStateBase() = default;
2636
2637 /// Return the best possible representable state.
2638 static constexpr base_t getBestState() { return BestState; }
2639 static constexpr base_t getBestState(const IntegerStateBase &) {
2640 return getBestState();
2641 }
2642
2643 /// Return the worst possible representable state.
2644 static constexpr base_t getWorstState() { return WorstState; }
2645 static constexpr base_t getWorstState(const IntegerStateBase &) {
2646 return getWorstState();
2647 }
2648
2649 /// NOTE: For now we simply pretend that the worst possible state is invalid.
2650 bool isValidState() const override { return Assumed != getWorstState(); }
2651
2652 bool isAtFixpoint() const override { return Assumed == Known; }
2653
2658
2663
2664 /// Return the known state encoding
2665 base_t getKnown() const { return Known; }
2666
2667 /// Return the assumed state encoding.
2668 base_t getAssumed() const { return Assumed; }
2669
2670 /// Equality for IntegerStateBase.
2671 bool
2673 return this->getAssumed() == R.getAssumed() &&
2674 this->getKnown() == R.getKnown();
2675 }
2676
2677 /// Inequality for IntegerStateBase.
2678 bool
2680 return !(*this == R);
2681 }
2682
2683 /// "Clamp" this state with \p R. The result is subtype dependent but it is
2684 /// intended that only information assumed in both states will be assumed in
2685 /// this one afterwards.
2689
2690 /// "Clamp" this state with \p R. The result is subtype dependent but it is
2691 /// intended that information known in either state will be known in
2692 /// this one afterwards.
2696
2698 joinOR(R.getAssumed(), R.getKnown());
2699 }
2700
2702 joinAND(R.getAssumed(), R.getKnown());
2703 }
2704
2705protected:
2706 /// Handle a new assumed value \p Value. Subtype dependent.
2708
2709 /// Handle a new known value \p Value. Subtype dependent.
2711
2712 /// Handle a value \p Value. Subtype dependent.
2713 virtual void joinOR(base_t AssumedValue, base_t KnownValue) = 0;
2714
2715 /// Handle a new assumed value \p Value. Subtype dependent.
2716 virtual void joinAND(base_t AssumedValue, base_t KnownValue) = 0;
2717
2718 /// The known state encoding in an integer of type base_t.
2720
2721 /// The assumed state encoding in an integer of type base_t.
2723};
2724
2725/// Specialization of the integer state for a bit-wise encoding.
2726template <typename base_ty = uint32_t, base_ty BestState = ~base_ty(0),
2727 base_ty WorstState = 0>
2729 : public IntegerStateBase<base_ty, BestState, WorstState> {
2731 using base_t = base_ty;
2732 BitIntegerState() = default;
2734
2735 /// Return true if the bits set in \p BitsEncoding are "known bits".
2736 bool isKnown(base_t BitsEncoding = BestState) const {
2737 return (this->Known & BitsEncoding) == BitsEncoding;
2738 }
2739
2740 /// Return true if the bits set in \p BitsEncoding are "assumed bits".
2741 bool isAssumed(base_t BitsEncoding = BestState) const {
2742 return (this->Assumed & BitsEncoding) == BitsEncoding;
2743 }
2744
2745 /// Add the bits in \p BitsEncoding to the "known bits".
2747 // Make sure we never miss any "known bits".
2748 this->Assumed |= Bits;
2749 this->Known |= Bits;
2750 return *this;
2751 }
2752
2753 /// Remove the bits in \p BitsEncoding from the "assumed bits" if not known.
2755 return intersectAssumedBits(~BitsEncoding);
2756 }
2757
2758 /// Remove the bits in \p BitsEncoding from the "known bits".
2760 this->Known = (this->Known & ~BitsEncoding);
2761 return *this;
2762 }
2763
2764 /// Keep only "assumed bits" also set in \p BitsEncoding but all known ones.
2766 // Make sure we never lose any "known bits".
2767 this->Assumed = (this->Assumed & BitsEncoding) | this->Known;
2768 return *this;
2769 }
2770
2771private:
2772 void handleNewAssumedValue(base_t Value) override {
2774 }
2775 void handleNewKnownValue(base_t Value) override { addKnownBits(Value); }
2776 void joinOR(base_t AssumedValue, base_t KnownValue) override {
2777 this->Known |= KnownValue;
2778 this->Assumed |= AssumedValue;
2779 }
2780 void joinAND(base_t AssumedValue, base_t KnownValue) override {
2781 this->Known &= KnownValue;
2782 this->Assumed &= AssumedValue;
2783 }
2784};
2785
2786/// Specialization of the integer state for an increasing value, hence ~0u is
2787/// the best state and 0 the worst.
2788template <typename base_ty = uint32_t, base_ty BestState = ~base_ty(0),
2789 base_ty WorstState = 0>
2791 : public IntegerStateBase<base_ty, BestState, WorstState> {
2793 using base_t = base_ty;
2794
2797
2798 /// Return the best possible representable state.
2799 static constexpr base_t getBestState() { return BestState; }
2800 static constexpr base_t
2804
2805 /// Take minimum of assumed and \p Value.
2807 // Make sure we never lose "known value".
2808 this->Assumed = std::max(std::min(this->Assumed, Value), this->Known);
2809 return *this;
2810 }
2811
2812 /// Take maximum of known and \p Value.
2814 // Make sure we never lose "known value".
2815 this->Assumed = std::max(Value, this->Assumed);
2816 this->Known = std::max(Value, this->Known);
2817 return *this;
2818 }
2819
2820private:
2821 void handleNewAssumedValue(base_t Value) override {
2823 }
2824 void handleNewKnownValue(base_t Value) override { takeKnownMaximum(Value); }
2825 void joinOR(base_t AssumedValue, base_t KnownValue) override {
2826 this->Known = std::max(this->Known, KnownValue);
2827 this->Assumed = std::max(this->Assumed, AssumedValue);
2828 }
2829 void joinAND(base_t AssumedValue, base_t KnownValue) override {
2830 this->Known = std::min(this->Known, KnownValue);
2831 this->Assumed = std::min(this->Assumed, AssumedValue);
2832 }
2833};
2834
2835/// Specialization of the integer state for a decreasing value, hence 0 is the
2836/// best state and ~0u the worst.
2837template <typename base_ty = uint32_t>
2838struct DecIntegerState : public IntegerStateBase<base_ty, 0, ~base_ty(0)> {
2839 using base_t = base_ty;
2840
2841 /// Take maximum of assumed and \p Value.
2843 // Make sure we never lose "known value".
2844 this->Assumed = std::min(std::max(this->Assumed, Value), this->Known);
2845 return *this;
2846 }
2847
2848 /// Take minimum of known and \p Value.
2850 // Make sure we never lose "known value".
2851 this->Assumed = std::min(Value, this->Assumed);
2852 this->Known = std::min(Value, this->Known);
2853 return *this;
2854 }
2855
2856private:
2857 void handleNewAssumedValue(base_t Value) override {
2859 }
2860 void handleNewKnownValue(base_t Value) override { takeKnownMinimum(Value); }
2861 void joinOR(base_t AssumedValue, base_t KnownValue) override {
2862 this->Assumed = std::min(this->Assumed, KnownValue);
2863 this->Assumed = std::min(this->Assumed, AssumedValue);
2864 }
2865 void joinAND(base_t AssumedValue, base_t KnownValue) override {
2866 this->Assumed = std::max(this->Assumed, KnownValue);
2867 this->Assumed = std::max(this->Assumed, AssumedValue);
2868 }
2869};
2870
2871/// Simple wrapper for a single bit (boolean) state.
2872struct BooleanState : public IntegerStateBase<bool, true, false> {
2875
2876 BooleanState() = default;
2878
2879 /// Set the known and asssumed value to \p Value.
2880 void setKnown(bool Value) {
2881 Known |= Value;
2882 Assumed |= Value;
2883 }
2884
2885 /// Return true if the state is assumed to hold.
2886 bool isAssumed() const { return getAssumed(); }
2887
2888 /// Return true if the state is known to hold.
2889 bool isKnown() const { return getKnown(); }
2890
2891private:
2892 void handleNewAssumedValue(base_t Value) override {
2893 if (!Value)
2894 Assumed = Known;
2895 }
2896 void handleNewKnownValue(base_t Value) override {
2897 if (Value)
2898 Known = (Assumed = Value);
2899 }
2900 void joinOR(base_t AssumedValue, base_t KnownValue) override {
2901 Known |= KnownValue;
2902 Assumed |= AssumedValue;
2903 }
2904 void joinAND(base_t AssumedValue, base_t KnownValue) override {
2905 Known &= KnownValue;
2906 Assumed &= AssumedValue;
2907 }
2908};
2909
2910/// State for an integer range.
2912
2913 /// Bitwidth of the associated value.
2915
2916 /// State representing assumed range, initially set to empty.
2918
2919 /// State representing known range, initially set to [-inf, inf].
2921
2925
2929
2930 /// Return the worst possible representable state.
2932 return ConstantRange::getFull(BitWidth);
2933 }
2934
2935 /// Return the best possible representable state.
2937 return ConstantRange::getEmpty(BitWidth);
2938 }
2940 return getBestState(IRS.getBitWidth());
2941 }
2942
2943 /// Return associated values' bit width.
2944 uint32_t getBitWidth() const { return BitWidth; }
2945
2946 bool isValidState() const override {
2947 return BitWidth > 0 && !Assumed.isFullSet();
2948 }
2949
2950 bool isAtFixpoint() const override { return Assumed == Known; }
2951
2956
2961
2962 /// Return the known state encoding
2963 ConstantRange getKnown() const { return Known; }
2964
2965 /// Return the assumed state encoding.
2967
2968 /// Unite assumed range with the passed state.
2970 // Don't lose a known range.
2971 Assumed = Assumed.unionWith(R).intersectWith(Known);
2972 }
2973
2974 /// See IntegerRangeState::unionAssumed(..).
2976 unionAssumed(R.getAssumed());
2977 }
2978
2979 /// Intersect known range with the passed state.
2981 Assumed = Assumed.intersectWith(R);
2982 Known = Known.intersectWith(R);
2983 }
2984
2985 /// See IntegerRangeState::intersectKnown(..).
2987 intersectKnown(R.getKnown());
2988 }
2989
2990 /// Equality for IntegerRangeState.
2991 bool operator==(const IntegerRangeState &R) const {
2992 return getAssumed() == R.getAssumed() && getKnown() == R.getKnown();
2993 }
2994
2995 /// "Clamp" this state with \p R. The result is subtype dependent but it is
2996 /// intended that only information assumed in both states will be assumed in
2997 /// this one afterwards.
2999 // NOTE: `^=` operator seems like `intersect` but in this case, we need to
3000 // take `union`.
3001 unionAssumed(R);
3002 return *this;
3003 }
3004
3006 // NOTE: `&=` operator seems like `intersect` but in this case, we need to
3007 // take `union`.
3008 Known = Known.unionWith(R.getKnown());
3009 Assumed = Assumed.unionWith(R.getAssumed());
3010 return *this;
3011 }
3012};
3013
3014/// Simple state for a set.
3015///
3016/// This represents a state containing a set of values. The interface supports
3017/// modelling sets that contain all possible elements. The state's internal
3018/// value is modified using union or intersection operations.
3019template <typename BaseTy> struct SetState : public AbstractState {
3020 /// A wrapper around a set that has semantics for handling unions and
3021 /// intersections with a "universal" set that contains all elements.
3023 /// Creates a universal set with no concrete elements or an empty set.
3024 SetContents(bool Universal) : Universal(Universal) {}
3025
3026 /// Creates a non-universal set with concrete values.
3027 SetContents(const DenseSet<BaseTy> &Assumptions)
3028 : Universal(false), Set(Assumptions) {}
3029
3030 SetContents(bool Universal, const DenseSet<BaseTy> &Assumptions)
3031 : Universal(Universal), Set(Assumptions) {}
3032
3033 const DenseSet<BaseTy> &getSet() const { return Set; }
3034
3035 bool isUniversal() const { return Universal; }
3036
3037 bool empty() const { return Set.empty() && !Universal; }
3038
3039 /// Finds A := A ^ B where A or B could be the "Universal" set which
3040 /// contains every possible attribute. Returns true if changes were made.
3042 bool IsUniversal = Universal;
3043 unsigned Size = Set.size();
3044
3045 // A := A ^ U = A
3046 if (RHS.isUniversal())
3047 return false;
3048
3049 // A := U ^ B = B
3050 if (Universal)
3051 Set = RHS.getSet();
3052 else
3053 set_intersect(Set, RHS.getSet());
3054
3055 Universal &= RHS.isUniversal();
3056 return IsUniversal != Universal || Size != Set.size();
3057 }
3058
3059 /// Finds A := A u B where A or B could be the "Universal" set which
3060 /// contains every possible attribute. returns true if changes were made.
3061 bool getUnion(const SetContents &RHS) {
3062 bool IsUniversal = Universal;
3063 unsigned Size = Set.size();
3064
3065 // A := A u U = U = U u B
3066 if (!RHS.isUniversal() && !Universal)
3067 set_union(Set, RHS.getSet());
3068
3069 Universal |= RHS.isUniversal();
3070 return IsUniversal != Universal || Size != Set.size();
3071 }
3072
3073 private:
3074 /// Indicates if this set is "universal", containing every possible element.
3075 bool Universal;
3076
3077 /// The set of currently active assumptions.
3078 DenseSet<BaseTy> Set;
3079 };
3080
3081 SetState() : Known(false), Assumed(true), IsAtFixedpoint(false) {}
3082
3083 /// Initializes the known state with an initial set and initializes the
3084 /// assumed state as universal.
3086 : Known(Known), Assumed(true), IsAtFixedpoint(false) {}
3087
3088 bool isValidState() const override { return !Assumed.empty(); }
3089
3090 bool isAtFixpoint() const override { return IsAtFixedpoint; }
3091
3093 IsAtFixedpoint = true;
3094 Known = Assumed;
3096 }
3097
3099 IsAtFixedpoint = true;
3100 Assumed = Known;
3101 return ChangeStatus::CHANGED;
3102 }
3103
3104 /// Return the known state encoding.
3105 const SetContents &getKnown() const { return Known; }
3106
3107 /// Return the assumed state encoding.
3108 const SetContents &getAssumed() const { return Assumed; }
3109
3110 /// Returns if the set state contains the element.
3111 bool setContains(const BaseTy &Elem) const {
3112 return Assumed.getSet().contains(Elem) || Known.getSet().contains(Elem);
3113 }
3114
3115 /// Performs the set intersection between this set and \p RHS. Returns true if
3116 /// changes were made.
3118 bool IsUniversal = Assumed.isUniversal();
3119 unsigned SizeBefore = Assumed.getSet().size();
3120
3121 // Get intersection and make sure that the known set is still a proper
3122 // subset of the assumed set. A := K u (A ^ R).
3123 Assumed.getIntersection(RHS);
3124 Assumed.getUnion(Known);
3125
3126 return SizeBefore != Assumed.getSet().size() ||
3127 IsUniversal != Assumed.isUniversal();
3128 }
3129
3130 /// Performs the set union between this set and \p RHS. Returns true if
3131 /// changes were made.
3132 bool getUnion(const SetContents &RHS) { return Assumed.getUnion(RHS); }
3133
3134private:
3135 /// The set of values known for this state.
3136 SetContents Known;
3137
3138 /// The set of assumed values for this state.
3139 SetContents Assumed;
3140
3141 bool IsAtFixedpoint;
3142};
3143
3144/// Helper to tie a abstract state implementation to an abstract attribute.
3145template <typename StateTy, typename BaseType, class... Ts>
3146struct StateWrapper : public BaseType, public StateTy {
3147 /// Provide static access to the type of the state.
3149
3150 StateWrapper(const IRPosition &IRP, Ts... Args)
3151 : BaseType(IRP), StateTy(Args...) {}
3152
3153 StateType &getState() override { return *this; }
3154
3155 const StateType &getState() const override { return *this; }
3156};
3157
3158/// Helper class that provides common functionality to manifest IR attributes.
3159template <Attribute::AttrKind AK, typename BaseType, typename AAType>
3160struct IRAttribute : public BaseType {
3161 IRAttribute(const IRPosition &IRP) : BaseType(IRP) {}
3162
3163 /// Most boolean IRAttribute AAs don't do anything non-trivial
3164 /// in their initializers while non-boolean ones often do. Subclasses can
3165 /// change this.
3167
3168 /// Compile time access to the IR attribute kind.
3170
3171 /// Return true if the IR attribute(s) associated with this AA are implied for
3172 /// an undef value.
3173 static bool isImpliedByUndef() { return true; }
3174
3175 /// Return true if the IR attribute(s) associated with this AA are implied for
3176 /// an poison value.
3177 static bool isImpliedByPoison() { return true; }
3178
3179 static bool isImpliedByIR(Attributor &A, const IRPosition &IRP,
3180 Attribute::AttrKind ImpliedAttributeKind = AK,
3181 bool IgnoreSubsumingPositions = false) {
3182 if (AAType::isImpliedByUndef() && isa<UndefValue>(IRP.getAssociatedValue()))
3183 return true;
3184 if (AAType::isImpliedByPoison() &&
3186 return true;
3187 return A.hasAttr(IRP, {ImpliedAttributeKind}, IgnoreSubsumingPositions,
3188 ImpliedAttributeKind);
3189 }
3190
3192 if (isa<UndefValue>(this->getIRPosition().getAssociatedValue()))
3194 SmallVector<Attribute, 4> DeducedAttrs;
3195 getDeducedAttributes(A, this->getAnchorValue().getContext(), DeducedAttrs);
3196 if (DeducedAttrs.empty())
3198 return A.manifestAttrs(this->getIRPosition(), DeducedAttrs);
3199 }
3200
3201 /// Return the kind that identifies the abstract attribute implementation.
3202 Attribute::AttrKind getAttrKind() const { return AK; }
3203
3204 /// Return the deduced attributes in \p Attrs.
3206 SmallVectorImpl<Attribute> &Attrs) const {
3207 Attrs.emplace_back(Attribute::get(Ctx, getAttrKind()));
3208 }
3209};
3210
3211/// Base struct for all "concrete attribute" deductions.
3212///
3213/// The abstract attribute is a minimal interface that allows the Attributor to
3214/// orchestrate the abstract/fixpoint analysis. The design allows to hide away
3215/// implementation choices made for the subclasses but also to structure their
3216/// implementation and simplify the use of other abstract attributes in-flight.
3217///
3218/// To allow easy creation of new attributes, most methods have default
3219/// implementations. The ones that do not are generally straight forward, except
3220/// `AbstractAttribute::updateImpl` which is the location of most reasoning
3221/// associated with the abstract attribute. The update is invoked by the
3222/// Attributor in case the situation used to justify the current optimistic
3223/// state might have changed. The Attributor determines this automatically
3224/// by monitoring the `Attributor::getAAFor` calls made by abstract attributes.
3225///
3226/// The `updateImpl` method should inspect the IR and other abstract attributes
3227/// in-flight to justify the best possible (=optimistic) state. The actual
3228/// implementation is, similar to the underlying abstract state encoding, not
3229/// exposed. In the most common case, the `updateImpl` will go through a list of
3230/// reasons why its optimistic state is valid given the current information. If
3231/// any combination of them holds and is sufficient to justify the current
3232/// optimistic state, the method shall return UNCHAGED. If not, the optimistic
3233/// state is adjusted to the situation and the method shall return CHANGED.
3234///
3235/// If the manifestation of the "concrete attribute" deduced by the subclass
3236/// differs from the "default" behavior, which is a (set of) LLVM-IR
3237/// attribute(s) for an argument, call site argument, function return value, or
3238/// function, the `AbstractAttribute::manifest` method should be overloaded.
3239///
3240/// NOTE: If the state obtained via getState() is INVALID, thus if
3241/// AbstractAttribute::getState().isValidState() returns false, no
3242/// information provided by the methods of this class should be used.
3243/// NOTE: The Attributor currently has certain limitations to what we can do.
3244/// As a general rule of thumb, "concrete" abstract attributes should *for
3245/// now* only perform "backward" information propagation. That means
3246/// optimistic information obtained through abstract attributes should
3247/// only be used at positions that precede the origin of the information
3248/// with regards to the program flow. More practically, information can
3249/// *now* be propagated from instructions to their enclosing function, but
3250/// *not* from call sites to the called function. The mechanisms to allow
3251/// both directions will be added in the future.
3252/// NOTE: The mechanics of adding a new "concrete" abstract attribute are
3253/// described in the file comment.
3256
3258
3259 /// Virtual destructor.
3260 ~AbstractAttribute() override = default;
3261
3262 /// Compile time access to the IR attribute kind.
3264
3265 /// This function is used to identify if an \p DGN is of type
3266 /// AbstractAttribute so that the dyn_cast and cast can use such information
3267 /// to cast an AADepGraphNode to an AbstractAttribute.
3268 ///
3269 /// We eagerly return true here because all AADepGraphNodes except for the
3270 /// Synthethis Node are of type AbstractAttribute
3271 static bool classof(const AADepGraphNode *DGN) { return true; }
3272
3273 /// Return false if this AA does anything non-trivial (hence not done by
3274 /// default) in its initializer.
3275 static bool hasTrivialInitializer() { return false; }
3276
3277 /// Return true if this AA requires a "callee" (or an associted function) for
3278 /// a call site positon. Default is optimistic to minimize AAs.
3279 static bool requiresCalleeForCallBase() { return false; }
3280
3281 /// Return true if this AA requires non-asm "callee" for a call site positon.
3282 static bool requiresNonAsmForCallBase() { return true; }
3283
3284 /// Return true if this AA requires all callees for an argument or function
3285 /// positon.
3286 static bool requiresCallersForArgOrFunction() { return false; }
3287
3288 /// Return false if an AA should not be created for \p IRP.
3290 return true;
3291 }
3292
3293 /// Return false if an AA should not be updated for \p IRP.
3295 Function *AssociatedFn = IRP.getAssociatedFunction();
3296 bool IsFnInterface = IRP.isFnInterfaceKind();
3297 assert((!IsFnInterface || AssociatedFn) &&
3298 "Function interface without a function?");
3299
3300 // TODO: Not all attributes require an exact definition. Find a way to
3301 // enable deduction for some but not all attributes in case the
3302 // definition might be changed at runtime, see also
3303 // http://lists.llvm.org/pipermail/llvm-dev/2018-February/121275.html.
3304 // TODO: We could always determine abstract attributes and if sufficient
3305 // information was found we could duplicate the functions that do not
3306 // have an exact definition.
3307 return !IsFnInterface || A.isFunctionIPOAmendable(*AssociatedFn);
3308 }
3309
3310 /// Initialize the state with the information in the Attributor \p A.
3311 ///
3312 /// This function is called by the Attributor once all abstract attributes
3313 /// have been identified. It can and shall be used for task like:
3314 /// - identify existing knowledge in the IR and use it for the "known state"
3315 /// - perform any work that is not going to change over time, e.g., determine
3316 /// a subset of the IR, or attributes in-flight, that have to be looked at
3317 /// in the `updateImpl` method.
3318 virtual void initialize(Attributor &A) {}
3319
3320 /// A query AA is always scheduled as long as we do updates because it does
3321 /// lazy computation that cannot be determined to be done from the outside.
3322 /// However, while query AAs will not be fixed if they do not have outstanding
3323 /// dependences, we will only schedule them like other AAs. If a query AA that
3324 /// received a new query it needs to request an update via
3325 /// `Attributor::requestUpdateForAA`.
3326 virtual bool isQueryAA() const { return false; }
3327
3328 /// Return the internal abstract state for inspection.
3329 virtual StateType &getState() = 0;
3330 virtual const StateType &getState() const = 0;
3331
3332 /// Return an IR position, see struct IRPosition.
3333 const IRPosition &getIRPosition() const { return *this; };
3334 IRPosition &getIRPosition() { return *this; };
3335
3336 /// Helper functions, for debug purposes only.
3337 ///{
3338 void print(raw_ostream &OS) const { print(nullptr, OS); }
3339 void print(Attributor *, raw_ostream &OS) const override;
3340 virtual void printWithDeps(raw_ostream &OS) const;
3341 void dump() const { this->print(dbgs()); }
3342
3343 /// This function should return the "summarized" assumed state as string.
3344 virtual const std::string getAsStr(Attributor *A) const = 0;
3345
3346 /// This function should return the name of the AbstractAttribute
3347 virtual StringRef getName() const = 0;
3348
3349 /// This function should return the address of the ID of the AbstractAttribute
3350 virtual const char *getIdAddr() const = 0;
3351 ///}
3352
3353 /// Allow the Attributor access to the protected methods.
3354 friend struct Attributor;
3355
3356protected:
3357 /// Hook for the Attributor to trigger an update of the internal state.
3358 ///
3359 /// If this attribute is already fixed, this method will return UNCHANGED,
3360 /// otherwise it delegates to `AbstractAttribute::updateImpl`.
3361 ///
3362 /// \Return CHANGED if the internal state changed, otherwise UNCHANGED.
3364
3365 /// Hook for the Attributor to trigger the manifestation of the information
3366 /// represented by the abstract attribute in the LLVM-IR.
3367 ///
3368 /// \Return CHANGED if the IR was altered, otherwise UNCHANGED.
3372
3373 /// Hook to enable custom statistic tracking, called after manifest that
3374 /// resulted in a change if statistics are enabled.
3375 ///
3376 /// We require subclasses to provide an implementation so we remember to
3377 /// add statistics for them.
3378 virtual void trackStatistics() const = 0;
3379
3380 /// The actual update/transfer function which has to be implemented by the
3381 /// derived classes.
3382 ///
3383 /// If it is called, the environment has changed and we have to determine if
3384 /// the current information is still valid or adjust it otherwise.
3385 ///
3386 /// \Return CHANGED if the internal state changed, otherwise UNCHANGED.
3388};
3389
3390/// Forward declarations of output streams for debug purposes.
3391///
3392///{
3398template <typename base_ty, base_ty BestState, base_ty WorstState>
3402 return OS << "(" << S.getKnown() << "-" << S.getAssumed() << ")"
3403 << static_cast<const AbstractState &>(S);
3404}
3405LLVM_ABI raw_ostream &operator<<(raw_ostream &OS,
3406 const IntegerRangeState &State);
3407///}
3408
3417
3418/// A more lightweight version of the Attributor which only runs attribute
3419/// inference but no simplifications.
3420struct AttributorLightPass : public OptionalPassInfoMixin<AttributorLightPass> {
3422};
3423
3424/// A more lightweight version of the Attributor which only runs attribute
3425/// inference but no simplifications.
3427 : public OptionalPassInfoMixin<AttributorLightCGSCCPass> {
3430 CGSCCUpdateResult &UR);
3431};
3432
3433/// Helper function to clamp a state \p S of type \p StateType with the
3434/// information in \p R and indicate/return if \p S did change (as-in update is
3435/// required to be run again).
3436template <typename StateType>
3437ChangeStatus clampStateAndIndicateChange(StateType &S, const StateType &R) {
3438 auto Assumed = S.getAssumed();
3439 S ^= R;
3440 return Assumed == S.getAssumed() ? ChangeStatus::UNCHANGED
3442}
3443
3444/// ----------------------------------------------------------------------------
3445/// Abstract Attribute Classes
3446/// ----------------------------------------------------------------------------
3447
3449 : public IRAttribute<Attribute::NoUnwind,
3450 StateWrapper<BooleanState, AbstractAttribute>,
3451 AANoUnwind> {
3453
3454 /// Returns true if nounwind is assumed.
3455 bool isAssumedNoUnwind() const { return getAssumed(); }
3456
3457 /// Returns true if nounwind is known.
3458 bool isKnownNoUnwind() const { return getKnown(); }
3459
3460 /// Create an abstract attribute view for the position \p IRP.
3462 Attributor &A);
3463
3464 StringRef getName() const override { return "AANoUnwind"; }
3465
3466 const char *getIdAddr() const override { return &ID; }
3467
3468 /// This function should return true if the type of the \p AA is AANoUnwind
3469 static bool classof(const AbstractAttribute *AA) {
3470 return (AA->getIdAddr() == &ID);
3471 }
3472
3473 /// Unique ID (due to the unique address)
3474 LLVM_ABI static const char ID;
3475};
3476
3478 : public IRAttribute<Attribute::NoSync,
3479 StateWrapper<BooleanState, AbstractAttribute>,
3480 AANoSync> {
3482
3483 static bool isImpliedByIR(Attributor &A, const IRPosition &IRP,
3484 Attribute::AttrKind ImpliedAttributeKind,
3485 bool IgnoreSubsumingPositions = false) {
3486 // Note: This is also run for non-IPO amendable functions.
3487 assert(ImpliedAttributeKind == Attribute::NoSync);
3488 if (A.hasAttr(IRP, {Attribute::NoSync}, IgnoreSubsumingPositions,
3489 Attribute::NoSync))
3490 return true;
3491
3492 // Check for readonly + non-convergent.
3493 // TODO: We should be able to use hasAttr for Attributes, not only
3494 // AttrKinds.
3496 if (!F || F->isConvergent())
3497 return false;
3498
3500 A.getAttrs(IRP, {Attribute::Memory}, Attrs, IgnoreSubsumingPositions);
3501
3503 for (const Attribute &Attr : Attrs)
3504 ME &= Attr.getMemoryEffects();
3505
3506 if (!ME.onlyReadsMemory())
3507 return false;
3508
3509 A.manifestAttrs(IRP, Attribute::get(F->getContext(), Attribute::NoSync));
3510 return true;
3511 }
3512
3514 if (!IRP.isFunctionScope() &&
3516 return false;
3517 return IRAttribute::isValidIRPositionForInit(A, IRP);
3518 }
3519
3520 /// Returns true if "nosync" is assumed.
3521 bool isAssumedNoSync() const { return getAssumed(); }
3522
3523 /// Returns true if "nosync" is known.
3524 bool isKnownNoSync() const { return getKnown(); }
3525
3526 /// Helper function used to determine whether an instruction is non-relaxed
3527 /// atomic. In other words, if an atomic instruction does not have unordered
3528 /// or monotonic ordering
3529 LLVM_ABI static bool isNonRelaxedAtomic(const Instruction *I);
3530
3531 /// Helper function to determine if \p CB is an aligned (GPU) barrier. Aligned
3532 /// barriers have to be executed by all threads. The flag \p ExecutedAligned
3533 /// indicates if the call is executed by all threads in a (thread) block in an
3534 /// aligned way. If that is the case, non-aligned barriers are effectively
3535 /// aligned barriers.
3536 LLVM_ABI static bool isAlignedBarrier(const CallBase &CB,
3537 bool ExecutedAligned);
3538
3539 /// Create an abstract attribute view for the position \p IRP.
3541 Attributor &A);
3542
3543 StringRef getName() const override { return "AANoSync"; }
3544
3545 const char *getIdAddr() const override { return &ID; }
3546
3547 /// This function should return true if the type of the \p AA is AANoSync
3548 static bool classof(const AbstractAttribute *AA) {
3549 return (AA->getIdAddr() == &ID);
3550 }
3551
3552 /// Unique ID (due to the unique address)
3553 LLVM_ABI static const char ID;
3554};
3555
3556/// An abstract interface for all nonnull attributes.
3558 : public IRAttribute<Attribute::MustProgress,
3559 StateWrapper<BooleanState, AbstractAttribute>,
3560 AAMustProgress> {
3562
3563 static bool isImpliedByIR(Attributor &A, const IRPosition &IRP,
3564 Attribute::AttrKind ImpliedAttributeKind,
3565 bool IgnoreSubsumingPositions = false) {
3566 // Note: This is also run for non-IPO amendable functions.
3567 assert(ImpliedAttributeKind == Attribute::MustProgress);
3568 return A.hasAttr(IRP, {Attribute::MustProgress, Attribute::WillReturn},
3569 IgnoreSubsumingPositions, Attribute::MustProgress);
3570 }
3571
3572 /// Return true if we assume that the underlying value is nonnull.
3573 bool isAssumedMustProgress() const { return getAssumed(); }
3574
3575 /// Return true if we know that underlying value is nonnull.
3576 bool isKnownMustProgress() const { return getKnown(); }
3577
3578 /// Create an abstract attribute view for the position \p IRP.
3580 Attributor &A);
3581
3582 StringRef getName() const override { return "AAMustProgress"; }
3583
3584 const char *getIdAddr() const override { return &ID; }
3585
3586 /// This function should return true if the type of the \p AA is
3587 /// AAMustProgress
3588 static bool classof(const AbstractAttribute *AA) {
3589 return (AA->getIdAddr() == &ID);
3590 }
3591
3592 /// Unique ID (due to the unique address)
3593 LLVM_ABI static const char ID;
3594};
3595
3596/// An abstract interface for all nonnull attributes.
3598 : public IRAttribute<Attribute::NonNull,
3599 StateWrapper<BooleanState, AbstractAttribute>,
3600 AANonNull> {
3602
3603 static bool hasTrivialInitializer() { return false; }
3604
3605 /// Undef is not necessarily nonnull as nonnull + noundef would cause poison.
3606 /// Poison implies nonnull though.
3607 static bool isImpliedByUndef() { return false; }
3608
3611 return false;
3612 return IRAttribute::isValidIRPositionForInit(A, IRP);
3613 }
3614
3615 LLVM_ABI static bool isImpliedByIR(Attributor &A, const IRPosition &IRP,
3616 Attribute::AttrKind ImpliedAttributeKind,
3617 bool IgnoreSubsumingPositions = false);
3618
3619 /// Return true if we assume that the underlying value is nonnull.
3620 bool isAssumedNonNull() const { return getAssumed(); }
3621
3622 /// Return true if we know that underlying value is nonnull.
3623 bool isKnownNonNull() const { return getKnown(); }
3624
3625 /// Create an abstract attribute view for the position \p IRP.
3627 Attributor &A);
3628
3629 StringRef getName() const override { return "AANonNull"; }
3630
3631 const char *getIdAddr() const override { return &ID; }
3632
3633 /// This function should return true if the type of the \p AA is AANonNull
3634 static bool classof(const AbstractAttribute *AA) {
3635 return (AA->getIdAddr() == &ID);
3636 }
3637
3638 /// Unique ID (due to the unique address)
3639 LLVM_ABI static const char ID;
3640};
3641
3642/// An abstract attribute for norecurse.
3644 : public IRAttribute<Attribute::NoRecurse,
3645 StateWrapper<BooleanState, AbstractAttribute>,
3646 AANoRecurse> {
3648
3649 /// Return true if "norecurse" is assumed.
3650 bool isAssumedNoRecurse() const { return getAssumed(); }
3651
3652 /// Return true if "norecurse" is known.
3653 bool isKnownNoRecurse() const { return getKnown(); }
3654
3655 /// Create an abstract attribute view for the position \p IRP.
3657 Attributor &A);
3658
3659 StringRef getName() const override { return "AANoRecurse"; }
3660
3661 const char *getIdAddr() const override { return &ID; }
3662
3663 /// This function should return true if the type of the \p AA is AANoRecurse
3664 static bool classof(const AbstractAttribute *AA) {
3665 return (AA->getIdAddr() == &ID);
3666 }
3667
3668 /// Unique ID (due to the unique address)
3669 LLVM_ABI static const char ID;
3670};
3671
3672/// An abstract attribute for willreturn.
3674 : public IRAttribute<Attribute::WillReturn,
3675 StateWrapper<BooleanState, AbstractAttribute>,
3676 AAWillReturn> {
3678
3679 static bool isImpliedByIR(Attributor &A, const IRPosition &IRP,
3680 Attribute::AttrKind ImpliedAttributeKind,
3681 bool IgnoreSubsumingPositions = false) {
3682 // Note: This is also run for non-IPO amendable functions.
3683 assert(ImpliedAttributeKind == Attribute::WillReturn);
3684 if (IRAttribute::isImpliedByIR(A, IRP, ImpliedAttributeKind,
3685 IgnoreSubsumingPositions))
3686 return true;
3688 return false;
3689 A.manifestAttrs(IRP, Attribute::get(IRP.getAnchorValue().getContext(),
3690 Attribute::WillReturn));
3691 return true;
3692 }
3693
3694 /// Check for `mustprogress` and `readonly` as they imply `willreturn`.
3696 const IRPosition &IRP) {
3697 // Check for `mustprogress` in the scope and the associated function which
3698 // might be different if this is a call site.
3699 if (!A.hasAttr(IRP, {Attribute::MustProgress}))
3700 return false;
3701
3703 A.getAttrs(IRP, {Attribute::Memory}, Attrs,
3704 /* IgnoreSubsumingPositions */ false);
3705
3707 for (const Attribute &Attr : Attrs)
3708 ME &= Attr.getMemoryEffects();
3709 return ME.onlyReadsMemory();
3710 }
3711
3712 /// Return true if "willreturn" is assumed.
3713 bool isAssumedWillReturn() const { return getAssumed(); }
3714
3715 /// Return true if "willreturn" is known.
3716 bool isKnownWillReturn() const { return getKnown(); }
3717
3718 /// Create an abstract attribute view for the position \p IRP.
3720 Attributor &A);
3721
3722 StringRef getName() const override { return "AAWillReturn"; }
3723
3724 const char *getIdAddr() const override { return &ID; }
3725
3726 /// This function should return true if the type of the \p AA is AAWillReturn
3727 static bool classof(const AbstractAttribute *AA) {
3728 return (AA->getIdAddr() == &ID);
3729 }
3730
3731 /// Unique ID (due to the unique address)
3732 LLVM_ABI static const char ID;
3733};
3734
3735/// An abstract attribute for undefined behavior.
3737 : public StateWrapper<BooleanState, AbstractAttribute> {
3740
3741 /// Return true if "undefined behavior" is assumed for a specific instruction.
3742 virtual bool isAssumedToCauseUB(Instruction *I) const = 0;
3743
3744 /// Return true if "undefined behavior" is known for a specific instruction.
3745 virtual bool isKnownToCauseUB(Instruction *I) const = 0;
3746
3747 /// Create an abstract attribute view for the position \p IRP.
3749 Attributor &A);
3750
3751 StringRef getName() const override { return "AAUndefinedBehavior"; }
3752
3753 const char *getIdAddr() const override { return &ID; }
3754
3755 /// This function should return true if the type of the \p AA is
3756 /// AAUndefineBehavior
3757 static bool classof(const AbstractAttribute *AA) {
3758 return (AA->getIdAddr() == &ID);
3759 }
3760
3761 /// Unique ID (due to the unique address)
3762 LLVM_ABI static const char ID;
3763};
3764
3765/// An abstract interface to determine reachability of point A to B.
3767 : public StateWrapper<BooleanState, AbstractAttribute> {
3770
3771 /// Returns true if 'From' instruction is assumed to reach, 'To' instruction.
3772 /// Users should provide two positions they are interested in, and the class
3773 /// determines (and caches) reachability.
3775 Attributor &A, const Instruction &From, const Instruction &To,
3776 const AA::InstExclusionSetTy *ExclusionSet = nullptr) const = 0;
3777
3778 /// Create an abstract attribute view for the position \p IRP.
3781
3782 StringRef getName() const override { return "AAIntraFnReachability"; }
3783
3784 const char *getIdAddr() const override { return &ID; }
3785
3786 /// This function should return true if the type of the \p AA is
3787 /// AAIntraFnReachability
3788 static bool classof(const AbstractAttribute *AA) {
3789 return (AA->getIdAddr() == &ID);
3790 }
3791
3792 /// Unique ID (due to the unique address)
3793 LLVM_ABI static const char ID;
3794};
3795
3796/// An abstract interface for all noalias attributes.
3798 : public IRAttribute<Attribute::NoAlias,
3799 StateWrapper<BooleanState, AbstractAttribute>,
3800 AANoAlias> {
3802
3804 if (!IRP.getAssociatedType()->isPointerTy())
3805 return false;
3806 return IRAttribute::isValidIRPositionForInit(A, IRP);
3807 }
3808
3809 LLVM_ABI static bool isImpliedByIR(Attributor &A, const IRPosition &IRP,
3810 Attribute::AttrKind ImpliedAttributeKind,
3811 bool IgnoreSubsumingPositions = false);
3812
3813 static bool requiresCallersForArgOrFunction() { return true; }
3814
3815 /// Return true if we assume that the underlying value is alias.
3816 bool isAssumedNoAlias() const { return getAssumed(); }
3817
3818 /// Return true if we know that underlying value is noalias.
3819 bool isKnownNoAlias() const { return getKnown(); }
3820
3821 /// Create an abstract attribute view for the position \p IRP.
3823 Attributor &A);
3824
3825 StringRef getName() const override { return "AANoAlias"; }
3826
3827 const char *getIdAddr() const override { return &ID; }
3828
3829 /// This function should return true if the type of the \p AA is AANoAlias
3830 static bool classof(const AbstractAttribute *AA) {
3831 return (AA->getIdAddr() == &ID);
3832 }
3833
3834 /// Unique ID (due to the unique address)
3835 LLVM_ABI static const char ID;
3836};
3837
3838/// An AbstractAttribute for nofree.
3840 : public IRAttribute<Attribute::NoFree,
3841 StateWrapper<BooleanState, AbstractAttribute>,
3842 AANoFree> {
3844
3845 static bool isImpliedByIR(Attributor &A, const IRPosition &IRP,
3846 Attribute::AttrKind ImpliedAttributeKind,
3847 bool IgnoreSubsumingPositions = false) {
3848 // Note: This is also run for non-IPO amendable functions.
3849 assert(ImpliedAttributeKind == Attribute::NoFree);
3850 return A.hasAttr(
3851 IRP, {Attribute::ReadNone, Attribute::ReadOnly, Attribute::NoFree},
3852 IgnoreSubsumingPositions, Attribute::NoFree);
3853 }
3854
3856 if (!IRP.isFunctionScope() &&
3858 return false;
3859 return IRAttribute::isValidIRPositionForInit(A, IRP);
3860 }
3861
3862 /// Return true if "nofree" is assumed.
3863 bool isAssumedNoFree() const { return getAssumed(); }
3864
3865 /// Return true if "nofree" is known.
3866 bool isKnownNoFree() const { return getKnown(); }
3867
3868 /// Create an abstract attribute view for the position \p IRP.
3870 Attributor &A);
3871
3872 StringRef getName() const override { return "AANoFree"; }
3873
3874 const char *getIdAddr() const override { return &ID; }
3875
3876 /// This function should return true if the type of the \p AA is AANoFree
3877 static bool classof(const AbstractAttribute *AA) {
3878 return (AA->getIdAddr() == &ID);
3879 }
3880
3881 /// Unique ID (due to the unique address)
3882 LLVM_ABI static const char ID;
3883};
3884
3885/// An AbstractAttribute for noreturn.
3887 : public IRAttribute<Attribute::NoReturn,
3888 StateWrapper<BooleanState, AbstractAttribute>,
3889 AANoReturn> {
3891
3892 /// Return true if the underlying object is assumed to never return.
3893 bool isAssumedNoReturn() const { return getAssumed(); }
3894
3895 /// Return true if the underlying object is known to never return.
3896 bool isKnownNoReturn() const { return getKnown(); }
3897
3898 /// Create an abstract attribute view for the position \p IRP.
3900 Attributor &A);
3901
3902 StringRef getName() const override { return "AANoReturn"; }
3903
3904 const char *getIdAddr() const override { return &ID; }
3905
3906 /// This function should return true if the type of the \p AA is AANoReturn
3907 static bool classof(const AbstractAttribute *AA) {
3908 return (AA->getIdAddr() == &ID);
3909 }
3910
3911 /// Unique ID (due to the unique address)
3912 LLVM_ABI static const char ID;
3913};
3914
3915/// An abstract interface for liveness abstract attribute.
3917 : public StateWrapper<BitIntegerState<uint8_t, 3, 0>, AbstractAttribute> {
3919 AAIsDead(const IRPosition &IRP, Attributor &A) : Base(IRP) {}
3920
3923 return isa<Function>(IRP.getAnchorValue()) &&
3924 !cast<Function>(IRP.getAnchorValue()).isDeclaration();
3925 return true;
3926 }
3927
3928 /// State encoding bits. A set bit in the state means the property holds.
3929 enum {
3932
3934 };
3935 static_assert(IS_DEAD == getBestState(), "Unexpected BEST_STATE value");
3936
3937protected:
3938 /// The query functions are protected such that other attributes need to go
3939 /// through the Attributor interfaces: `Attributor::isAssumedDead(...)`
3940
3941 /// Returns true if the underlying value is assumed dead.
3942 virtual bool isAssumedDead() const = 0;
3943
3944 /// Returns true if the underlying value is known dead.
3945 virtual bool isKnownDead() const = 0;
3946
3947 /// Returns true if \p BB is known dead.
3948 virtual bool isKnownDead(const BasicBlock *BB) const = 0;
3949
3950 /// Returns true if \p I is assumed dead.
3951 virtual bool isAssumedDead(const Instruction *I) const = 0;
3952
3953 /// Returns true if \p I is known dead.
3954 virtual bool isKnownDead(const Instruction *I) const = 0;
3955
3956 /// Return true if the underlying value is a store that is known to be
3957 /// removable. This is different from dead stores as the removable store
3958 /// can have an effect on live values, especially loads, but that effect
3959 /// is propagated which allows us to remove the store in turn.
3960 virtual bool isRemovableStore() const { return false; }
3961
3962public:
3963 /// Create an abstract attribute view for the position \p IRP.
3965 Attributor &A);
3966
3967 /// Determine if \p F might catch asynchronous exceptions.
3969 return F.hasPersonalityFn() && !canSimplifyInvokeNoUnwind(&F);
3970 }
3971
3972 /// Returns true if \p BB is assumed dead.
3973 virtual bool isAssumedDead(const BasicBlock *BB) const = 0;
3974
3975 /// Return if the edge from \p From BB to \p To BB is assumed dead.
3976 /// This is specifically useful in AAReachability.
3977 virtual bool isEdgeDead(const BasicBlock *From, const BasicBlock *To) const {
3978 return false;
3979 }
3980
3981 StringRef getName() const override { return "AAIsDead"; }
3982
3983 const char *getIdAddr() const override { return &ID; }
3984
3985 /// This function should return true if the type of the \p AA is AAIsDead
3986 static bool classof(const AbstractAttribute *AA) {
3987 return (AA->getIdAddr() == &ID);
3988 }
3989
3990 /// Unique ID (due to the unique address)
3991 LLVM_ABI static const char ID;
3992
3993 friend struct Attributor;
3994};
3995
3996/// State for dereferenceable attribute
3998
3999 static DerefState getBestState() { return DerefState(); }
4000 static DerefState getBestState(const DerefState &) { return getBestState(); }
4001
4002 /// Return the worst possible representable state.
4004 DerefState DS;
4005 DS.indicatePessimisticFixpoint();
4006 return DS;
4007 }
4009 return getWorstState();
4010 }
4011
4012 /// State representing for dereferenceable bytes.
4014
4015 /// Map representing for accessed memory offsets and sizes.
4016 /// A key is Offset and a value is size.
4017 /// If there is a load/store instruction something like,
4018 /// p[offset] = v;
4019 /// (offset, sizeof(v)) will be inserted to this map.
4020 /// std::map is used because we want to iterate keys in ascending order.
4021 std::map<int64_t, uint64_t> AccessedBytesMap;
4022
4023 /// Helper function to calculate dereferenceable bytes from current known
4024 /// bytes and accessed bytes.
4025 ///
4026 /// int f(int *A){
4027 /// *A = 0;
4028 /// *(A+2) = 2;
4029 /// *(A+1) = 1;
4030 /// *(A+10) = 10;
4031 /// }
4032 /// ```
4033 /// In that case, AccessedBytesMap is `{0:4, 4:4, 8:4, 40:4}`.
4034 /// AccessedBytesMap is std::map so it is iterated in accending order on
4035 /// key(Offset). So KnownBytes will be updated like this:
4036 ///
4037 /// |Access | KnownBytes
4038 /// |(0, 4)| 0 -> 4
4039 /// |(4, 4)| 4 -> 8
4040 /// |(8, 4)| 8 -> 12
4041 /// |(40, 4) | 12 (break)
4042 void computeKnownDerefBytesFromAccessedMap() {
4043 int64_t KnownBytes = DerefBytesState.getKnown();
4044 for (auto &Access : AccessedBytesMap) {
4045 if (KnownBytes < Access.first)
4046 break;
4047 KnownBytes = std::max(KnownBytes, Access.first + (int64_t)Access.second);
4048 }
4049
4050 DerefBytesState.takeKnownMaximum(KnownBytes);
4051 }
4052
4053 /// State representing that whether the value is globaly dereferenceable.
4054 BooleanState GlobalState;
4055
4056 bool isValidState() const override { return DerefBytesState.isValidState(); }
4057
4058 bool isAtFixpoint() const override {
4059 return !isValidState() ||
4060 (DerefBytesState.isAtFixpoint() && GlobalState.isAtFixpoint());
4061 }
4062
4064 DerefBytesState.indicateOptimisticFixpoint();
4065 GlobalState.indicateOptimisticFixpoint();
4067 }
4068
4070 DerefBytesState.indicatePessimisticFixpoint();
4071 GlobalState.indicatePessimisticFixpoint();
4072 return ChangeStatus::CHANGED;
4073 }
4074
4075 /// Update known dereferenceable bytes.
4076 void takeKnownDerefBytesMaximum(uint64_t Bytes) {
4077 DerefBytesState.takeKnownMaximum(Bytes);
4078
4079 // Known bytes might increase.
4080 computeKnownDerefBytesFromAccessedMap();
4081 }
4082
4083 /// Update assumed dereferenceable bytes.
4084 void takeAssumedDerefBytesMinimum(uint64_t Bytes) {
4085 DerefBytesState.takeAssumedMinimum(Bytes);
4086 }
4087
4088 /// Add accessed bytes to the map.
4089 void addAccessedBytes(int64_t Offset, uint64_t Size) {
4090 uint64_t &AccessedBytes = AccessedBytesMap[Offset];
4091 AccessedBytes = std::max(AccessedBytes, Size);
4092
4093 // Known bytes might increase.
4094 computeKnownDerefBytesFromAccessedMap();
4095 }
4096
4097 /// Equality for DerefState.
4098 bool operator==(const DerefState &R) const {
4099 return this->DerefBytesState == R.DerefBytesState &&
4100 this->GlobalState == R.GlobalState;
4101 }
4102
4103 /// Inequality for DerefState.
4104 bool operator!=(const DerefState &R) const { return !(*this == R); }
4105
4106 /// See IntegerStateBase::operator^=
4107 DerefState operator^=(const DerefState &R) {
4108 DerefBytesState ^= R.DerefBytesState;
4109 GlobalState ^= R.GlobalState;
4110 return *this;
4111 }
4112
4113 /// See IntegerStateBase::operator+=
4114 DerefState operator+=(const DerefState &R) {
4115 DerefBytesState += R.DerefBytesState;
4116 GlobalState += R.GlobalState;
4117 return *this;
4118 }
4119
4120 /// See IntegerStateBase::operator&=
4121 DerefState operator&=(const DerefState &R) {
4122 DerefBytesState &= R.DerefBytesState;
4123 GlobalState &= R.GlobalState;
4124 return *this;
4125 }
4126
4127 /// See IntegerStateBase::operator|=
4128 DerefState operator|=(const DerefState &R) {
4129 DerefBytesState |= R.DerefBytesState;
4130 GlobalState |= R.GlobalState;
4131 return *this;
4132 }
4133};
4134
4135/// An abstract interface for all dereferenceable attribute.
4137 : public IRAttribute<Attribute::Dereferenceable,
4138 StateWrapper<DerefState, AbstractAttribute>,
4139 AADereferenceable> {
4141
4143 if (!IRP.getAssociatedType()->isPointerTy())
4144 return false;
4145 return IRAttribute::isValidIRPositionForInit(A, IRP);
4146 }
4147
4148 /// Return true if we assume that underlying value is
4149 /// dereferenceable(_or_null) globally.
4150 bool isAssumedGlobal() const { return GlobalState.getAssumed(); }
4151
4152 /// Return true if we know that underlying value is
4153 /// dereferenceable(_or_null) globally.
4154 bool isKnownGlobal() const { return GlobalState.getKnown(); }
4155
4156 /// Return assumed dereferenceable bytes.
4158 return DerefBytesState.getAssumed();
4159 }
4160
4161 /// Return known dereferenceable bytes.
4163 return DerefBytesState.getKnown();
4164 }
4165
4166 /// Create an abstract attribute view for the position \p IRP.
4168 Attributor &A);
4169
4170 StringRef getName() const override { return "AADereferenceable"; }
4171
4172 const char *getIdAddr() const override { return &ID; }
4173
4174 /// This function should return true if the type of the \p AA is
4175 /// AADereferenceable
4176 static bool classof(const AbstractAttribute *AA) {
4177 return (AA->getIdAddr() == &ID);
4178 }
4179
4180 /// Unique ID (due to the unique address)
4181 LLVM_ABI static const char ID;
4182};
4183
4186/// An abstract interface for all align attributes.
4188 : public IRAttribute<Attribute::Alignment,
4189 StateWrapper<AAAlignmentStateType, AbstractAttribute>,
4190 AAAlign> {
4192
4195 return false;
4196 return IRAttribute::isValidIRPositionForInit(A, IRP);
4197 }
4198
4199 /// Return assumed alignment.
4200 Align getAssumedAlign() const { return Align(getAssumed()); }
4201
4202 /// Return known alignment.
4203 Align getKnownAlign() const { return Align(getKnown()); }
4204
4205 StringRef getName() const override { return "AAAlign"; }
4206
4207 const char *getIdAddr() const override { return &ID; }
4208
4209 /// This function should return true if the type of the \p AA is AAAlign
4210 static bool classof(const AbstractAttribute *AA) {
4211 return (AA->getIdAddr() == &ID);
4212 }
4213
4214 /// Create an abstract attribute view for the position \p IRP.
4216 Attributor &A);
4217
4218 /// Unique ID (due to the unique address)
4219 LLVM_ABI static const char ID;
4220};
4221
4222/// An abstract interface to track if a value leaves it's defining function
4223/// instance.
4224/// TODO: We should make it a ternary AA tracking uniqueness, and uniqueness
4225/// wrt. the Attributor analysis separately.
4226struct AAInstanceInfo : public StateWrapper<BooleanState, AbstractAttribute> {
4229
4230 /// Return true if we assume that the underlying value is unique in its scope
4231 /// wrt. the Attributor analysis. That means it might not be unique but we can
4232 /// still use pointer equality without risking to represent two instances with
4233 /// one `llvm::Value`.
4234 bool isAssumedUniqueForAnalysis() const { return isAssumed(); }
4235
4236 /// Create an abstract attribute view for the position \p IRP.
4238 Attributor &A);
4239
4240 StringRef getName() const override { return "AAInstanceInfo"; }
4241
4242 const char *getIdAddr() const override { return &ID; }
4243
4244 /// This function should return true if the type of the \p AA is
4245 /// AAInstanceInfo
4246 static bool classof(const AbstractAttribute *AA) {
4247 return (AA->getIdAddr() == &ID);
4248 }
4249
4250 /// Unique ID (due to the unique address)
4251 LLVM_ABI static const char ID;
4252};
4253
4254/// An abstract interface for all nocapture attributes.
4256 : public IRAttribute<
4257 Attribute::Captures,
4258 StateWrapper<BitIntegerState<uint16_t, 7, 0>, AbstractAttribute>,
4259 AANoCapture> {
4261
4262 LLVM_ABI static bool isImpliedByIR(Attributor &A, const IRPosition &IRP,
4263 Attribute::AttrKind ImpliedAttributeKind,
4264 bool IgnoreSubsumingPositions = false);
4265
4266 /// Update \p State according to the capture capabilities of \p F for position
4267 /// \p IRP.
4268 LLVM_ABI static void
4270 BitIntegerState &State);
4271
4273 if (!IRP.getAssociatedType()->isPointerTy())
4274 return false;
4275 return IRAttribute::isValidIRPositionForInit(A, IRP);
4276 }
4277
4278 /// State encoding bits. A set bit in the state means the property holds.
4279 /// NO_CAPTURE is the best possible state, 0 the worst possible state.
4280 enum {
4284
4285 /// If we do not capture the value in memory or through integers we can only
4286 /// communicate it back as a derived pointer.
4288
4289 /// If we do not capture the value in memory, through integers, or as a
4290 /// derived pointer we know it is not captured.
4293 };
4294
4295 /// Return true if we know that the underlying value is not captured in its
4296 /// respective scope.
4297 bool isKnownNoCapture() const { return isKnown(NO_CAPTURE); }
4298
4299 /// Return true if we assume that the underlying value is not captured in its
4300 /// respective scope.
4301 bool isAssumedNoCapture() const { return isAssumed(NO_CAPTURE); }
4302
4303 /// Return true if we know that the underlying value is not captured in its
4304 /// respective scope but we allow it to escape through a "return".
4308
4309 /// Return true if we assume that the underlying value is not captured in its
4310 /// respective scope but we allow it to escape through a "return".
4314
4315 /// Create an abstract attribute view for the position \p IRP.
4317 Attributor &A);
4318
4319 StringRef getName() const override { return "AANoCapture"; }
4320
4321 const char *getIdAddr() const override { return &ID; }
4322
4323 /// This function should return true if the type of the \p AA is AANoCapture
4324 static bool classof(const AbstractAttribute *AA) {
4325 return (AA->getIdAddr() == &ID);
4326 }
4327
4328 /// Unique ID (due to the unique address)
4329 LLVM_ABI static const char ID;
4330};
4331
4333
4335
4340 return getBestState(VS.Ty);
4341 }
4342
4343 /// Return the worst possible representable state.
4346 DS.indicatePessimisticFixpoint();
4347 return DS;
4348 }
4351 return getWorstState(VS.Ty);
4352 }
4353
4354 bool isValidState() const override { return BS.isValidState(); }
4355
4356 bool isAtFixpoint() const override { return BS.isAtFixpoint(); }
4357
4358 /// Return the assumed state encoding.
4360 const ValueSimplifyStateType &getAssumed() const { return *this; }
4361
4363 return BS.indicatePessimisticFixpoint();
4364 }
4365
4367 return BS.indicateOptimisticFixpoint();
4368 }
4369
4370 /// "Clamp" this state with \p PVS.
4372 BS ^= VS.BS;
4373 unionAssumed(VS.SimplifiedAssociatedValue);
4374 return *this;
4375 }
4376
4378 if (isValidState() != RHS.isValidState())
4379 return false;
4380 if (!isValidState() && !RHS.isValidState())
4381 return true;
4382 return SimplifiedAssociatedValue == RHS.SimplifiedAssociatedValue;
4383 }
4384
4385protected:
4386 /// The type of the original value.
4388
4389 /// Merge \p Other into the currently assumed simplified value
4390 LLVM_ABI bool unionAssumed(std::optional<Value *> Other);
4391
4392 /// Helper to track validity and fixpoint
4394
4395 /// An assumed simplified value. Initially, it is set to std::nullopt, which
4396 /// means that the value is not clear under current assumption. If in the
4397 /// pessimistic state, getAssumedSimplifiedValue doesn't return this value but
4398 /// returns orignal associated value.
4399 std::optional<Value *> SimplifiedAssociatedValue;
4400};
4401
4402/// An abstract interface for value simplify abstract attribute.
4404 : public StateWrapper<ValueSimplifyStateType, AbstractAttribute, Type *> {
4407 : Base(IRP, IRP.getAssociatedType()) {}
4408
4409 /// Create an abstract attribute view for the position \p IRP.
4411 Attributor &A);
4412
4413 StringRef getName() const override { return "AAValueSimplify"; }
4414
4415 const char *getIdAddr() const override { return &ID; }
4416
4417 /// This function should return true if the type of the \p AA is
4418 /// AAValueSimplify
4419 static bool classof(const AbstractAttribute *AA) {
4420 return (AA->getIdAddr() == &ID);
4421 }
4422
4423 /// Unique ID (due to the unique address)
4424 LLVM_ABI static const char ID;
4425
4426private:
4427 /// Return an assumed simplified value if a single candidate is found. If
4428 /// there cannot be one, return original value. If it is not clear yet, return
4429 /// std::nullopt.
4430 ///
4431 /// Use `Attributor::getAssumedSimplified` for value simplification.
4432 virtual std::optional<Value *>
4433 getAssumedSimplifiedValue(Attributor &A) const = 0;
4434
4435 friend struct Attributor;
4436};
4437
4438struct AAHeapToStack : public StateWrapper<BooleanState, AbstractAttribute> {
4440 AAHeapToStack(const IRPosition &IRP, Attributor &A) : Base(IRP) {}
4441
4442 /// Returns true if HeapToStack conversion is assumed to be possible.
4443 virtual bool isAssumedHeapToStack(const CallBase &CB) const = 0;
4444
4445 /// Returns true if HeapToStack conversion is assumed and the CB is a
4446 /// callsite to a free operation to be removed.
4447 virtual bool isAssumedHeapToStackRemovedFree(CallBase &CB) const = 0;
4448
4449 /// Create an abstract attribute view for the position \p IRP.
4451 Attributor &A);
4452
4453 StringRef getName() const override { return "AAHeapToStack"; }
4454
4455 const char *getIdAddr() const override { return &ID; }
4456
4457 /// This function should return true if the type of the \p AA is AAHeapToStack
4458 static bool classof(const AbstractAttribute *AA) {
4459 return (AA->getIdAddr() == &ID);
4460 }
4461
4462 /// Unique ID (due to the unique address)
4463 LLVM_ABI static const char ID;
4464};
4465
4466/// An abstract interface for privatizability.
4467///
4468/// A pointer is privatizable if it can be replaced by a new, private one.
4469/// Privatizing pointer reduces the use count, interaction between unrelated
4470/// code parts.
4471///
4472/// In order for a pointer to be privatizable its value cannot be observed
4473/// (=nocapture), it is (for now) not written (=readonly & noalias), we know
4474/// what values are necessary to make the private copy look like the original
4475/// one, and the values we need can be loaded (=dereferenceable).
4477 : public StateWrapper<BooleanState, AbstractAttribute> {
4480
4483 return false;
4485 }
4486
4487 /// Returns true if pointer privatization is assumed to be possible.
4488 bool isAssumedPrivatizablePtr() const { return getAssumed(); }
4489
4490 static bool requiresCallersForArgOrFunction() { return true; }
4491
4492 /// Return the type we can choose for a private copy of the underlying
4493 /// value. std::nullopt means it is not clear yet, nullptr means there is
4494 /// none.
4495 virtual std::optional<Type *> getPrivatizableType() const = 0;
4496
4497 /// Create an abstract attribute view for the position \p IRP.
4499 Attributor &A);
4500
4501 StringRef getName() const override { return "AAPrivatizablePtr"; }
4502
4503 const char *getIdAddr() const override { return &ID; }
4504
4505 /// This function should return true if the type of the \p AA is
4506 /// AAPricatizablePtr
4507 static bool classof(const AbstractAttribute *AA) {
4508 return (AA->getIdAddr() == &ID);
4509 }
4510
4511 /// Unique ID (due to the unique address)
4512 LLVM_ABI static const char ID;
4513};
4514
4515/// An abstract interface for memory access kind related attributes
4516/// (readnone/readonly/writeonly).
4518 : public IRAttribute<
4519 Attribute::None,
4520 StateWrapper<BitIntegerState<uint8_t, 3>, AbstractAttribute>,
4521 AAMemoryBehavior> {
4523
4524 static bool hasTrivialInitializer() { return false; }
4525
4527 if (!IRP.isFunctionScope() && !IRP.getAssociatedType()->isPointerTy())
4528 return false;
4529 return IRAttribute::isValidIRPositionForInit(A, IRP);
4530 }
4531
4532 /// State encoding bits. A set bit in the state means the property holds.
4533 /// BEST_STATE is the best possible state, 0 the worst possible state.
4534 enum {
4535 NO_READS = 1 << 0,
4536 NO_WRITES = 1 << 1,
4538
4540 };
4541 static_assert(BEST_STATE == getBestState(), "Unexpected BEST_STATE value");
4542
4543 /// Return true if we know that the underlying value is not read or accessed
4544 /// in its respective scope.
4545 bool isKnownReadNone() const { return isKnown(NO_ACCESSES); }
4546
4547 /// Return true if we assume that the underlying value is not read or accessed
4548 /// in its respective scope.
4549 bool isAssumedReadNone() const { return isAssumed(NO_ACCESSES); }
4550
4551 /// Return true if we know that the underlying value is not accessed
4552 /// (=written) in its respective scope.
4553 bool isKnownReadOnly() const { return isKnown(NO_WRITES); }
4554
4555 /// Return true if we assume that the underlying value is not accessed
4556 /// (=written) in its respective scope.
4557 bool isAssumedReadOnly() const { return isAssumed(NO_WRITES); }
4558
4559 /// Return true if we know that the underlying value is not read in its
4560 /// respective scope.
4561 bool isKnownWriteOnly() const { return isKnown(NO_READS); }
4562
4563 /// Return true if we assume that the underlying value is not read in its
4564 /// respective scope.
4565 bool isAssumedWriteOnly() const { return isAssumed(NO_READS); }
4566
4567 /// Create an abstract attribute view for the position \p IRP.
4569 Attributor &A);
4570
4571 StringRef getName() const override { return "AAMemoryBehavior"; }
4572
4573 const char *getIdAddr() const override { return &ID; }
4574
4575 /// This function should return true if the type of the \p AA is
4576 /// AAMemoryBehavior
4577 static bool classof(const AbstractAttribute *AA) {
4578 return (AA->getIdAddr() == &ID);
4579 }
4580
4581 /// Unique ID (due to the unique address)
4582 LLVM_ABI static const char ID;
4583};
4584
4585/// An abstract interface for all memory location attributes
4586/// (readnone/argmemonly/inaccessiblememonly/inaccessibleorargmemonly).
4588 : public IRAttribute<
4589 Attribute::None,
4590 StateWrapper<BitIntegerState<uint32_t, 511>, AbstractAttribute>,
4591 AAMemoryLocation> {
4592 using MemoryLocationsKind = StateType::base_t;
4593
4595
4596 static bool requiresCalleeForCallBase() { return true; }
4597
4598 static bool hasTrivialInitializer() { return false; }
4599
4601 if (!IRP.isFunctionScope() &&
4603 return false;
4604 return IRAttribute::isValidIRPositionForInit(A, IRP);
4605 }
4606
4607 /// Encoding of different locations that could be accessed by a memory
4608 /// access.
4609 enum {
4623
4624 // Helper bit to track if we gave up or not.
4626
4628 };
4629 static_assert(BEST_STATE == getBestState(), "Unexpected BEST_STATE value");
4630
4631 /// Return true if we know that the associated functions has no observable
4632 /// accesses.
4633 bool isKnownReadNone() const { return isKnown(NO_LOCATIONS); }
4634
4635 /// Return true if we assume that the associated functions has no observable
4636 /// accesses.
4637 bool isAssumedReadNone() const {
4639 }
4640
4641 /// Return true if we know that the associated functions has at most
4642 /// local/stack accesses.
4643 bool isKnowStackOnly() const {
4644 return isKnown(inverseLocation(NO_LOCAL_MEM, true, true));
4645 }
4646
4647 /// Return true if we assume that the associated functions has at most
4648 /// local/stack accesses.
4649 bool isAssumedStackOnly() const {
4650 return isAssumed(inverseLocation(NO_LOCAL_MEM, true, true));
4651 }
4652
4653 /// Return true if we know that the underlying value will only access
4654 /// inaccesible memory only (see Attribute::InaccessibleMemOnly).
4656 return isKnown(inverseLocation(NO_INACCESSIBLE_MEM, true, true));
4657 }
4658
4659 /// Return true if we assume that the underlying value will only access
4660 /// inaccesible memory only (see Attribute::InaccessibleMemOnly).
4662 return isAssumed(inverseLocation(NO_INACCESSIBLE_MEM, true, true));
4663 }
4664
4665 /// Return true if we know that the underlying value will only access
4666 /// argument pointees (see Attribute::ArgMemOnly).
4667 bool isKnownArgMemOnly() const {
4668 return isKnown(inverseLocation(NO_ARGUMENT_MEM, true, true));
4669 }
4670
4671 /// Return true if we assume that the underlying value will only access
4672 /// argument pointees (see Attribute::ArgMemOnly).
4673 bool isAssumedArgMemOnly() const {
4674 return isAssumed(inverseLocation(NO_ARGUMENT_MEM, true, true));
4675 }
4676
4677 /// Return true if we know that the underlying value will only access
4678 /// inaccesible memory or argument pointees (see
4679 /// Attribute::InaccessibleOrArgMemOnly).
4681 return isKnown(
4683 }
4684
4685 /// Return true if we assume that the underlying value will only access
4686 /// inaccesible memory or argument pointees (see
4687 /// Attribute::InaccessibleOrArgMemOnly).
4692
4693 /// Return true if the underlying value may access memory through arguement
4694 /// pointers of the associated function, if any.
4695 bool mayAccessArgMem() const { return !isAssumed(NO_ARGUMENT_MEM); }
4696
4697 /// Return true if only the memory locations specififed by \p MLK are assumed
4698 /// to be accessed by the associated function.
4700 return isAssumed(MLK);
4701 }
4702
4703 /// Return the locations that are assumed to be not accessed by the associated
4704 /// function, if any.
4708
4709 /// Return the inverse of location \p Loc, thus for NO_XXX the return
4710 /// describes ONLY_XXX. The flags \p AndLocalMem and \p AndConstMem determine
4711 /// if local (=stack) and constant memory are allowed as well. Most of the
4712 /// time we do want them to be included, e.g., argmemonly allows accesses via
4713 /// argument pointers or local or constant memory accesses.
4714 static MemoryLocationsKind
4715 inverseLocation(MemoryLocationsKind Loc, bool AndLocalMem, bool AndConstMem) {
4716 return NO_LOCATIONS & ~(Loc | (AndLocalMem ? NO_LOCAL_MEM : 0) |
4717 (AndConstMem ? NO_CONST_MEM : 0));
4718 };
4719
4720 /// Return the locations encoded by \p MLK as a readable string.
4722
4723 /// Simple enum to distinguish read/write/read-write accesses.
4725 NONE = 0,
4726 READ = 1 << 0,
4727 WRITE = 1 << 1,
4729 };
4730
4731 /// Check \p Pred on all accesses to the memory kinds specified by \p MLK.
4732 ///
4733 /// This method will evaluate \p Pred on all accesses (access instruction +
4734 /// underlying accessed memory pointer) and it will return true if \p Pred
4735 /// holds every time.
4737 function_ref<bool(const Instruction *, const Value *, AccessKind,
4739 Pred,
4740 MemoryLocationsKind MLK) const = 0;
4741
4742 /// Create an abstract attribute view for the position \p IRP.
4744 Attributor &A);
4745
4746 const std::string getAsStr(Attributor *A) const override {
4748 }
4749
4750 StringRef getName() const override { return "AAMemoryLocation"; }
4751
4752 const char *getIdAddr() const override { return &ID; }
4753
4754 /// This function should return true if the type of the \p AA is
4755 /// AAMemoryLocation
4756 static bool classof(const AbstractAttribute *AA) {
4757 return (AA->getIdAddr() == &ID);
4758 }
4759
4760 /// Unique ID (due to the unique address)
4761 LLVM_ABI static const char ID;
4762};
4763
4764/// An abstract interface for range value analysis.
4766 : public StateWrapper<IntegerRangeState, AbstractAttribute, uint32_t> {
4769 : Base(IRP, IRP.getAssociatedType()->getIntegerBitWidth()) {}
4770
4772 if (!IRP.getAssociatedType()->isIntegerTy())
4773 return false;
4775 }
4776
4777 static bool requiresCallersForArgOrFunction() { return true; }
4778
4779 IntegerRangeState &getState() override { return *this; }
4780 const IntegerRangeState &getState() const override { return *this; }
4781
4782 /// Create an abstract attribute view for the position \p IRP.
4784 Attributor &A);
4785
4786 /// Return an assumed range for the associated value a program point \p CtxI.
4787 /// If \p I is nullptr, simply return an assumed range.
4788 virtual ConstantRange
4790 const Instruction *CtxI = nullptr) const = 0;
4791
4792 /// Return an assumed constant for the associated value a program point \p
4793 /// CtxI.
4794 std::optional<Constant *>
4795 getAssumedConstant(Attributor &A, const Instruction *CtxI = nullptr) const {
4796 ConstantRange RangeV = getAssumedConstantRange(A, CtxI);
4797 if (auto *C = RangeV.getSingleElement()) {
4800 AA::getWithType(*ConstantInt::get(Ty->getContext(), *C), *Ty));
4801 }
4802 if (RangeV.isEmptySet())
4803 return std::nullopt;
4804 return nullptr;
4805 }
4806
4807 StringRef getName() const override { return "AAValueConstantRange"; }
4808
4809 const char *getIdAddr() const override { return &ID; }
4810
4811 /// This function should return true if the type of the \p AA is
4812 /// AAValueConstantRange
4813 static bool classof(const AbstractAttribute *AA) {
4814 return (AA->getIdAddr() == &ID);
4815 }
4816
4817 /// Unique ID (due to the unique address)
4818 LLVM_ABI static const char ID;
4819};
4820
4821/// A class for a set state.
4822/// The assumed boolean state indicates whether the corresponding set is full
4823/// set or not. If the assumed state is false, this is the worst state. The
4824/// worst state (invalid state) of set of potential values is when the set
4825/// contains every possible value (i.e. we cannot in any way limit the value
4826/// that the target position can take). That never happens naturally, we only
4827/// force it. As for the conditions under which we force it, see
4828/// AAPotentialConstantValues.
4829template <typename MemberTy> struct PotentialValuesState : AbstractState {
4831
4832 PotentialValuesState() : IsValidState(true), UndefIsContained(false) {}
4833
4835 : IsValidState(IsValid), UndefIsContained(false) {}
4836
4837 bool isValidState() const override { return IsValidState.isValidState(); }
4838
4839 bool isAtFixpoint() const override { return IsValidState.isAtFixpoint(); }
4840
4842 return IsValidState.indicatePessimisticFixpoint();
4843 }
4844
4846 return IsValidState.indicateOptimisticFixpoint();
4847 }
4848
4849 /// Return the assumed state
4851 const PotentialValuesState &getAssumed() const { return *this; }
4852
4853 /// Return this set. We should check whether this set is valid or not by
4854 /// isValidState() before calling this function.
4855 const SetTy &getAssumedSet() const {
4856 assert(isValidState() && "This set shoud not be used when it is invalid!");
4857 return Set;
4858 }
4859
4860 /// Returns whether this state contains an undef value or not.
4861 bool undefIsContained() const {
4862 assert(isValidState() && "This flag shoud not be used when it is invalid!");
4863 return UndefIsContained;
4864 }
4865
4867 if (isValidState() != RHS.isValidState())
4868 return false;
4869 if (!isValidState() && !RHS.isValidState())
4870 return true;
4871 if (undefIsContained() != RHS.undefIsContained())
4872 return false;
4873 return Set == RHS.getAssumedSet();
4874 }
4875
4876 /// Maximum number of potential values to be tracked.
4877 /// This is set by -attributor-max-potential-values command line option
4878 static unsigned MaxPotentialValues;
4879
4880 /// Return empty set as the best state of potential values.
4882 return PotentialValuesState(true);
4883 }
4884
4886 return getBestState();
4887 }
4888
4889 /// Return full set as the worst state of potential values.
4891 return PotentialValuesState(false);
4892 }
4893
4894 /// Union assumed set with the passed value.
4895 void unionAssumed(const MemberTy &C) { insert(C); }
4896
4897 /// Union assumed set with assumed set of the passed state \p PVS.
4898 void unionAssumed(const PotentialValuesState &PVS) { unionWith(PVS); }
4899
4900 /// Union assumed set with an undef value.
4901 void unionAssumedWithUndef() { unionWithUndef(); }
4902
4903 /// "Clamp" this state with \p PVS.
4905 IsValidState ^= PVS.IsValidState;
4906 unionAssumed(PVS);
4907 return *this;
4908 }
4909
4911 IsValidState &= PVS.IsValidState;
4912 unionAssumed(PVS);
4913 return *this;
4914 }
4915
4916protected:
4918 assert(isValidState() && "This set shoud not be used when it is invalid!");
4919 return Set;
4920 }
4921
4922private:
4923 /// Check the size of this set, and invalidate when the size is no
4924 /// less than \p MaxPotentialValues threshold.
4925 void checkAndInvalidate() {
4926 if (Set.size() >= MaxPotentialValues)
4928 else
4929 reduceUndefValue();
4930 }
4931
4932 /// If this state contains both undef and not undef, we can reduce
4933 /// undef to the not undef value.
4934 void reduceUndefValue() { UndefIsContained = UndefIsContained & Set.empty(); }
4935
4936 /// Insert an element into this set.
4937 void insert(const MemberTy &C) {
4938 if (!isValidState())
4939 return;
4940 Set.insert(C);
4941 checkAndInvalidate();
4942 }
4943
4944 /// Take union with R.
4945 void unionWith(const PotentialValuesState &R) {
4946 /// If this is a full set, do nothing.
4947 if (!isValidState())
4948 return;
4949 /// If R is full set, change L to a full set.
4950 if (!R.isValidState()) {
4952 return;
4953 }
4954 Set.insert_range(R.Set);
4955 UndefIsContained |= R.undefIsContained();
4956 checkAndInvalidate();
4957 }
4958
4959 /// Take union with an undef value.
4960 void unionWithUndef() {
4961 UndefIsContained = true;
4962 reduceUndefValue();
4963 }
4964
4965 /// A helper state which indicate whether this state is valid or not.
4966 BooleanState IsValidState;
4967
4968 /// Container for potential values
4969 SetTy Set;
4970
4971 /// Flag for undef value
4972 bool UndefIsContained;
4973};
4974
4979
4980 bool operator==(const DenormalState Other) const {
4981 return Mode == Other.Mode && ModeF32 == Other.ModeF32;
4982 }
4983
4984 bool operator!=(const DenormalState Other) const {
4985 return Mode != Other.Mode || ModeF32 != Other.ModeF32;
4986 }
4987
4988 bool isValid() const { return Mode.isValid() && ModeF32.isValid(); }
4989
4993 if (Caller == Callee)
4994 return Caller;
4995 if (Callee == DenormalMode::Dynamic)
4996 return Caller;
4997 if (Caller == DenormalMode::Dynamic)
4998 return Callee;
4999 return DenormalMode::Invalid;
5000 }
5001
5003 return DenormalMode{unionDenormalKind(Callee.Output, Caller.Output),
5004 unionDenormalKind(Callee.Input, Caller.Input)};
5005 }
5006
5008 DenormalState Callee(*this);
5009 Callee.Mode = unionAssumed(Callee.Mode, Caller.Mode);
5010 Callee.ModeF32 = unionAssumed(Callee.ModeF32, Caller.ModeF32);
5011 return Callee;
5012 }
5013 };
5014
5016
5017 /// Explicitly track whether we've hit a fixed point.
5018 bool IsAtFixedpoint = false;
5019
5021
5022 DenormalState getKnown() const { return Known; }
5023
5024 // There's only really known or unknown, there's no speculatively assumable
5025 // state.
5026 DenormalState getAssumed() const { return Known; }
5027
5028 bool isValidState() const override { return Known.isValid(); }
5029
5030 /// Return true if there are no dynamic components to the denormal mode worth
5031 /// specializing.
5032 bool isModeFixed() const {
5033 return Known.Mode.Input != DenormalMode::Dynamic &&
5034 Known.Mode.Output != DenormalMode::Dynamic &&
5035 Known.ModeF32.Input != DenormalMode::Dynamic &&
5036 Known.ModeF32.Output != DenormalMode::Dynamic;
5037 }
5038
5039 bool isAtFixpoint() const override { return IsAtFixedpoint; }
5040
5046
5050
5054
5056 Known = Known.unionWith(Caller.getKnown());
5057 return *this;
5058 }
5059};
5060
5064
5068 const PotentialLLVMValuesState &R);
5069
5070/// An abstract interface for potential values analysis.
5071///
5072/// This AA collects potential values for each IR position.
5073/// An assumed set of potential values is initialized with the empty set (the
5074/// best state) and it will grow monotonically as we find more potential values
5075/// for this position.
5076/// The set might be forced to the worst state, that is, to contain every
5077/// possible value for this position in 2 cases.
5078/// 1. We surpassed the \p MaxPotentialValues threshold. This includes the
5079/// case that this position is affected (e.g. because of an operation) by a
5080/// Value that is in the worst state.
5081/// 2. We tried to initialize on a Value that we cannot handle (e.g. an
5082/// operator we do not currently handle).
5083///
5084/// For non constant integers see AAPotentialValues.
5086 : public StateWrapper<PotentialConstantIntValuesState, AbstractAttribute> {
5089
5091 if (!IRP.getAssociatedType()->isIntegerTy())
5092 return false;
5094 }
5095
5096 static bool requiresCallersForArgOrFunction() { return true; }
5097
5098 PotentialConstantIntValuesState &getState() override { return *this; }
5100 return *this;
5101 }
5102
5103 /// Create an abstract attribute view for the position \p IRP.
5106
5107 /// Return assumed constant for the associated value
5108 std::optional<Constant *>
5109 getAssumedConstant(Attributor &A, const Instruction *CtxI = nullptr) const {
5110 if (!isValidState())
5111 return nullptr;
5112 if (getAssumedSet().size() == 1) {
5115 *ConstantInt::get(Ty->getContext(), *(getAssumedSet().begin())),
5116 *Ty));
5117 }
5118 if (getAssumedSet().size() == 0) {
5119 if (undefIsContained())
5121 return std::nullopt;
5122 }
5123
5124 return nullptr;
5125 }
5126
5127 /// Return the minimum trailing zeros of potential constants
5129 if (!isValidState() || getAssumedSet().empty())
5130 return 0;
5131 unsigned TrailingZeros = getAssumedSet().begin()->getBitWidth() + 1;
5132 for (const APInt &It : getAssumedSet()) {
5133 if (It.countTrailingZeros() < TrailingZeros)
5134 TrailingZeros = It.countTrailingZeros();
5135 }
5136 if (TrailingZeros > getAssumedSet().begin()->getBitWidth())
5137 return 0;
5138 return TrailingZeros;
5139 }
5140 StringRef getName() const override { return "AAPotentialConstantValues"; }
5141
5142 const char *getIdAddr() const override { return &ID; }
5143
5144 /// This function should return true if the type of the \p AA is
5145 /// AAPotentialConstantValues
5146 static bool classof(const AbstractAttribute *AA) {
5147 return (AA->getIdAddr() == &ID);
5148 }
5149
5150 /// Unique ID (due to the unique address)
5151 LLVM_ABI static const char ID;
5152};
5153
5155 : public StateWrapper<PotentialLLVMValuesState, AbstractAttribute> {
5158
5159 static bool requiresCallersForArgOrFunction() { return true; }
5160
5161 PotentialLLVMValuesState &getState() override { return *this; }
5162 const PotentialLLVMValuesState &getState() const override { return *this; }
5163
5164 /// Create an abstract attribute view for the position \p IRP.
5166 Attributor &A);
5167
5168 /// Extract the single value in \p Values if any.
5169 LLVM_ABI static Value *
5171 const IRPosition &IRP,
5173
5174 StringRef getName() const override { return "AAPotentialValues"; }
5175
5176 const char *getIdAddr() const override { return &ID; }
5177
5178 /// This function should return true if the type of the \p AA is
5179 /// AAPotentialValues
5180 static bool classof(const AbstractAttribute *AA) {
5181 return (AA->getIdAddr() == &ID);
5182 }
5183
5184 /// Unique ID (due to the unique address)
5185 LLVM_ABI static const char ID;
5186
5187private:
5188 virtual bool getAssumedSimplifiedValues(
5190 AA::ValueScope, bool RecurseForSelectAndPHI = false) const = 0;
5191
5192 friend struct Attributor;
5193};
5194
5195/// An abstract interface for all noundef attributes.
5197 : public IRAttribute<Attribute::NoUndef,
5198 StateWrapper<BooleanState, AbstractAttribute>,
5199 AANoUndef> {
5201
5202 static bool isImpliedByUndef() { return false; }
5203
5204 static bool isImpliedByPoison() { return false; }
5205
5206 LLVM_ABI static bool isImpliedByIR(Attributor &A, const IRPosition &IRP,
5207 Attribute::AttrKind ImpliedAttributeKind,
5208 bool IgnoreSubsumingPositions = false);
5209
5210 /// Return true if we assume that the underlying value is noundef.
5211 bool isAssumedNoUndef() const { return getAssumed(); }
5212
5213 /// Return true if we know that underlying value is noundef.
5214 bool isKnownNoUndef() const { return getKnown(); }
5215
5216 /// Create an abstract attribute view for the position \p IRP.
5218 Attributor &A);
5219
5220 StringRef getName() const override { return "AANoUndef"; }
5221
5222 const char *getIdAddr() const override { return &ID; }
5223
5224 /// This function should return true if the type of the \p AA is AANoUndef
5225 static bool classof(const AbstractAttribute *AA) {
5226 return (AA->getIdAddr() == &ID);
5227 }
5228
5229 /// Unique ID (due to the unique address)
5230 LLVM_ABI static const char ID;
5231};
5232
5234 : public IRAttribute<
5235 Attribute::NoFPClass,
5236 StateWrapper<BitIntegerState<uint32_t, fcAllFlags, fcNone>,
5237 AbstractAttribute>,
5238 AANoFPClass> {
5241
5243
5245 return AttributeFuncs::isNoFPClassCompatibleType(IRP.getAssociatedType());
5246 }
5247
5248 /// Return the underlying assumed nofpclass.
5250 return static_cast<FPClassTest>(getAssumed());
5251 }
5252 /// Return the underlying known nofpclass.
5254 return static_cast<FPClassTest>(getKnown());
5255 }
5256
5257 /// Create an abstract attribute view for the position \p IRP.
5259 Attributor &A);
5260
5261 StringRef getName() const override { return "AANoFPClass"; }
5262
5263 const char *getIdAddr() const override { return &ID; }
5264
5265 /// This function should return true if the type of the \p AA is AANoFPClass
5266 static bool classof(const AbstractAttribute *AA) {
5267 return (AA->getIdAddr() == &ID);
5268 }
5269
5270 /// Unique ID (due to the unique address)
5271 LLVM_ABI static const char ID;
5272};
5273
5274struct AACallGraphNode;
5275struct AACallEdges;
5276
5277/// An Iterator for call edges, creates AACallEdges attributes in a lazy way.
5278/// This iterator becomes invalid if the underlying edge list changes.
5279/// So This shouldn't outlive a iteration of Attributor.
5280class AACallEdgeIterator
5281 : public iterator_adaptor_base<AACallEdgeIterator,
5282 SetVector<Function *>::iterator> {
5283 AACallEdgeIterator(Attributor &A, SetVector<Function *>::iterator Begin)
5284 : iterator_adaptor_base(Begin), A(A) {}
5285
5286public:
5288
5289private:
5290 Attributor &A;
5291 friend AACallEdges;
5292 friend AttributorCallGraph;
5293};
5294
5297 virtual ~AACallGraphNode() = default;
5298
5301
5302 /// Iterator range for exploring the call graph.
5307
5308protected:
5309 /// Reference to Attributor needed for GraphTraits implementation.
5311};
5312
5313/// An abstract state for querying live call edges.
5314/// This interface uses the Attributor's optimistic liveness
5315/// information to compute the edges that are alive.
5316struct AACallEdges : public StateWrapper<BooleanState, AbstractAttribute>,
5319
5321 : Base(IRP), AACallGraphNode(A) {}
5322
5323 static bool requiresNonAsmForCallBase() { return false; }
5324
5325 /// Get the optimistic edges.
5326 virtual const SetVector<Function *> &getOptimisticEdges() const = 0;
5327
5328 /// Is there any call with a unknown callee.
5329 virtual bool hasUnknownCallee() const = 0;
5330
5331 /// Is there any call with a unknown callee, excluding any inline asm.
5332 virtual bool hasNonAsmUnknownCallee() const = 0;
5333
5334 /// Iterator for exploring the call graph.
5338
5339 /// Iterator for exploring the call graph.
5343
5344 /// Create an abstract attribute view for the position \p IRP.
5346 Attributor &A);
5347
5348 StringRef getName() const override { return "AACallEdges"; }
5349
5350 const char *getIdAddr() const override { return &ID; }
5351
5352 /// This function should return true if the type of the \p AA is AACallEdges.
5353 static bool classof(const AbstractAttribute *AA) {
5354 return (AA->getIdAddr() == &ID);
5355 }
5356
5357 /// Unique ID (due to the unique address)
5358 LLVM_ABI static const char ID;
5359};
5360
5361// Synthetic root node for the Attributor's internal call graph.
5364 ~AttributorCallGraph() override = default;
5365
5367 return AACallEdgeIterator(A, A.Functions.begin());
5368 }
5369
5371 return AACallEdgeIterator(A, A.Functions.end());
5372 }
5373
5374 /// Force populate the entire call graph.
5375 void populateAll() const {
5376 for (const AACallGraphNode *AA : optimisticEdgesRange()) {
5377 // Nothing else to do here.
5378 (void)AA;
5379 }
5380 }
5381
5382 LLVM_ABI void print();
5383};
5384
5385template <> struct GraphTraits<AACallGraphNode *> {
5388
5390 return Node->optimisticEdgesBegin();
5391 }
5392
5394 return Node->optimisticEdgesEnd();
5395 }
5396};
5397
5398template <>
5402
5404 return static_cast<AACallGraphNode *>(G);
5405 }
5406
5408 return G->optimisticEdgesBegin();
5409 }
5410
5412 return G->optimisticEdgesEnd();
5413 }
5414};
5415
5416template <>
5419
5421 const AttributorCallGraph *Graph) {
5422 const AACallEdges *AACE = static_cast<const AACallEdges *>(Node);
5423 return AACE->getAssociatedFunction()->getName().str();
5424 }
5425
5427 const AttributorCallGraph *Graph) {
5428 // Hide the synth root.
5429 return static_cast<const AACallGraphNode *>(Graph) == Node;
5430 }
5431};
5432
5434 : public StateWrapper<BooleanState, AbstractAttribute> {
5437
5438 /// Summary about the execution domain of a block or instruction.
5463
5464 /// Create an abstract attribute view for the position \p IRP.
5466 Attributor &A);
5467
5468 StringRef getName() const override { return "AAExecutionDomain"; }
5469
5470 const char *getIdAddr() const override { return &ID; }
5471
5472 /// Check if an instruction is executed only by the initial thread.
5474 return isExecutedByInitialThreadOnly(*I.getParent());
5475 }
5476
5477 /// Check if a basic block is executed only by the initial thread.
5478 virtual bool isExecutedByInitialThreadOnly(const BasicBlock &) const = 0;
5479
5480 /// Check if the instruction \p I is executed in an aligned region, that is,
5481 /// the synchronizing effects before and after \p I are both aligned barriers.
5482 /// This effectively means all threads execute \p I together.
5484 const Instruction &I) const = 0;
5485
5487 /// Return the execution domain with which the call \p CB is entered and the
5488 /// one with which it is left.
5489 virtual std::pair<ExecutionDomainTy, ExecutionDomainTy>
5490 getExecutionDomain(const CallBase &CB) const = 0;
5492
5493 /// Helper function to determine if \p FI is a no-op given the information
5494 /// about its execution from \p ExecDomainAA.
5495 virtual bool isNoOpFence(const FenceInst &FI) const = 0;
5496
5497 /// This function should return true if the type of the \p AA is
5498 /// AAExecutionDomain.
5499 static bool classof(const AbstractAttribute *AA) {
5500 return (AA->getIdAddr() == &ID);
5501 }
5502
5503 /// Unique ID (due to the unique address)
5504 LLVM_ABI static const char ID;
5505};
5506
5507/// An abstract Attribute for computing reachability between functions.
5509 : public StateWrapper<BooleanState, AbstractAttribute> {
5511
5513
5514 /// If the function represented by this possition can reach \p Fn.
5515 bool canReach(Attributor &A, const Function &Fn) const {
5516 Function *Scope = getAnchorScope();
5517 if (!Scope || Scope->isDeclaration())
5518 return true;
5519 return instructionCanReach(A, Scope->getEntryBlock().front(), Fn);
5520 }
5521
5522 /// Can \p Inst reach \p Fn.
5523 /// See also AA::isPotentiallyReachable.
5525 Attributor &A, const Instruction &Inst, const Function &Fn,
5526 const AA::InstExclusionSetTy *ExclusionSet = nullptr) const = 0;
5527
5528 /// Create an abstract attribute view for the position \p IRP.
5531
5532 StringRef getName() const override { return "AAInterFnReachability"; }
5533
5534 const char *getIdAddr() const override { return &ID; }
5535
5536 /// This function should return true if the type of the \p AA is AACallEdges.
5537 static bool classof(const AbstractAttribute *AA) {
5538 return (AA->getIdAddr() == &ID);
5539 }
5540
5541 /// Unique ID (due to the unique address)
5542 LLVM_ABI static const char ID;
5543};
5544
5545/// An abstract Attribute for determining the necessity of the convergent
5546/// attribute.
5547struct AANonConvergent : public StateWrapper<BooleanState, AbstractAttribute> {
5549
5551
5552 /// Create an abstract attribute view for the position \p IRP.
5554 Attributor &A);
5555
5556 /// Return true if "non-convergent" is assumed.
5557 bool isAssumedNotConvergent() const { return getAssumed(); }
5558
5559 /// Return true if "non-convergent" is known.
5560 bool isKnownNotConvergent() const { return getKnown(); }
5561
5562 StringRef getName() const override { return "AANonConvergent"; }
5563
5564 const char *getIdAddr() const override { return &ID; }
5565
5566 /// This function should return true if the type of the \p AA is
5567 /// AANonConvergent.
5568 static bool classof(const AbstractAttribute *AA) {
5569 return (AA->getIdAddr() == &ID);
5570 }
5571
5572 /// Unique ID (due to the unique address)
5573 LLVM_ABI static const char ID;
5574};
5575
5576/// An abstract interface for struct information.
5579
5582 return false;
5584 }
5585
5587 // First two bits to distinguish may and must accesses.
5588 AK_MUST = 1 << 0,
5589 AK_MAY = 1 << 1,
5590
5591 // Then two bits for read and write. These are not exclusive.
5592 AK_R = 1 << 2,
5593 AK_W = 1 << 3,
5595
5596 // One special case for assumptions about memory content. These
5597 // are neither reads nor writes. They are however always modeled
5598 // as read to avoid using them for write removal.
5600
5601 // Helper for easy access.
5608 };
5609
5610 /// A helper containing a list of offsets computed for a Use. Ideally this
5611 /// list should be strictly ascending, but we ensure that only when we
5612 /// actually translate the list of offsets to a RangeList.
5613 struct OffsetInfo {
5617
5618 const_iterator begin() const { return Offsets.begin(); }
5619 const_iterator end() const { return Offsets.end(); }
5620
5621 bool operator==(const OffsetInfo &RHS) const {
5622 return Offsets == RHS.Offsets;
5623 }
5624
5625 bool operator!=(const OffsetInfo &RHS) const { return !(*this == RHS); }
5626
5627 bool insert(int64_t Offset) { return Offsets.insert(Offset).second; }
5628 bool isUnassigned() const { return Offsets.size() == 0; }
5629
5630 bool isUnknown() const {
5631 if (isUnassigned())
5632 return false;
5633 if (Offsets.size() == 1)
5634 return *Offsets.begin() == AA::RangeTy::Unknown;
5635 return false;
5636 }
5637
5638 void setUnknown() {
5639 Offsets.clear();
5641 }
5642
5643 void addToAll(int64_t Inc) {
5644 VecTy NewOffsets;
5645 for (auto &Offset : Offsets)
5646 NewOffsets.insert(Offset + Inc);
5647 Offsets = std::move(NewOffsets);
5648 }
5649
5650 /// Copy offsets from \p R into the current list.
5651 ///
5652 /// Ideally all lists should be strictly ascending, but we defer that to the
5653 /// actual use of the list. So we just blindly append here.
5654 bool merge(const OffsetInfo &R) { return set_union(Offsets, R.Offsets); }
5655 };
5656
5657 /// A container for a list of ranges.
5658 struct RangeList {
5659 // The set of ranges rarely contains more than one element, and is unlikely
5660 // to contain more than say four elements. So we find the middle-ground with
5661 // a sorted vector. This avoids hard-coding a rarely used number like "four"
5662 // into every instance of a SmallSet.
5668
5669 RangeList(const RangeTy &R) { Ranges.push_back(R); }
5671 Ranges.reserve(Offsets.size());
5672 for (unsigned i = 0, e = Offsets.size(); i != e; ++i) {
5673 assert(((i + 1 == e) || Offsets[i] < Offsets[i + 1]) &&
5674 "Expected strictly ascending offsets.");
5675 Ranges.emplace_back(Offsets[i], Size);
5676 }
5677 }
5678 RangeList() = default;
5679
5680 iterator begin() { return Ranges.begin(); }
5681 iterator end() { return Ranges.end(); }
5682 const_iterator begin() const { return Ranges.begin(); }
5683 const_iterator end() const { return Ranges.end(); }
5684
5685 // Helpers required for std::set_difference
5687 void push_back(const RangeTy &R) {
5688 assert((Ranges.empty() || RangeTy::LessThan(Ranges.back(), R)) &&
5689 "Ensure the last element is the greatest.");
5690 Ranges.push_back(R);
5691 }
5692
5693 /// Copy ranges from \p L that are not in \p R, into \p D.
5694 static void set_difference(const RangeList &L, const RangeList &R,
5695 RangeList &D) {
5696 std::set_difference(L.begin(), L.end(), R.begin(), R.end(),
5697 std::back_inserter(D), RangeTy::LessThan);
5698 }
5699
5700 unsigned size() const { return Ranges.size(); }
5701
5702 bool operator==(const RangeList &OI) const { return Ranges == OI.Ranges; }
5703
5704 /// Merge the ranges in \p RHS into the current ranges.
5705 /// - Merging a list of unknown ranges makes the current list unknown.
5706 /// - Ranges with the same offset are merged according to RangeTy::operator&
5707 /// \return true if the current RangeList changed.
5708 bool merge(const RangeList &RHS) {
5709 if (isUnknown())
5710 return false;
5711 if (RHS.isUnknown()) {
5712 setUnknown();
5713 return true;
5714 }
5715
5716 if (Ranges.empty()) {
5717 Ranges = RHS.Ranges;
5718 return true;
5719 }
5720
5721 bool Changed = false;
5722 auto LPos = Ranges.begin();
5723 for (auto &R : RHS.Ranges) {
5724 auto Result = insert(LPos, R);
5725 if (isUnknown())
5726 return true;
5727 LPos = Result.first;
5728 Changed |= Result.second;
5729 }
5730 return Changed;
5731 }
5732
5733 /// Insert \p R at the given iterator \p Pos, and merge if necessary.
5734 ///
5735 /// This assumes that all ranges before \p Pos are LessThan \p R, and
5736 /// then maintains the sorted order for the suffix list.
5737 ///
5738 /// \return The place of insertion and true iff anything changed.
5739 std::pair<iterator, bool> insert(iterator Pos, const RangeTy &R) {
5740 if (isUnknown())
5741 return std::make_pair(Ranges.begin(), false);
5742 if (R.offsetOrSizeAreUnknown()) {
5743 return std::make_pair(setUnknown(), true);
5744 }
5745
5746 // Maintain this as a sorted vector of unique entries.
5747 auto LB = std::lower_bound(Pos, Ranges.end(), R, RangeTy::LessThan);
5748 if (LB == Ranges.end() || LB->Offset != R.Offset)
5749 return std::make_pair(Ranges.insert(LB, R), true);
5750 bool Changed = *LB != R;
5751 *LB &= R;
5752 if (LB->offsetOrSizeAreUnknown())
5753 return std::make_pair(setUnknown(), true);
5754 return std::make_pair(LB, Changed);
5755 }
5756
5757 /// Add the increment \p Inc to the offset of every range.
5758 void addToAllOffsets(int64_t Inc) {
5759 assert(!isUnassigned() &&
5760 "Cannot increment if the offset is not yet computed!");
5761 if (isUnknown())
5762 return;
5763 for (auto &R : Ranges) {
5764 R.Offset += Inc;
5765 }
5766 }
5767
5768 /// Return true iff the list contains an unknown range.
5769 bool isUnknown() const {
5770 if (isUnassigned())
5771 return false;
5772 if (Ranges.front().offsetOrSizeAreUnknown()) {
5773 assert(Ranges.size() == 1 && "Unknown is a singleton range.");
5774 return true;
5775 }
5776 return false;
5777 }
5778
5779 /// Discard all ranges and insert a single unknown range.
5781 Ranges.clear();
5782 Ranges.push_back(RangeTy::getUnknown());
5783 return Ranges.begin();
5784 }
5785
5786 /// Return true if no ranges have been inserted.
5787 bool isUnassigned() const { return Ranges.size() == 0; }
5788 };
5789
5790 /// An access description.
5791 struct Access {
5792 Access(Instruction *I, int64_t Offset, int64_t Size,
5793 std::optional<Value *> Content, AccessKind Kind, Type *Ty)
5794 : LocalI(I), RemoteI(I), Content(Content), Ranges(Offset, Size),
5795 Kind(Kind), Ty(Ty) {
5796 verify();
5797 }
5798 Access(Instruction *LocalI, Instruction *RemoteI, const RangeList &Ranges,
5799 std::optional<Value *> Content, AccessKind K, Type *Ty)
5800 : LocalI(LocalI), RemoteI(RemoteI), Content(Content), Ranges(Ranges),
5801 Kind(K), Ty(Ty) {
5802 if (Ranges.size() > 1) {
5803 Kind = AccessKind(Kind | AK_MAY);
5804 Kind = AccessKind(Kind & ~AK_MUST);
5805 }
5806 verify();
5807 }
5808 Access(Instruction *LocalI, Instruction *RemoteI, int64_t Offset,
5809 int64_t Size, std::optional<Value *> Content, AccessKind Kind,
5810 Type *Ty)
5811 : LocalI(LocalI), RemoteI(RemoteI), Content(Content),
5812 Ranges(Offset, Size), Kind(Kind), Ty(Ty) {
5813 verify();
5814 }
5815 Access(const Access &Other) = default;
5816
5817 Access &operator=(const Access &Other) = default;
5818 bool operator==(const Access &R) const {
5819 return LocalI == R.LocalI && RemoteI == R.RemoteI && Ranges == R.Ranges &&
5820 Content == R.Content && Kind == R.Kind;
5821 }
5822 bool operator!=(const Access &R) const { return !(*this == R); }
5823
5825 assert(RemoteI == R.RemoteI && "Expected same instruction!");
5826 assert(LocalI == R.LocalI && "Expected same instruction!");
5827
5828 // Note that every Access object corresponds to a unique Value, and only
5829 // accesses to the same Value are merged. Hence we assume that all ranges
5830 // are the same size. If ranges can be different size, then the contents
5831 // must be dropped.
5832 Ranges.merge(R.Ranges);
5833 Content =
5834 AA::combineOptionalValuesInAAValueLatice(Content, R.Content, Ty);
5835
5836 // Combine the access kind, which results in a bitwise union.
5837 // If there is more than one range, then this must be a MAY.
5838 // If we combine a may and a must access we clear the must bit.
5839 Kind = AccessKind(Kind | R.Kind);
5840 if ((Kind & AK_MAY) || Ranges.size() > 1) {
5841 Kind = AccessKind(Kind | AK_MAY);
5842 Kind = AccessKind(Kind & ~AK_MUST);
5843 }
5844 verify();
5845 return *this;
5846 }
5847
5848 void verify() {
5849 assert(isMustAccess() + isMayAccess() == 1 &&
5850 "Expect must or may access, not both.");
5851 assert(isAssumption() + isWrite() <= 1 &&
5852 "Expect assumption access or write access, never both.");
5853 assert((isMayAccess() || Ranges.size() == 1) &&
5854 "Cannot be a must access if there are multiple ranges.");
5855 }
5856
5857 /// Return the access kind.
5858 AccessKind getKind() const { return Kind; }
5859
5860 /// Return true if this is a read access.
5861 bool isRead() const { return Kind & AK_R; }
5862
5863 /// Return true if this is a write access.
5864 bool isWrite() const { return Kind & AK_W; }
5865
5866 /// Return true if this is a write access.
5867 bool isWriteOrAssumption() const { return isWrite() || isAssumption(); }
5868
5869 /// Return true if this is an assumption access.
5870 bool isAssumption() const { return Kind == AK_ASSUMPTION; }
5871
5872 bool isMustAccess() const {
5873 bool MustAccess = Kind & AK_MUST;
5874 assert((!MustAccess || Ranges.size() < 2) &&
5875 "Cannot be a must access if there are multiple ranges.");
5876 return MustAccess;
5877 }
5878
5879 bool isMayAccess() const {
5880 bool MayAccess = Kind & AK_MAY;
5881 assert((MayAccess || Ranges.size() < 2) &&
5882 "Cannot be a must access if there are multiple ranges.");
5883 return MayAccess;
5884 }
5885
5886 /// Return the instruction that causes the access with respect to the local
5887 /// scope of the associated attribute.
5888 Instruction *getLocalInst() const { return LocalI; }
5889
5890 /// Return the actual instruction that causes the access.
5891 Instruction *getRemoteInst() const { return RemoteI; }
5892
5893 /// Return true if the value written is not known yet.
5894 bool isWrittenValueYetUndetermined() const { return !Content; }
5895
5896 /// Return true if the value written cannot be determined at all.
5898 return Content.has_value() && !*Content;
5899 }
5900
5901 /// Return the type associated with the access, if known.
5902 Type *getType() const { return Ty; }
5903
5904 /// Return the value writen, if any.
5907 "Value needs to be determined before accessing it.");
5908 return *Content;
5909 }
5910
5911 /// Return the written value which can be `llvm::null` if it is not yet
5912 /// determined.
5913 std::optional<Value *> getContent() const { return Content; }
5914
5915 const RangeList &getRanges() const { return Ranges; }
5916
5918 const_iterator begin() const { return Ranges.begin(); }
5919 const_iterator end() const { return Ranges.end(); }
5920
5921 private:
5922 /// The instruction responsible for the access with respect to the local
5923 /// scope of the associated attribute.
5924 Instruction *LocalI;
5925
5926 /// The instruction responsible for the access.
5927 Instruction *RemoteI;
5928
5929 /// The value written, if any. `std::nullopt` means "not known yet",
5930 /// `nullptr` cannot be determined.
5931 std::optional<Value *> Content;
5932
5933 /// Set of potential ranges accessed from the base pointer.
5934 RangeList Ranges;
5935
5936 /// The access kind, e.g., READ, as bitset (could be more than one).
5938
5939 /// The type of the content, thus the type read/written, can be null if not
5940 /// available.
5941 Type *Ty;
5942 };
5943
5944 /// Create an abstract attribute view for the position \p IRP.
5946 Attributor &A);
5947
5948 StringRef getName() const override { return "AAPointerInfo"; }
5949
5950 const char *getIdAddr() const override { return &ID; }
5951
5953 using const_bin_iterator = OffsetBinsTy::const_iterator;
5954 virtual const_bin_iterator begin() const = 0;
5955 virtual const_bin_iterator end() const = 0;
5956 virtual int64_t numOffsetBins() const = 0;
5957 virtual bool reachesReturn() const = 0;
5958 virtual void addReturnedOffsetsTo(OffsetInfo &) const = 0;
5959
5960 /// Call \p CB on all accesses that might interfere with \p Range and return
5961 /// true if all such accesses were known and the callback returned true for
5962 /// all of them, false otherwise. An access interferes with an offset-size
5963 /// pair if it might read or write that memory region.
5965 AA::RangeTy Range, function_ref<bool(const Access &, bool)> CB) const = 0;
5966
5967 /// Call \p CB on all accesses that might interfere with \p I and
5968 /// return true if all such accesses were known and the callback returned true
5969 /// for all of them, false otherwise. In contrast to forallInterferingAccesses
5970 /// this function will perform reasoning to exclude write accesses that cannot
5971 /// affect the load even if they on the surface look as if they would. The
5972 /// flag \p HasBeenWrittenTo will be set to true if we know that \p I does not
5973 /// read the initial value of the underlying memory. If \p SkipCB is given and
5974 /// returns false for a potentially interfering access, that access is not
5975 /// checked for actual interference.
5977 Attributor &A, const AbstractAttribute &QueryingAA, Instruction &I,
5978 bool FindInterferingWrites, bool FindInterferingReads,
5979 function_ref<bool(const Access &, bool)> CB, bool &HasBeenWrittenTo,
5981 function_ref<bool(const Access &)> SkipCB = nullptr) const = 0;
5982
5983 /// This function should return true if the type of the \p AA is AAPointerInfo
5984 static bool classof(const AbstractAttribute *AA) {
5985 return (AA->getIdAddr() == &ID);
5986 }
5987
5988 /// Unique ID (due to the unique address)
5989 LLVM_ABI static const char ID;
5990};
5991
5993
5994/// An abstract attribute for getting assumption information.
5996 : public StateWrapper<SetState<StringRef>, AbstractAttribute,
5997 DenseSet<StringRef>> {
5998 using Base =
6000
6002 const DenseSet<StringRef> &Known)
6003 : Base(IRP, Known) {}
6004
6005 /// Returns true if the assumption set contains the assumption \p Assumption.
6006 virtual bool hasAssumption(const StringRef Assumption) const = 0;
6007
6008 /// Create an abstract attribute view for the position \p IRP.
6010 Attributor &A);
6011
6012 StringRef getName() const override { return "AAAssumptionInfo"; }
6013
6014 const char *getIdAddr() const override { return &ID; }
6015
6016 /// This function should return true if the type of the \p AA is
6017 /// AAAssumptionInfo
6018 static bool classof(const AbstractAttribute *AA) {
6019 return (AA->getIdAddr() == &ID);
6020 }
6021
6022 /// Unique ID (due to the unique address)
6023 LLVM_ABI static const char ID;
6024};
6025
6026/// An abstract attribute for getting all assumption underlying objects.
6029
6032 return false;
6034 }
6035
6036 static bool requiresCallersForArgOrFunction() { return true; }
6037
6038 /// Create an abstract attribute biew for the position \p IRP.
6040 Attributor &A);
6041
6042 StringRef getName() const override { return "AAUnderlyingObjects"; }
6043
6044 const char *getIdAddr() const override { return &ID; }
6045
6046 /// This function should return true if the type of the \p AA is
6047 /// AAUnderlyingObjects.
6048 static bool classof(const AbstractAttribute *AA) {
6049 return (AA->getIdAddr() == &ID);
6050 }
6051
6052 /// Unique ID (due to the unique address)
6053 LLVM_ABI static const char ID;
6054
6055 /// Check \p Pred on all underlying objects in \p Scope collected so far.
6056 ///
6057 /// This method will evaluate \p Pred on all underlying objects in \p Scope
6058 /// collected so far and return true if \p Pred holds on all of them.
6059 virtual bool
6061 AA::ValueScope Scope = AA::Interprocedural) const = 0;
6062};
6063
6064/// An abstract interface for identifying pointers from which loads can be
6065/// marked invariant.
6068
6070 if (!IRP.getAssociatedType()->isPointerTy())
6071 return false;
6072
6074 }
6075
6076 /// Create an abstract attribute view for the position \p IRP.
6079
6080 /// Return true if the pointer's contents are known to remain invariant.
6081 virtual bool isKnownInvariant() const = 0;
6082 virtual bool isKnownLocallyInvariant() const = 0;
6083
6084 /// Return true if the pointer's contents are assumed to remain invariant.
6085 virtual bool isAssumedInvariant() const = 0;
6086 virtual bool isAssumedLocallyInvariant() const = 0;
6087
6088 StringRef getName() const override { return "AAInvariantLoadPointer"; }
6089
6090 const char *getIdAddr() const override { return &ID; }
6091
6092 /// This function should return true if the type of the \p AA is
6093 /// AAInvariantLoadPointer
6094 static bool classof(const AbstractAttribute *AA) {
6095 return (AA->getIdAddr() == &ID);
6096 }
6097
6098 /// Unique ID (due to the unique address).
6099 LLVM_ABI static const char ID;
6100};
6101
6102/// An abstract interface for address space information.
6103struct AAAddressSpace : public StateWrapper<BooleanState, AbstractAttribute> {
6106
6109 return false;
6111 }
6112
6113 static bool requiresCallersForArgOrFunction() { return true; }
6114
6115 /// Return the address space of the associated value. \p NoAddressSpace is
6116 /// returned if the associated value is dead. This functions is not supposed
6117 /// to be called if the AA is invalid.
6118 virtual uint32_t getAddressSpace() const = 0;
6119
6120 /// Create an abstract attribute view for the position \p IRP.
6122 Attributor &A);
6123
6124 StringRef getName() const override { return "AAAddressSpace"; }
6125
6126 const char *getIdAddr() const override { return &ID; }
6127
6128 /// This function should return true if the type of the \p AA is
6129 /// AAAssumptionInfo
6130 static bool classof(const AbstractAttribute *AA) {
6131 return (AA->getIdAddr() == &ID);
6132 }
6133
6134 /// Unique ID (due to the unique address)
6135 LLVM_ABI static const char ID;
6136
6137protected:
6138 // Invalid address space which indicates the associated value is dead.
6139 static const uint32_t InvalidAddressSpace = ~0U;
6140};
6141
6142/// An abstract interface for potential address space information.
6144 : public StateWrapper<BooleanState, AbstractAttribute> {
6149
6152 return false;
6154 }
6155
6156 static bool requiresCallersForArgOrFunction() { return true; }
6157
6158 /// Create an abstract attribute view for the position \p IRP.
6160 Attributor &A);
6161 StringRef getName() const override { return "AANoAliasAddrSpace"; }
6162
6163 const char *getIdAddr() const override { return &ID; }
6164
6165 /// This function should return true if the type of the \p AA is
6166 /// AAAssumptionInfo
6167 static bool classof(const AbstractAttribute *AA) {
6168 return (AA->getIdAddr() == &ID);
6169 }
6170
6171 /// Unique ID (due to the unique address)
6172 LLVM_ABI static const char ID;
6173
6174protected:
6177};
6178
6179struct AAAllocationInfo : public StateWrapper<BooleanState, AbstractAttribute> {
6182
6185 return false;
6187 }
6188
6189 /// Create an abstract attribute view for the position \p IRP.
6191 Attributor &A);
6192
6193 virtual std::optional<TypeSize> getAllocatedSize() const = 0;
6194
6195 StringRef getName() const override { return "AAAllocationInfo"; }
6196
6197 const char *getIdAddr() const override { return &ID; }
6198
6199 /// This function should return true if the type of the \p AA is
6200 /// AAAllocationInfo
6201 static bool classof(const AbstractAttribute *AA) {
6202 return (AA->getIdAddr() == &ID);
6203 }
6204
6205 constexpr static const std::optional<TypeSize> HasNoAllocationSize =
6206 std::make_optional<TypeSize>(-1, true);
6207
6208 LLVM_ABI static const char ID;
6209};
6210
6211/// An abstract interface for llvm::GlobalValue information interference.
6213 : public StateWrapper<BooleanState, AbstractAttribute> {
6216
6219 return false;
6220 auto *GV = dyn_cast<GlobalValue>(&IRP.getAnchorValue());
6221 if (!GV)
6222 return false;
6223 return GV->hasLocalLinkage();
6224 }
6225
6226 /// Create an abstract attribute view for the position \p IRP.
6228 Attributor &A);
6229
6230 /// Return true iff \p U is a potential use of the associated global value.
6231 virtual bool isPotentialUse(const Use &U) const = 0;
6232
6233 StringRef getName() const override { return "AAGlobalValueInfo"; }
6234
6235 const char *getIdAddr() const override { return &ID; }
6236
6237 /// This function should return true if the type of the \p AA is
6238 /// AAGlobalValueInfo
6239 static bool classof(const AbstractAttribute *AA) {
6240 return (AA->getIdAddr() == &ID);
6241 }
6242
6243 /// Unique ID (due to the unique address)
6244 LLVM_ABI static const char ID;
6245};
6246
6247/// An abstract interface for indirect call information interference.
6249 : public StateWrapper<BooleanState, AbstractAttribute> {
6252
6255 return false;
6256 auto *CB = cast<CallBase>(IRP.getCtxI());
6257 return CB->getOpcode() == Instruction::Call && CB->isIndirectCall() &&
6258 !CB->isMustTailCall();
6259 }
6260
6261 /// Create an abstract attribute view for the position \p IRP.
6263 Attributor &A);
6264
6265 /// Call \CB on each potential callee value and return true if all were known
6266 /// and \p CB returned true on all of them. Otherwise, return false.
6267 virtual bool foreachCallee(function_ref<bool(Function *)> CB) const = 0;
6268
6269 StringRef getName() const override { return "AAIndirectCallInfo"; }
6270
6271 const char *getIdAddr() const override { return &ID; }
6272
6273 /// This function should return true if the type of the \p AA is
6274 /// AAIndirectCallInfo
6275 /// This function should return true if the type of the \p AA is
6276 /// AADenormalFPMath.
6277 static bool classof(const AbstractAttribute *AA) {
6278 return (AA->getIdAddr() == &ID);
6279 }
6280
6281 /// Unique ID (due to the unique address)
6282 LLVM_ABI static const char ID;
6283};
6284
6285/// An abstract Attribute for specializing "dynamic" components of
6286/// denormal_fpenv to a known denormal mode.
6288 : public StateWrapper<DenormalFPMathState, AbstractAttribute> {
6290
6292
6293 /// Create an abstract attribute view for the position \p IRP.
6295 Attributor &A);
6296
6297 StringRef getName() const override { return "AADenormalFPMath"; }
6298
6299 const char *getIdAddr() const override { return &ID; }
6300
6301 /// This function should return true if the type of the \p AA is
6302 /// AADenormalFPMath.
6303 static bool classof(const AbstractAttribute *AA) {
6304 return (AA->getIdAddr() == &ID);
6305 }
6306
6307 /// Unique ID (due to the unique address)
6308 LLVM_ABI static const char ID;
6309};
6310
6311/// Run options, used by the pass manager.
6322
6323namespace AA {
6324/// Helper to avoid creating an AA for IR Attributes that might already be set.
6325template <Attribute::AttrKind AK, typename AAType = AbstractAttribute>
6327 const IRPosition &IRP, DepClassTy DepClass, bool &IsKnown,
6328 bool IgnoreSubsumingPositions = false,
6329 const AAType **AAPtr = nullptr) {
6330 IsKnown = false;
6331 switch (AK) {
6332#define CASE(ATTRNAME, AANAME, ...) \
6333 case Attribute::ATTRNAME: { \
6334 if (AANAME::isImpliedByIR(A, IRP, AK, IgnoreSubsumingPositions)) \
6335 return IsKnown = true; \
6336 if (!QueryingAA) \
6337 return false; \
6338 const auto *AA = A.getAAFor<AANAME>(*QueryingAA, IRP, DepClass); \
6339 if (AAPtr) \
6340 *AAPtr = reinterpret_cast<const AAType *>(AA); \
6341 if (!AA || !AA->isAssumed(__VA_ARGS__)) \
6342 return false; \
6343 IsKnown = AA->isKnown(__VA_ARGS__); \
6344 return true; \
6345 }
6346 CASE(NoUnwind, AANoUnwind, );
6347 CASE(WillReturn, AAWillReturn, );
6348 CASE(NoFree, AANoFree, );
6349 CASE(Captures, AANoCapture, );
6350 CASE(NoRecurse, AANoRecurse, );
6351 CASE(NoReturn, AANoReturn, );
6352 CASE(NoSync, AANoSync, );
6353 CASE(NoAlias, AANoAlias, );
6354 CASE(NonNull, AANonNull, );
6355 CASE(MustProgress, AAMustProgress, );
6356 CASE(NoUndef, AANoUndef, );
6360#undef CASE
6361 default:
6362 llvm_unreachable("hasAssumedIRAttr not available for this attribute kind");
6363 };
6364}
6365} // namespace AA
6366
6367} // end namespace llvm
6368
6369#endif // LLVM_TRANSFORMS_IPO_ATTRIBUTOR_H
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()
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