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