LLVM 23.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.
842 AttributeList getAttrList() const {
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 (Phase == AttributorPhase::SEEDING || Phase == AttributorPhase::UPDATE)
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 (Phase == AttributorPhase::MANIFEST || Phase == AttributorPhase::CLEANUP)
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 /// Mark the internal function \p F as live.
1825 ///
1826 /// This will trigger the identification and initialization of attributes for
1827 /// \p F.
1829 assert(F.hasLocalLinkage() &&
1830 "Only local linkage is assumed dead initially.");
1831
1832 if (Configuration.DefaultInitializeLiveInternals)
1834 if (Configuration.InitializationCallback)
1835 Configuration.InitializationCallback(*this, F);
1836 }
1837
1838 /// Record that \p U is to be replaces with \p NV after information was
1839 /// manifested. This also triggers deletion of trivially dead istructions.
1841 Value *&V = ToBeChangedUses[&U];
1842 if (V && (V->stripPointerCasts() == NV.stripPointerCasts() ||
1844 return false;
1845 assert((!V || V == &NV || isa<UndefValue>(NV)) &&
1846 "Use was registered twice for replacement with different values!");
1847 V = &NV;
1848 return true;
1849 }
1850
1851 /// Helper function to replace all uses associated with \p IRP with \p NV.
1852 /// Return true if there is any change. The flag \p ChangeDroppable indicates
1853 /// if dropppable uses should be changed too.
1855 bool ChangeDroppable = true) {
1857 auto *CB = cast<CallBase>(IRP.getCtxI());
1859 CB->getArgOperandUse(IRP.getCallSiteArgNo()), NV);
1860 }
1861 Value &V = IRP.getAssociatedValue();
1862 auto &Entry = ToBeChangedValues[&V];
1863 Value *CurNV = get<0>(Entry);
1864 if (CurNV && (CurNV->stripPointerCasts() == NV.stripPointerCasts() ||
1865 isa<UndefValue>(CurNV)))
1866 return false;
1867 assert((!CurNV || CurNV == &NV || isa<UndefValue>(NV)) &&
1868 "Value replacement was registered twice with different values!");
1869 Entry = {&NV, ChangeDroppable};
1870 return true;
1871 }
1872
1873 /// Record that \p I is to be replaced with `unreachable` after information
1874 /// was manifested.
1876 ToBeChangedToUnreachableInsts.insert(I);
1877 }
1878
1879 /// Record that \p II has at least one dead successor block. This information
1880 /// is used, e.g., to replace \p II with a call, after information was
1881 /// manifested.
1883 InvokeWithDeadSuccessor.insert(&II);
1884 }
1885
1886 /// Record that \p I is deleted after information was manifested. This also
1887 /// triggers deletion of trivially dead istructions.
1888 void deleteAfterManifest(Instruction &I) { ToBeDeletedInsts.insert(&I); }
1889
1890 /// Record that \p BB is deleted after information was manifested. This also
1891 /// triggers deletion of trivially dead istructions.
1892 void deleteAfterManifest(BasicBlock &BB) { ToBeDeletedBlocks.insert(&BB); }
1893
1894 // Record that \p BB is added during the manifest of an AA. Added basic blocks
1895 // are preserved in the IR.
1897 ManifestAddedBlocks.insert(&BB);
1898 }
1899
1900 /// Record that \p F is deleted after information was manifested.
1902 if (Configuration.DeleteFns)
1903 ToBeDeletedFunctions.insert(&F);
1904 }
1905
1906 /// Return the attributes of kind \p AK existing in the IR as operand bundles
1907 /// of an llvm.assume.
1908 LLVM_ABI bool getAttrsFromAssumes(const IRPosition &IRP,
1911
1912 /// Return true if any kind in \p AKs existing in the IR at a position that
1913 /// will affect this one. See also getAttrs(...).
1914 /// \param IgnoreSubsumingPositions Flag to determine if subsuming positions,
1915 /// e.g., the function position if this is an
1916 /// argument position, should be ignored.
1917 LLVM_ABI bool
1919 bool IgnoreSubsumingPositions = false,
1920 Attribute::AttrKind ImpliedAttributeKind = Attribute::None);
1921
1922 /// Return the attributes of any kind in \p AKs existing in the IR at a
1923 /// position that will affect this one. While each position can only have a
1924 /// single attribute of any kind in \p AKs, there are "subsuming" positions
1925 /// that could have an attribute as well. This method returns all attributes
1926 /// found in \p Attrs.
1927 /// \param IgnoreSubsumingPositions Flag to determine if subsuming positions,
1928 /// e.g., the function position if this is an
1929 /// argument position, should be ignored.
1930 LLVM_ABI void getAttrs(const IRPosition &IRP,
1933 bool IgnoreSubsumingPositions = false);
1934
1935 /// Remove all \p AttrKinds attached to \p IRP.
1939 ArrayRef<StringRef> Attrs);
1940
1941 /// Attach \p DeducedAttrs to \p IRP, if \p ForceReplace is set we do this
1942 /// even if the same attribute kind was already present.
1944 ArrayRef<Attribute> DeducedAttrs,
1945 bool ForceReplace = false);
1946
1947private:
1948 /// Helper to check \p Attrs for \p AK, if not found, check if \p
1949 /// AAType::isImpliedByIR is true, and if not, create AAType for \p IRP.
1950 /// If \p SkipHasAttrCheck is true, don't check whether the attribute is set
1951 /// first. This should be used if only some values of a complex IR attribute
1952 /// imply the AAType.
1953 template <Attribute::AttrKind AK, typename AAType>
1954 void checkAndQueryIRAttr(const IRPosition &IRP, AttributeSet Attrs,
1955 bool SkipHasAttrCheck = false);
1956
1957 /// Helper to apply \p CB on all attributes of type \p AttrDescs of \p IRP.
1958 template <typename DescTy>
1959 ChangeStatus updateAttrMap(const IRPosition &IRP, ArrayRef<DescTy> AttrDescs,
1960 function_ref<bool(const DescTy &, AttributeSet,
1961 AttributeMask &, AttrBuilder &)>
1962 CB);
1963
1964 /// Mapping from functions/call sites to their attributes.
1966
1967public:
1968 /// If \p IRP is assumed to be a constant, return it, if it is unclear yet,
1969 /// return std::nullopt, otherwise return `nullptr`.
1970 LLVM_ABI std::optional<Constant *>
1972 bool &UsedAssumedInformation);
1973 std::optional<Constant *> getAssumedConstant(const Value &V,
1974 const AbstractAttribute &AA,
1975 bool &UsedAssumedInformation) {
1976 return getAssumedConstant(IRPosition::value(V), AA, UsedAssumedInformation);
1977 }
1978
1979 /// If \p V is assumed simplified, return it, if it is unclear yet,
1980 /// return std::nullopt, otherwise return `nullptr`.
1981 std::optional<Value *> getAssumedSimplified(const IRPosition &IRP,
1982 const AbstractAttribute &AA,
1983 bool &UsedAssumedInformation,
1984 AA::ValueScope S) {
1985 return getAssumedSimplified(IRP, &AA, UsedAssumedInformation, S);
1986 }
1987 std::optional<Value *> getAssumedSimplified(const Value &V,
1988 const AbstractAttribute &AA,
1989 bool &UsedAssumedInformation,
1990 AA::ValueScope S) {
1992 UsedAssumedInformation, S);
1993 }
1994
1995 /// If \p V is assumed simplified, return it, if it is unclear yet,
1996 /// return std::nullopt, otherwise return `nullptr`. Same as the public
1997 /// version except that it can be used without recording dependences on any \p
1998 /// AA.
1999 LLVM_ABI std::optional<Value *>
2001 bool &UsedAssumedInformation, AA::ValueScope S);
2002
2003 /// Try to simplify \p IRP and in the scope \p S. If successful, true is
2004 /// returned and all potential values \p IRP can take are put into \p Values.
2005 /// If the result in \p Values contains select or PHI instructions it means
2006 /// those could not be simplified to a single value. Recursive calls with
2007 /// these instructions will yield their respective potential values. If false
2008 /// is returned no other information is valid.
2009 LLVM_ABI bool
2012 AA::ValueScope S, bool &UsedAssumedInformation,
2013 bool RecurseForSelectAndPHI = true);
2014
2015 /// Register \p CB as a simplification callback.
2016 /// `Attributor::getAssumedSimplified` will use these callbacks before
2017 /// we it will ask `AAValueSimplify`. It is important to ensure this
2018 /// is called before `identifyDefaultAbstractAttributes`, assuming the
2019 /// latter is called at all.
2020 using SimplifictionCallbackTy = std::function<std::optional<Value *>(
2021 const IRPosition &, const AbstractAttribute *, bool &)>;
2023 const SimplifictionCallbackTy &CB) {
2024 SimplificationCallbacks[IRP].emplace_back(CB);
2025 }
2026
2027 /// Return true if there is a simplification callback for \p IRP.
2029 return SimplificationCallbacks.count(IRP);
2030 }
2031
2032 /// Register \p CB as a simplification callback.
2033 /// Similar to \p registerSimplificationCallback, the call back will be called
2034 /// first when we simplify a global variable \p GV.
2036 std::function<std::optional<Constant *>(
2037 const GlobalVariable &, const AbstractAttribute *, bool &)>;
2039 const GlobalVariable &GV,
2041 GlobalVariableSimplificationCallbacks[&GV].emplace_back(CB);
2042 }
2043
2044 /// Return true if there is a simplification callback for \p GV.
2046 return GlobalVariableSimplificationCallbacks.count(&GV);
2047 }
2048
2049 /// Return \p std::nullopt if there is no call back registered for \p GV or
2050 /// the call back is still not sure if \p GV can be simplified. Return \p
2051 /// nullptr if \p GV can't be simplified.
2052 std::optional<Constant *>
2054 const AbstractAttribute *AA,
2055 bool &UsedAssumedInformation) {
2056 assert(GlobalVariableSimplificationCallbacks.contains(&GV));
2057 for (auto &CB : GlobalVariableSimplificationCallbacks.lookup(&GV)) {
2058 auto SimplifiedGV = CB(GV, AA, UsedAssumedInformation);
2059 // For now we assume the call back will not return a std::nullopt.
2060 assert(SimplifiedGV.has_value() && "SimplifiedGV has not value");
2061 return *SimplifiedGV;
2062 }
2063 llvm_unreachable("there must be a callback registered");
2064 }
2065
2067 std::function<bool(Attributor &, const AbstractAttribute *)>;
2069 const VirtualUseCallbackTy &CB) {
2070 VirtualUseCallbacks[&V].emplace_back(CB);
2071 }
2072
2073private:
2074 /// The vector with all simplification callbacks registered by outside AAs.
2076 SimplificationCallbacks;
2077
2078 /// The vector with all simplification callbacks for global variables
2079 /// registered by outside AAs.
2080 DenseMap<const GlobalVariable *,
2082 GlobalVariableSimplificationCallbacks;
2083
2085 VirtualUseCallbacks;
2086
2087public:
2088 /// Translate \p V from the callee context into the call site context.
2089 LLVM_ABI std::optional<Value *>
2090 translateArgumentToCallSiteContent(std::optional<Value *> V, CallBase &CB,
2091 const AbstractAttribute &AA,
2092 bool &UsedAssumedInformation);
2093
2094 /// Return true if \p AA (or its context instruction) is assumed dead.
2095 ///
2096 /// If \p LivenessAA is not provided it is queried.
2098 const AAIsDead *LivenessAA,
2099 bool &UsedAssumedInformation,
2100 bool CheckBBLivenessOnly = false,
2101 DepClassTy DepClass = DepClassTy::OPTIONAL);
2102
2103 /// Return true if \p I is assumed dead.
2104 ///
2105 /// If \p LivenessAA is not provided it is queried.
2106 LLVM_ABI bool isAssumedDead(const Instruction &I,
2107 const AbstractAttribute *QueryingAA,
2108 const AAIsDead *LivenessAA,
2109 bool &UsedAssumedInformation,
2110 bool CheckBBLivenessOnly = false,
2112 bool CheckForDeadStore = false);
2113
2114 /// Return true if \p U is assumed dead.
2115 ///
2116 /// If \p FnLivenessAA is not provided it is queried.
2117 LLVM_ABI bool isAssumedDead(const Use &U, const AbstractAttribute *QueryingAA,
2118 const AAIsDead *FnLivenessAA,
2119 bool &UsedAssumedInformation,
2120 bool CheckBBLivenessOnly = false,
2121 DepClassTy DepClass = DepClassTy::OPTIONAL);
2122
2123 /// Return true if \p IRP is assumed dead.
2124 ///
2125 /// If \p FnLivenessAA is not provided it is queried.
2126 LLVM_ABI bool isAssumedDead(const IRPosition &IRP,
2127 const AbstractAttribute *QueryingAA,
2128 const AAIsDead *FnLivenessAA,
2129 bool &UsedAssumedInformation,
2130 bool CheckBBLivenessOnly = false,
2131 DepClassTy DepClass = DepClassTy::OPTIONAL);
2132
2133 /// Return true if \p BB is assumed dead.
2134 ///
2135 /// If \p LivenessAA is not provided it is queried.
2136 LLVM_ABI bool isAssumedDead(const BasicBlock &BB,
2137 const AbstractAttribute *QueryingAA,
2138 const AAIsDead *FnLivenessAA,
2139 DepClassTy DepClass = DepClassTy::OPTIONAL);
2140
2141 /// Check \p Pred on all potential Callees of \p CB.
2142 ///
2143 /// This method will evaluate \p Pred with all potential callees of \p CB as
2144 /// input and return true if \p Pred does. If some callees might be unknown
2145 /// this function will return false.
2147 function_ref<bool(ArrayRef<const Function *> Callees)> Pred,
2148 const AbstractAttribute &QueryingAA, const CallBase &CB);
2149
2150 /// Check \p Pred on all (transitive) uses of \p V.
2151 ///
2152 /// This method will evaluate \p Pred on all (transitive) uses of the
2153 /// associated value and return true if \p Pred holds every time.
2154 /// If uses are skipped in favor of equivalent ones, e.g., if we look through
2155 /// memory, the \p EquivalentUseCB will be used to give the caller an idea
2156 /// what original used was replaced by a new one (or new ones). The visit is
2157 /// cut short if \p EquivalentUseCB returns false and the function will return
2158 /// false as well.
2160 function_ref<bool(const Use &, bool &)> Pred,
2161 const AbstractAttribute &QueryingAA, const Value &V,
2162 bool CheckBBLivenessOnly = false,
2163 DepClassTy LivenessDepClass = DepClassTy::OPTIONAL,
2164 bool IgnoreDroppableUses = true,
2165 function_ref<bool(const Use &OldU, const Use &NewU)> EquivalentUseCB =
2166 nullptr);
2167
2168 /// Emit a remark generically.
2169 ///
2170 /// This template function can be used to generically emit a remark. The
2171 /// RemarkKind should be one of the following:
2172 /// - OptimizationRemark to indicate a successful optimization attempt
2173 /// - OptimizationRemarkMissed to report a failed optimization attempt
2174 /// - OptimizationRemarkAnalysis to provide additional information about an
2175 /// optimization attempt
2176 ///
2177 /// The remark is built using a callback function \p RemarkCB that takes a
2178 /// RemarkKind as input and returns a RemarkKind.
2179 template <typename RemarkKind, typename RemarkCallBack>
2181 RemarkCallBack &&RemarkCB) const {
2182 if (!Configuration.OREGetter)
2183 return;
2184
2185 Function *F = I->getFunction();
2186 auto &ORE = Configuration.OREGetter(F);
2187
2188 if (RemarkName.starts_with("OMP"))
2189 ORE.emit([&]() {
2190 return RemarkCB(RemarkKind(Configuration.PassName, RemarkName, I))
2191 << " [" << RemarkName << "]";
2192 });
2193 else
2194 ORE.emit([&]() {
2195 return RemarkCB(RemarkKind(Configuration.PassName, RemarkName, I));
2196 });
2197 }
2198
2199 /// Emit a remark on a function.
2200 template <typename RemarkKind, typename RemarkCallBack>
2201 void emitRemark(Function *F, StringRef RemarkName,
2202 RemarkCallBack &&RemarkCB) const {
2203 if (!Configuration.OREGetter)
2204 return;
2205
2206 auto &ORE = Configuration.OREGetter(F);
2207
2208 if (RemarkName.starts_with("OMP"))
2209 ORE.emit([&]() {
2210 return RemarkCB(RemarkKind(Configuration.PassName, RemarkName, F))
2211 << " [" << RemarkName << "]";
2212 });
2213 else
2214 ORE.emit([&]() {
2215 return RemarkCB(RemarkKind(Configuration.PassName, RemarkName, F));
2216 });
2217 }
2218
2219 /// Helper struct used in the communication between an abstract attribute (AA)
2220 /// that wants to change the signature of a function and the Attributor which
2221 /// applies the changes. The struct is partially initialized with the
2222 /// information from the AA (see the constructor). All other members are
2223 /// provided by the Attributor prior to invoking any callbacks.
2224 struct ArgumentReplacementInfo {
2225 /// Callee repair callback type
2226 ///
2227 /// The function repair callback is invoked once to rewire the replacement
2228 /// arguments in the body of the new function. The argument replacement info
2229 /// is passed, as build from the registerFunctionSignatureRewrite call, as
2230 /// well as the replacement function and an iteratore to the first
2231 /// replacement argument.
2232 using CalleeRepairCBTy = std::function<void(
2233 const ArgumentReplacementInfo &, Function &, Function::arg_iterator)>;
2234
2235 /// Abstract call site (ACS) repair callback type
2236 ///
2237 /// The abstract call site repair callback is invoked once on every abstract
2238 /// call site of the replaced function (\see ReplacedFn). The callback needs
2239 /// to provide the operands for the call to the new replacement function.
2240 /// The number and type of the operands appended to the provided vector
2241 /// (second argument) is defined by the number and types determined through
2242 /// the replacement type vector (\see ReplacementTypes). The first argument
2243 /// is the ArgumentReplacementInfo object registered with the Attributor
2244 /// through the registerFunctionSignatureRewrite call.
2246 std::function<void(const ArgumentReplacementInfo &, AbstractCallSite,
2248
2249 /// Simple getters, see the corresponding members for details.
2250 ///{
2251
2252 Attributor &getAttributor() const { return A; }
2253 const Function &getReplacedFn() const { return ReplacedFn; }
2254 const Argument &getReplacedArg() const { return ReplacedArg; }
2255 unsigned getNumReplacementArgs() const { return ReplacementTypes.size(); }
2257 return ReplacementTypes;
2258 }
2259
2260 ///}
2261
2262 private:
2263 /// Constructor that takes the argument to be replaced, the types of
2264 /// the replacement arguments, as well as callbacks to repair the call sites
2265 /// and new function after the replacement happened.
2267 ArrayRef<Type *> ReplacementTypes,
2268 CalleeRepairCBTy &&CalleeRepairCB,
2269 ACSRepairCBTy &&ACSRepairCB)
2270 : A(A), ReplacedFn(*Arg.getParent()), ReplacedArg(Arg),
2271 ReplacementTypes(ReplacementTypes),
2272 CalleeRepairCB(std::move(CalleeRepairCB)),
2273 ACSRepairCB(std::move(ACSRepairCB)) {}
2274
2275 /// Reference to the attributor to allow access from the callbacks.
2276 Attributor &A;
2277
2278 /// The "old" function replaced by ReplacementFn.
2279 const Function &ReplacedFn;
2280
2281 /// The "old" argument replaced by new ones defined via ReplacementTypes.
2282 const Argument &ReplacedArg;
2283
2284 /// The types of the arguments replacing ReplacedArg.
2285 const SmallVector<Type *, 8> ReplacementTypes;
2286
2287 /// Callee repair callback, see CalleeRepairCBTy.
2288 const CalleeRepairCBTy CalleeRepairCB;
2289
2290 /// Abstract call site (ACS) repair callback, see ACSRepairCBTy.
2291 const ACSRepairCBTy ACSRepairCB;
2292
2293 /// Allow access to the private members from the Attributor.
2294 friend struct Attributor;
2295 };
2296
2297 /// Check if we can rewrite a function signature.
2298 ///
2299 /// The argument \p Arg is replaced with new ones defined by the number,
2300 /// order, and types in \p ReplacementTypes.
2301 ///
2302 /// \returns True, if the replacement can be registered, via
2303 /// registerFunctionSignatureRewrite, false otherwise.
2304 LLVM_ABI bool
2306 ArrayRef<Type *> ReplacementTypes);
2307
2308 /// Register a rewrite for a function signature.
2309 ///
2310 /// The argument \p Arg is replaced with new ones defined by the number,
2311 /// order, and types in \p ReplacementTypes. The rewiring at the call sites is
2312 /// done through \p ACSRepairCB and at the callee site through
2313 /// \p CalleeRepairCB.
2314 ///
2315 /// \returns True, if the replacement was registered, false otherwise.
2317 Argument &Arg, ArrayRef<Type *> ReplacementTypes,
2320
2321 /// Check \p Pred on all function call sites.
2322 ///
2323 /// This method will evaluate \p Pred on call sites and return
2324 /// true if \p Pred holds in every call sites. However, this is only possible
2325 /// all call sites are known, hence the function has internal linkage.
2326 /// If true is returned, \p UsedAssumedInformation is set if assumed
2327 /// information was used to skip or simplify potential call sites.
2329 const AbstractAttribute &QueryingAA,
2330 bool RequireAllCallSites,
2331 bool &UsedAssumedInformation);
2332
2333 /// Check \p Pred on all call sites of \p Fn.
2334 ///
2335 /// This method will evaluate \p Pred on call sites and return
2336 /// true if \p Pred holds in every call sites. However, this is only possible
2337 /// all call sites are known, hence the function has internal linkage.
2338 /// If true is returned, \p UsedAssumedInformation is set if assumed
2339 /// information was used to skip or simplify potential call sites.
2341 const Function &Fn,
2342 bool RequireAllCallSites,
2343 const AbstractAttribute *QueryingAA,
2344 bool &UsedAssumedInformation,
2345 bool CheckPotentiallyDead = false);
2346
2347 /// Check \p Pred on all values potentially returned by the function
2348 /// associated with \p QueryingAA.
2349 ///
2350 /// This is the context insensitive version of the method above.
2351 LLVM_ABI bool
2353 const AbstractAttribute &QueryingAA,
2355 bool RecurseForSelectAndPHI = true);
2356
2357 /// Check \p Pred on all instructions in \p Fn with an opcode present in
2358 /// \p Opcodes.
2359 ///
2360 /// This method will evaluate \p Pred on all instructions with an opcode
2361 /// present in \p Opcode and return true if \p Pred holds on all of them.
2363 const Function *Fn,
2364 const AbstractAttribute *QueryingAA,
2365 ArrayRef<unsigned> Opcodes,
2366 bool &UsedAssumedInformation,
2367 bool CheckBBLivenessOnly = false,
2368 bool CheckPotentiallyDead = false);
2369
2370 /// Check \p Pred on all instructions with an opcode present in \p Opcodes.
2371 ///
2372 /// This method will evaluate \p Pred on all instructions with an opcode
2373 /// present in \p Opcode and return true if \p Pred holds on all of them.
2375 const AbstractAttribute &QueryingAA,
2376 ArrayRef<unsigned> Opcodes,
2377 bool &UsedAssumedInformation,
2378 bool CheckBBLivenessOnly = false,
2379 bool CheckPotentiallyDead = false);
2380
2381 /// Check \p Pred on all call-like instructions (=CallBased derived).
2382 ///
2383 /// See checkForAllCallLikeInstructions(...) for more information.
2385 const AbstractAttribute &QueryingAA,
2386 bool &UsedAssumedInformation,
2387 bool CheckBBLivenessOnly = false,
2388 bool CheckPotentiallyDead = false) {
2390 Pred, QueryingAA,
2391 {(unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,
2392 (unsigned)Instruction::Call},
2393 UsedAssumedInformation, CheckBBLivenessOnly, CheckPotentiallyDead);
2394 }
2395
2396 /// Check \p Pred on all Read/Write instructions.
2397 ///
2398 /// This method will evaluate \p Pred on all instructions that read or write
2399 /// to memory present in the information cache and return true if \p Pred
2400 /// holds on all of them.
2401 LLVM_ABI bool
2403 AbstractAttribute &QueryingAA,
2404 bool &UsedAssumedInformation);
2405
2406 /// Create a shallow wrapper for \p F such that \p F has internal linkage
2407 /// afterwards. It also sets the original \p F 's name to anonymous
2408 ///
2409 /// A wrapper is a function with the same type (and attributes) as \p F
2410 /// that will only call \p F and return the result, if any.
2411 ///
2412 /// Assuming the declaration of looks like:
2413 /// rty F(aty0 arg0, ..., atyN argN);
2414 ///
2415 /// The wrapper will then look as follows:
2416 /// rty wrapper(aty0 arg0, ..., atyN argN) {
2417 /// return F(arg0, ..., argN);
2418 /// }
2419 ///
2421
2422 /// Returns true if the function \p F can be internalized. i.e. it has a
2423 /// compatible linkage.
2424 LLVM_ABI static bool isInternalizable(Function &F);
2425
2426 /// Make another copy of the function \p F such that the copied version has
2427 /// internal linkage afterwards and can be analysed. Then we replace all uses
2428 /// of the original function to the copied one
2429 ///
2430 /// Only non-locally linked functions that have `linkonce_odr` or `weak_odr`
2431 /// linkage can be internalized because these linkages guarantee that other
2432 /// definitions with the same name have the same semantics as this one.
2433 ///
2434 /// This will only be run if the `attributor-allow-deep-wrappers` option is
2435 /// set, or if the function is called with \p Force set to true.
2436 ///
2437 /// If the function \p F failed to be internalized the return value will be a
2438 /// null pointer.
2440 bool Force = false);
2441
2442 /// Make copies of each function in the set \p FnSet such that the copied
2443 /// version has internal linkage afterwards and can be analysed. Then we
2444 /// replace all uses of the original function to the copied one. The map
2445 /// \p FnMap contains a mapping of functions to their internalized versions.
2446 ///
2447 /// Only non-locally linked functions that have `linkonce_odr` or `weak_odr`
2448 /// linkage can be internalized because these linkages guarantee that other
2449 /// definitions with the same name have the same semantics as this one.
2450 ///
2451 /// This version will internalize all the functions in the set \p FnSet at
2452 /// once and then replace the uses. This prevents internalized functions being
2453 /// called by external functions when there is an internalized version in the
2454 /// module.
2455 LLVM_ABI static bool
2458
2459 /// Return the data layout associated with the anchor scope.
2460 const DataLayout &getDataLayout() const { return InfoCache.getDL(); }
2461
2462 /// The allocator used to allocate memory, e.g. for `AbstractAttribute`s.
2464
2466 return CGModifiedFunctions;
2467 }
2468
2469private:
2470 /// This method will do fixpoint iteration until fixpoint or the
2471 /// maximum iteration count is reached.
2472 ///
2473 /// If the maximum iteration count is reached, This method will
2474 /// indicate pessimistic fixpoint on attributes that transitively depend
2475 /// on attributes that were scheduled for an update.
2476 void runTillFixpoint();
2477
2478 /// Gets called after scheduling, manifests attributes to the LLVM IR.
2479 ChangeStatus manifestAttributes();
2480
2481 /// Gets called after attributes have been manifested, cleans up the IR.
2482 /// Deletes dead functions, blocks and instructions.
2483 /// Rewrites function signitures and updates the call graph.
2484 ChangeStatus cleanupIR();
2485
2486 /// Identify internal functions that are effectively dead, thus not reachable
2487 /// from a live entry point. The functions are added to ToBeDeletedFunctions.
2488 void identifyDeadInternalFunctions();
2489
2490 /// Run `::update` on \p AA and track the dependences queried while doing so.
2491 /// Also adjust the state if we know further updates are not necessary.
2493
2494 /// Remember the dependences on the top of the dependence stack such that they
2495 /// may trigger further updates. (\see DependenceStack)
2496 void rememberDependences();
2497
2498 /// Determine if CallBase context in \p IRP should be propagated.
2499 LLVM_ABI bool shouldPropagateCallBaseContext(const IRPosition &IRP);
2500
2501 /// Apply all requested function signature rewrites
2502 /// (\see registerFunctionSignatureRewrite) and return Changed if the module
2503 /// was altered.
2505 rewriteFunctionSignatures(SmallSetVector<Function *, 8> &ModifiedFns);
2506
2507 /// Check if the Attribute \p AA should be seeded.
2508 /// See getOrCreateAAFor.
2509 LLVM_ABI bool shouldSeedAttribute(AbstractAttribute &AA);
2510
2511 /// A nested map to lookup abstract attributes based on the argument position
2512 /// on the outer level, and the addresses of the static member (AAType::ID) on
2513 /// the inner level.
2514 ///{
2515 using AAMapKeyTy = std::pair<const char *, IRPosition>;
2517 ///}
2518
2519 /// Map to remember all requested signature changes (= argument replacements).
2521 ArgumentReplacementMap;
2522
2523 /// The set of functions we are deriving attributes for.
2524 SetVector<Function *> &Functions;
2525
2526 /// The information cache that holds pre-processed (LLVM-IR) information.
2527 InformationCache &InfoCache;
2528
2529 /// Abstract Attribute dependency graph
2530 AADepGraph DG;
2531
2532 /// Set of functions for which we modified the content such that it might
2533 /// impact the call graph.
2534 SmallSetVector<Function *, 8> CGModifiedFunctions;
2535
2536 /// Information about a dependence. If FromAA is changed ToAA needs to be
2537 /// updated as well.
2538 struct DepInfo {
2539 const AbstractAttribute *FromAA;
2540 const AbstractAttribute *ToAA;
2541 DepClassTy DepClass;
2542 };
2543
2544 /// The dependence stack is used to track dependences during an
2545 /// `AbstractAttribute::update` call. As `AbstractAttribute::update` can be
2546 /// recursive we might have multiple vectors of dependences in here. The stack
2547 /// size, should be adjusted according to the expected recursion depth and the
2548 /// inner dependence vector size to the expected number of dependences per
2549 /// abstract attribute. Since the inner vectors are actually allocated on the
2550 /// stack we can be generous with their size.
2551 using DependenceVector = SmallVector<DepInfo, 8>;
2553
2554 /// A set to remember the functions we already assume to be live and visited.
2555 DenseSet<const Function *> VisitedFunctions;
2556
2557 /// Uses we replace with a new value after manifest is done. We will remove
2558 /// then trivially dead instructions as well.
2559 SmallMapVector<Use *, Value *, 32> ToBeChangedUses;
2560
2561 /// Values we replace with a new value after manifest is done. We will remove
2562 /// then trivially dead instructions as well.
2563 SmallMapVector<Value *, PointerIntPair<Value *, 1, bool>, 32>
2564 ToBeChangedValues;
2565
2566 /// Instructions we replace with `unreachable` insts after manifest is done.
2567 SmallSetVector<WeakVH, 16> ToBeChangedToUnreachableInsts;
2568
2569 /// Invoke instructions with at least a single dead successor block.
2570 SmallSetVector<WeakVH, 16> InvokeWithDeadSuccessor;
2571
2572 /// A flag that indicates which stage of the process we are in. Initially, the
2573 /// phase is SEEDING. Phase is changed in `Attributor::run()`
2574 enum class AttributorPhase {
2575 SEEDING,
2576 UPDATE,
2577 MANIFEST,
2578 CLEANUP,
2579 } Phase = AttributorPhase::SEEDING;
2580
2581 /// The current initialization chain length. Tracked to avoid stack overflows.
2582 unsigned InitializationChainLength = 0;
2583
2584 /// Functions, blocks, and instructions we delete after manifest is done.
2585 ///
2586 ///{
2587 SmallPtrSet<BasicBlock *, 8> ManifestAddedBlocks;
2588 SmallSetVector<Function *, 8> ToBeDeletedFunctions;
2589 SmallSetVector<BasicBlock *, 8> ToBeDeletedBlocks;
2590 SmallSetVector<WeakVH, 8> ToBeDeletedInsts;
2591 ///}
2592
2593 /// Container with all the query AAs that requested an update via
2594 /// registerForUpdate.
2595 SmallSetVector<AbstractAttribute *, 16> QueryAAsAwaitingUpdate;
2596
2597 /// User provided configuration for this Attributor instance.
2598 const AttributorConfig Configuration;
2599
2600 friend AADepGraph;
2601 friend AttributorCallGraph;
2602};
2603
2604/// An interface to query the internal state of an abstract attribute.
2605///
2606/// The abstract state is a minimal interface that allows the Attributor to
2607/// communicate with the abstract attributes about their internal state without
2608/// enforcing or exposing implementation details, e.g., the (existence of an)
2609/// underlying lattice.
2610///
2611/// It is sufficient to be able to query if a state is (1) valid or invalid, (2)
2612/// at a fixpoint, and to indicate to the state that (3) an optimistic fixpoint
2613/// was reached or (4) a pessimistic fixpoint was enforced.
2614///
2615/// All methods need to be implemented by the subclass. For the common use case,
2616/// a single boolean state or a bit-encoded state, the BooleanState and
2617/// {Inc,Dec,Bit}IntegerState classes are already provided. An abstract
2618/// attribute can inherit from them to get the abstract state interface and
2619/// additional methods to directly modify the state based if needed. See the
2620/// class comments for help.
2622 virtual ~AbstractState() = default;
2623
2624 /// Return if this abstract state is in a valid state. If false, no
2625 /// information provided should be used.
2626 virtual bool isValidState() const = 0;
2627
2628 /// Return if this abstract state is fixed, thus does not need to be updated
2629 /// if information changes as it cannot change itself.
2630 virtual bool isAtFixpoint() const = 0;
2631
2632 /// Indicate that the abstract state should converge to the optimistic state.
2633 ///
2634 /// This will usually make the optimistically assumed state the known to be
2635 /// true state.
2636 ///
2637 /// \returns ChangeStatus::UNCHANGED as the assumed value should not change.
2639
2640 /// Indicate that the abstract state should converge to the pessimistic state.
2641 ///
2642 /// This will usually revert the optimistically assumed state to the known to
2643 /// be true state.
2644 ///
2645 /// \returns ChangeStatus::CHANGED as the assumed value may change.
2647};
2648
2649/// Simple state with integers encoding.
2650///
2651/// The interface ensures that the assumed bits are always a subset of the known
2652/// bits. Users can only add known bits and, except through adding known bits,
2653/// they can only remove assumed bits. This should guarantee monotonicity and
2654/// thereby the existence of a fixpoint (if used correctly). The fixpoint is
2655/// reached when the assumed and known state/bits are equal. Users can
2656/// force/inidicate a fixpoint. If an optimistic one is indicated, the known
2657/// state will catch up with the assumed one, for a pessimistic fixpoint it is
2658/// the other way around.
2659template <typename base_ty, base_ty BestState, base_ty WorstState>
2661 using base_t = base_ty;
2662
2663 IntegerStateBase() = default;
2665
2666 /// Return the best possible representable state.
2667 static constexpr base_t getBestState() { return BestState; }
2668 static constexpr base_t getBestState(const IntegerStateBase &) {
2669 return getBestState();
2670 }
2671
2672 /// Return the worst possible representable state.
2673 static constexpr base_t getWorstState() { return WorstState; }
2674 static constexpr base_t getWorstState(const IntegerStateBase &) {
2675 return getWorstState();
2676 }
2677
2678 /// See AbstractState::isValidState()
2679 /// NOTE: For now we simply pretend that the worst possible state is invalid.
2680 bool isValidState() const override { return Assumed != getWorstState(); }
2681
2682 /// See AbstractState::isAtFixpoint()
2683 bool isAtFixpoint() const override { return Assumed == Known; }
2684
2685 /// See AbstractState::indicateOptimisticFixpoint(...)
2690
2691 /// See AbstractState::indicatePessimisticFixpoint(...)
2696
2697 /// Return the known state encoding
2698 base_t getKnown() const { return Known; }
2699
2700 /// Return the assumed state encoding.
2701 base_t getAssumed() const { return Assumed; }
2702
2703 /// Equality for IntegerStateBase.
2704 bool
2706 return this->getAssumed() == R.getAssumed() &&
2707 this->getKnown() == R.getKnown();
2708 }
2709
2710 /// Inequality for IntegerStateBase.
2711 bool
2713 return !(*this == R);
2714 }
2715
2716 /// "Clamp" this state with \p R. The result is subtype dependent but it is
2717 /// intended that only information assumed in both states will be assumed in
2718 /// this one afterwards.
2722
2723 /// "Clamp" this state with \p R. The result is subtype dependent but it is
2724 /// intended that information known in either state will be known in
2725 /// this one afterwards.
2729
2731 joinOR(R.getAssumed(), R.getKnown());
2732 }
2733
2735 joinAND(R.getAssumed(), R.getKnown());
2736 }
2737
2738protected:
2739 /// Handle a new assumed value \p Value. Subtype dependent.
2741
2742 /// Handle a new known value \p Value. Subtype dependent.
2744
2745 /// Handle a value \p Value. Subtype dependent.
2746 virtual void joinOR(base_t AssumedValue, base_t KnownValue) = 0;
2747
2748 /// Handle a new assumed value \p Value. Subtype dependent.
2749 virtual void joinAND(base_t AssumedValue, base_t KnownValue) = 0;
2750
2751 /// The known state encoding in an integer of type base_t.
2753
2754 /// The assumed state encoding in an integer of type base_t.
2756};
2757
2758/// Specialization of the integer state for a bit-wise encoding.
2759template <typename base_ty = uint32_t, base_ty BestState = ~base_ty(0),
2760 base_ty WorstState = 0>
2762 : public IntegerStateBase<base_ty, BestState, WorstState> {
2764 using base_t = base_ty;
2765 BitIntegerState() = default;
2767
2768 /// Return true if the bits set in \p BitsEncoding are "known bits".
2769 bool isKnown(base_t BitsEncoding = BestState) const {
2770 return (this->Known & BitsEncoding) == BitsEncoding;
2771 }
2772
2773 /// Return true if the bits set in \p BitsEncoding are "assumed bits".
2774 bool isAssumed(base_t BitsEncoding = BestState) const {
2775 return (this->Assumed & BitsEncoding) == BitsEncoding;
2776 }
2777
2778 /// Add the bits in \p BitsEncoding to the "known bits".
2780 // Make sure we never miss any "known bits".
2781 this->Assumed |= Bits;
2782 this->Known |= Bits;
2783 return *this;
2784 }
2785
2786 /// Remove the bits in \p BitsEncoding from the "assumed bits" if not known.
2788 return intersectAssumedBits(~BitsEncoding);
2789 }
2790
2791 /// Remove the bits in \p BitsEncoding from the "known bits".
2793 this->Known = (this->Known & ~BitsEncoding);
2794 return *this;
2795 }
2796
2797 /// Keep only "assumed bits" also set in \p BitsEncoding but all known ones.
2799 // Make sure we never lose any "known bits".
2800 this->Assumed = (this->Assumed & BitsEncoding) | this->Known;
2801 return *this;
2802 }
2803
2804private:
2805 void handleNewAssumedValue(base_t Value) override {
2807 }
2808 void handleNewKnownValue(base_t Value) override { addKnownBits(Value); }
2809 void joinOR(base_t AssumedValue, base_t KnownValue) override {
2810 this->Known |= KnownValue;
2811 this->Assumed |= AssumedValue;
2812 }
2813 void joinAND(base_t AssumedValue, base_t KnownValue) override {
2814 this->Known &= KnownValue;
2815 this->Assumed &= AssumedValue;
2816 }
2817};
2818
2819/// Specialization of the integer state for an increasing value, hence ~0u is
2820/// the best state and 0 the worst.
2821template <typename base_ty = uint32_t, base_ty BestState = ~base_ty(0),
2822 base_ty WorstState = 0>
2824 : public IntegerStateBase<base_ty, BestState, WorstState> {
2826 using base_t = base_ty;
2827
2830
2831 /// Return the best possible representable state.
2832 static constexpr base_t getBestState() { return BestState; }
2833 static constexpr base_t
2837
2838 /// Take minimum of assumed and \p Value.
2840 // Make sure we never lose "known value".
2841 this->Assumed = std::max(std::min(this->Assumed, Value), this->Known);
2842 return *this;
2843 }
2844
2845 /// Take maximum of known and \p Value.
2847 // Make sure we never lose "known value".
2848 this->Assumed = std::max(Value, this->Assumed);
2849 this->Known = std::max(Value, this->Known);
2850 return *this;
2851 }
2852
2853private:
2854 void handleNewAssumedValue(base_t Value) override {
2856 }
2857 void handleNewKnownValue(base_t Value) override { takeKnownMaximum(Value); }
2858 void joinOR(base_t AssumedValue, base_t KnownValue) override {
2859 this->Known = std::max(this->Known, KnownValue);
2860 this->Assumed = std::max(this->Assumed, AssumedValue);
2861 }
2862 void joinAND(base_t AssumedValue, base_t KnownValue) override {
2863 this->Known = std::min(this->Known, KnownValue);
2864 this->Assumed = std::min(this->Assumed, AssumedValue);
2865 }
2866};
2867
2868/// Specialization of the integer state for a decreasing value, hence 0 is the
2869/// best state and ~0u the worst.
2870template <typename base_ty = uint32_t>
2871struct DecIntegerState : public IntegerStateBase<base_ty, 0, ~base_ty(0)> {
2872 using base_t = base_ty;
2873
2874 /// Take maximum of assumed and \p Value.
2876 // Make sure we never lose "known value".
2877 this->Assumed = std::min(std::max(this->Assumed, Value), this->Known);
2878 return *this;
2879 }
2880
2881 /// Take minimum of known and \p Value.
2883 // Make sure we never lose "known value".
2884 this->Assumed = std::min(Value, this->Assumed);
2885 this->Known = std::min(Value, this->Known);
2886 return *this;
2887 }
2888
2889private:
2890 void handleNewAssumedValue(base_t Value) override {
2892 }
2893 void handleNewKnownValue(base_t Value) override { takeKnownMinimum(Value); }
2894 void joinOR(base_t AssumedValue, base_t KnownValue) override {
2895 this->Assumed = std::min(this->Assumed, KnownValue);
2896 this->Assumed = std::min(this->Assumed, AssumedValue);
2897 }
2898 void joinAND(base_t AssumedValue, base_t KnownValue) override {
2899 this->Assumed = std::max(this->Assumed, KnownValue);
2900 this->Assumed = std::max(this->Assumed, AssumedValue);
2901 }
2902};
2903
2904/// Simple wrapper for a single bit (boolean) state.
2905struct BooleanState : public IntegerStateBase<bool, true, false> {
2908
2909 BooleanState() = default;
2911
2912 /// Set the assumed value to \p Value but never below the known one.
2913 void setAssumed(bool Value) { Assumed &= (Known | Value); }
2914
2915 /// Set the known and asssumed value to \p Value.
2916 void setKnown(bool Value) {
2917 Known |= Value;
2918 Assumed |= Value;
2919 }
2920
2921 /// Return true if the state is assumed to hold.
2922 bool isAssumed() const { return getAssumed(); }
2923
2924 /// Return true if the state is known to hold.
2925 bool isKnown() const { return getKnown(); }
2926
2927private:
2928 void handleNewAssumedValue(base_t Value) override {
2929 if (!Value)
2930 Assumed = Known;
2931 }
2932 void handleNewKnownValue(base_t Value) override {
2933 if (Value)
2934 Known = (Assumed = Value);
2935 }
2936 void joinOR(base_t AssumedValue, base_t KnownValue) override {
2937 Known |= KnownValue;
2938 Assumed |= AssumedValue;
2939 }
2940 void joinAND(base_t AssumedValue, base_t KnownValue) override {
2941 Known &= KnownValue;
2942 Assumed &= AssumedValue;
2943 }
2944};
2945
2946/// State for an integer range.
2948
2949 /// Bitwidth of the associated value.
2951
2952 /// State representing assumed range, initially set to empty.
2954
2955 /// State representing known range, initially set to [-inf, inf].
2957
2961
2965
2966 /// Return the worst possible representable state.
2968 return ConstantRange::getFull(BitWidth);
2969 }
2970
2971 /// Return the best possible representable state.
2973 return ConstantRange::getEmpty(BitWidth);
2974 }
2976 return getBestState(IRS.getBitWidth());
2977 }
2978
2979 /// Return associated values' bit width.
2980 uint32_t getBitWidth() const { return BitWidth; }
2981
2982 /// See AbstractState::isValidState()
2983 bool isValidState() const override {
2984 return BitWidth > 0 && !Assumed.isFullSet();
2985 }
2986
2987 /// See AbstractState::isAtFixpoint()
2988 bool isAtFixpoint() const override { return Assumed == Known; }
2989
2990 /// See AbstractState::indicateOptimisticFixpoint(...)
2995
2996 /// See AbstractState::indicatePessimisticFixpoint(...)
3001
3002 /// Return the known state encoding
3003 ConstantRange getKnown() const { return Known; }
3004
3005 /// Return the assumed state encoding.
3007
3008 /// Unite assumed range with the passed state.
3010 // Don't lose a known range.
3011 Assumed = Assumed.unionWith(R).intersectWith(Known);
3012 }
3013
3014 /// See IntegerRangeState::unionAssumed(..).
3016 unionAssumed(R.getAssumed());
3017 }
3018
3019 /// Intersect known range with the passed state.
3021 Assumed = Assumed.intersectWith(R);
3022 Known = Known.intersectWith(R);
3023 }
3024
3025 /// See IntegerRangeState::intersectKnown(..).
3027 intersectKnown(R.getKnown());
3028 }
3029
3030 /// Equality for IntegerRangeState.
3031 bool operator==(const IntegerRangeState &R) const {
3032 return getAssumed() == R.getAssumed() && getKnown() == R.getKnown();
3033 }
3034
3035 /// "Clamp" this state with \p R. The result is subtype dependent but it is
3036 /// intended that only information assumed in both states will be assumed in
3037 /// this one afterwards.
3039 // NOTE: `^=` operator seems like `intersect` but in this case, we need to
3040 // take `union`.
3041 unionAssumed(R);
3042 return *this;
3043 }
3044
3046 // NOTE: `&=` operator seems like `intersect` but in this case, we need to
3047 // take `union`.
3048 Known = Known.unionWith(R.getKnown());
3049 Assumed = Assumed.unionWith(R.getAssumed());
3050 return *this;
3051 }
3052};
3053
3054/// Simple state for a set.
3055///
3056/// This represents a state containing a set of values. The interface supports
3057/// modelling sets that contain all possible elements. The state's internal
3058/// value is modified using union or intersection operations.
3059template <typename BaseTy> struct SetState : public AbstractState {
3060 /// A wrapper around a set that has semantics for handling unions and
3061 /// intersections with a "universal" set that contains all elements.
3063 /// Creates a universal set with no concrete elements or an empty set.
3064 SetContents(bool Universal) : Universal(Universal) {}
3065
3066 /// Creates a non-universal set with concrete values.
3067 SetContents(const DenseSet<BaseTy> &Assumptions)
3068 : Universal(false), Set(Assumptions) {}
3069
3070 SetContents(bool Universal, const DenseSet<BaseTy> &Assumptions)
3071 : Universal(Universal), Set(Assumptions) {}
3072
3073 const DenseSet<BaseTy> &getSet() const { return Set; }
3074
3075 bool isUniversal() const { return Universal; }
3076
3077 bool empty() const { return Set.empty() && !Universal; }
3078
3079 /// Finds A := A ^ B where A or B could be the "Universal" set which
3080 /// contains every possible attribute. Returns true if changes were made.
3082 bool IsUniversal = Universal;
3083 unsigned Size = Set.size();
3084
3085 // A := A ^ U = A
3086 if (RHS.isUniversal())
3087 return false;
3088
3089 // A := U ^ B = B
3090 if (Universal)
3091 Set = RHS.getSet();
3092 else
3093 set_intersect(Set, RHS.getSet());
3094
3095 Universal &= RHS.isUniversal();
3096 return IsUniversal != Universal || Size != Set.size();
3097 }
3098
3099 /// Finds A := A u B where A or B could be the "Universal" set which
3100 /// contains every possible attribute. returns true if changes were made.
3101 bool getUnion(const SetContents &RHS) {
3102 bool IsUniversal = Universal;
3103 unsigned Size = Set.size();
3104
3105 // A := A u U = U = U u B
3106 if (!RHS.isUniversal() && !Universal)
3107 set_union(Set, RHS.getSet());
3108
3109 Universal |= RHS.isUniversal();
3110 return IsUniversal != Universal || Size != Set.size();
3111 }
3112
3113 private:
3114 /// Indicates if this set is "universal", containing every possible element.
3115 bool Universal;
3116
3117 /// The set of currently active assumptions.
3118 DenseSet<BaseTy> Set;
3119 };
3120
3121 SetState() : Known(false), Assumed(true), IsAtFixedpoint(false) {}
3122
3123 /// Initializes the known state with an initial set and initializes the
3124 /// assumed state as universal.
3126 : Known(Known), Assumed(true), IsAtFixedpoint(false) {}
3127
3128 /// See AbstractState::isValidState()
3129 bool isValidState() const override { return !Assumed.empty(); }
3130
3131 /// See AbstractState::isAtFixpoint()
3132 bool isAtFixpoint() const override { return IsAtFixedpoint; }
3133
3134 /// See AbstractState::indicateOptimisticFixpoint(...)
3136 IsAtFixedpoint = true;
3137 Known = Assumed;
3139 }
3140
3141 /// See AbstractState::indicatePessimisticFixpoint(...)
3143 IsAtFixedpoint = true;
3144 Assumed = Known;
3145 return ChangeStatus::CHANGED;
3146 }
3147
3148 /// Return the known state encoding.
3149 const SetContents &getKnown() const { return Known; }
3150
3151 /// Return the assumed state encoding.
3152 const SetContents &getAssumed() const { return Assumed; }
3153
3154 /// Returns if the set state contains the element.
3155 bool setContains(const BaseTy &Elem) const {
3156 return Assumed.getSet().contains(Elem) || Known.getSet().contains(Elem);
3157 }
3158
3159 /// Performs the set intersection between this set and \p RHS. Returns true if
3160 /// changes were made.
3162 bool IsUniversal = Assumed.isUniversal();
3163 unsigned SizeBefore = Assumed.getSet().size();
3164
3165 // Get intersection and make sure that the known set is still a proper
3166 // subset of the assumed set. A := K u (A ^ R).
3167 Assumed.getIntersection(RHS);
3168 Assumed.getUnion(Known);
3169
3170 return SizeBefore != Assumed.getSet().size() ||
3171 IsUniversal != Assumed.isUniversal();
3172 }
3173
3174 /// Performs the set union between this set and \p RHS. Returns true if
3175 /// changes were made.
3176 bool getUnion(const SetContents &RHS) { return Assumed.getUnion(RHS); }
3177
3178private:
3179 /// The set of values known for this state.
3180 SetContents Known;
3181
3182 /// The set of assumed values for this state.
3183 SetContents Assumed;
3184
3185 bool IsAtFixedpoint;
3186};
3187
3188/// Helper to tie a abstract state implementation to an abstract attribute.
3189template <typename StateTy, typename BaseType, class... Ts>
3190struct StateWrapper : public BaseType, public StateTy {
3191 /// Provide static access to the type of the state.
3193
3194 StateWrapper(const IRPosition &IRP, Ts... Args)
3195 : BaseType(IRP), StateTy(Args...) {}
3196
3197 /// See AbstractAttribute::getState(...).
3198 StateType &getState() override { return *this; }
3199
3200 /// See AbstractAttribute::getState(...).
3201 const StateType &getState() const override { return *this; }
3202};
3203
3204/// Helper class that provides common functionality to manifest IR attributes.
3205template <Attribute::AttrKind AK, typename BaseType, typename AAType>
3206struct IRAttribute : public BaseType {
3207 IRAttribute(const IRPosition &IRP) : BaseType(IRP) {}
3208
3209 /// Most boolean IRAttribute AAs don't do anything non-trivial
3210 /// in their initializers while non-boolean ones often do. Subclasses can
3211 /// change this.
3213
3214 /// Compile time access to the IR attribute kind.
3216
3217 /// Return true if the IR attribute(s) associated with this AA are implied for
3218 /// an undef value.
3219 static bool isImpliedByUndef() { return true; }
3220
3221 /// Return true if the IR attribute(s) associated with this AA are implied for
3222 /// an poison value.
3223 static bool isImpliedByPoison() { return true; }
3224
3225 static bool isImpliedByIR(Attributor &A, const IRPosition &IRP,
3226 Attribute::AttrKind ImpliedAttributeKind = AK,
3227 bool IgnoreSubsumingPositions = false) {
3228 if (AAType::isImpliedByUndef() && isa<UndefValue>(IRP.getAssociatedValue()))
3229 return true;
3230 if (AAType::isImpliedByPoison() &&
3232 return true;
3233 return A.hasAttr(IRP, {ImpliedAttributeKind}, IgnoreSubsumingPositions,
3234 ImpliedAttributeKind);
3235 }
3236
3237 /// See AbstractAttribute::manifest(...).
3239 if (isa<UndefValue>(this->getIRPosition().getAssociatedValue()))
3241 SmallVector<Attribute, 4> DeducedAttrs;
3242 getDeducedAttributes(A, this->getAnchorValue().getContext(), DeducedAttrs);
3243 if (DeducedAttrs.empty())
3245 return A.manifestAttrs(this->getIRPosition(), DeducedAttrs);
3246 }
3247
3248 /// Return the kind that identifies the abstract attribute implementation.
3249 Attribute::AttrKind getAttrKind() const { return AK; }
3250
3251 /// Return the deduced attributes in \p Attrs.
3253 SmallVectorImpl<Attribute> &Attrs) const {
3254 Attrs.emplace_back(Attribute::get(Ctx, getAttrKind()));
3255 }
3256};
3257
3258/// Base struct for all "concrete attribute" deductions.
3259///
3260/// The abstract attribute is a minimal interface that allows the Attributor to
3261/// orchestrate the abstract/fixpoint analysis. The design allows to hide away
3262/// implementation choices made for the subclasses but also to structure their
3263/// implementation and simplify the use of other abstract attributes in-flight.
3264///
3265/// To allow easy creation of new attributes, most methods have default
3266/// implementations. The ones that do not are generally straight forward, except
3267/// `AbstractAttribute::updateImpl` which is the location of most reasoning
3268/// associated with the abstract attribute. The update is invoked by the
3269/// Attributor in case the situation used to justify the current optimistic
3270/// state might have changed. The Attributor determines this automatically
3271/// by monitoring the `Attributor::getAAFor` calls made by abstract attributes.
3272///
3273/// The `updateImpl` method should inspect the IR and other abstract attributes
3274/// in-flight to justify the best possible (=optimistic) state. The actual
3275/// implementation is, similar to the underlying abstract state encoding, not
3276/// exposed. In the most common case, the `updateImpl` will go through a list of
3277/// reasons why its optimistic state is valid given the current information. If
3278/// any combination of them holds and is sufficient to justify the current
3279/// optimistic state, the method shall return UNCHAGED. If not, the optimistic
3280/// state is adjusted to the situation and the method shall return CHANGED.
3281///
3282/// If the manifestation of the "concrete attribute" deduced by the subclass
3283/// differs from the "default" behavior, which is a (set of) LLVM-IR
3284/// attribute(s) for an argument, call site argument, function return value, or
3285/// function, the `AbstractAttribute::manifest` method should be overloaded.
3286///
3287/// NOTE: If the state obtained via getState() is INVALID, thus if
3288/// AbstractAttribute::getState().isValidState() returns false, no
3289/// information provided by the methods of this class should be used.
3290/// NOTE: The Attributor currently has certain limitations to what we can do.
3291/// As a general rule of thumb, "concrete" abstract attributes should *for
3292/// now* only perform "backward" information propagation. That means
3293/// optimistic information obtained through abstract attributes should
3294/// only be used at positions that precede the origin of the information
3295/// with regards to the program flow. More practically, information can
3296/// *now* be propagated from instructions to their enclosing function, but
3297/// *not* from call sites to the called function. The mechanisms to allow
3298/// both directions will be added in the future.
3299/// NOTE: The mechanics of adding a new "concrete" abstract attribute are
3300/// described in the file comment.
3303
3305
3306 /// Virtual destructor.
3307 ~AbstractAttribute() override = default;
3308
3309 /// Compile time access to the IR attribute kind.
3311
3312 /// This function is used to identify if an \p DGN is of type
3313 /// AbstractAttribute so that the dyn_cast and cast can use such information
3314 /// to cast an AADepGraphNode to an AbstractAttribute.
3315 ///
3316 /// We eagerly return true here because all AADepGraphNodes except for the
3317 /// Synthethis Node are of type AbstractAttribute
3318 static bool classof(const AADepGraphNode *DGN) { return true; }
3319
3320 /// Return false if this AA does anything non-trivial (hence not done by
3321 /// default) in its initializer.
3322 static bool hasTrivialInitializer() { return false; }
3323
3324 /// Return true if this AA requires a "callee" (or an associted function) for
3325 /// a call site positon. Default is optimistic to minimize AAs.
3326 static bool requiresCalleeForCallBase() { return false; }
3327
3328 /// Return true if this AA requires non-asm "callee" for a call site positon.
3329 static bool requiresNonAsmForCallBase() { return true; }
3330
3331 /// Return true if this AA requires all callees for an argument or function
3332 /// positon.
3333 static bool requiresCallersForArgOrFunction() { return false; }
3334
3335 /// Return false if an AA should not be created for \p IRP.
3337 return true;
3338 }
3339
3340 /// Return false if an AA should not be updated for \p IRP.
3342 Function *AssociatedFn = IRP.getAssociatedFunction();
3343 bool IsFnInterface = IRP.isFnInterfaceKind();
3344 assert((!IsFnInterface || AssociatedFn) &&
3345 "Function interface without a function?");
3346
3347 // TODO: Not all attributes require an exact definition. Find a way to
3348 // enable deduction for some but not all attributes in case the
3349 // definition might be changed at runtime, see also
3350 // http://lists.llvm.org/pipermail/llvm-dev/2018-February/121275.html.
3351 // TODO: We could always determine abstract attributes and if sufficient
3352 // information was found we could duplicate the functions that do not
3353 // have an exact definition.
3354 return !IsFnInterface || A.isFunctionIPOAmendable(*AssociatedFn);
3355 }
3356
3357 /// Initialize the state with the information in the Attributor \p A.
3358 ///
3359 /// This function is called by the Attributor once all abstract attributes
3360 /// have been identified. It can and shall be used for task like:
3361 /// - identify existing knowledge in the IR and use it for the "known state"
3362 /// - perform any work that is not going to change over time, e.g., determine
3363 /// a subset of the IR, or attributes in-flight, that have to be looked at
3364 /// in the `updateImpl` method.
3365 virtual void initialize(Attributor &A) {}
3366
3367 /// A query AA is always scheduled as long as we do updates because it does
3368 /// lazy computation that cannot be determined to be done from the outside.
3369 /// However, while query AAs will not be fixed if they do not have outstanding
3370 /// dependences, we will only schedule them like other AAs. If a query AA that
3371 /// received a new query it needs to request an update via
3372 /// `Attributor::requestUpdateForAA`.
3373 virtual bool isQueryAA() const { return false; }
3374
3375 /// Return the internal abstract state for inspection.
3376 virtual StateType &getState() = 0;
3377 virtual const StateType &getState() const = 0;
3378
3379 /// Return an IR position, see struct IRPosition.
3380 const IRPosition &getIRPosition() const { return *this; };
3381 IRPosition &getIRPosition() { return *this; };
3382
3383 /// Helper functions, for debug purposes only.
3384 ///{
3385 void print(raw_ostream &OS) const { print(nullptr, OS); }
3386 void print(Attributor *, raw_ostream &OS) const override;
3387 virtual void printWithDeps(raw_ostream &OS) const;
3388 void dump() const { this->print(dbgs()); }
3389
3390 /// This function should return the "summarized" assumed state as string.
3391 virtual const std::string getAsStr(Attributor *A) const = 0;
3392
3393 /// This function should return the name of the AbstractAttribute
3394 virtual StringRef getName() const = 0;
3395
3396 /// This function should return the address of the ID of the AbstractAttribute
3397 virtual const char *getIdAddr() const = 0;
3398 ///}
3399
3400 /// Allow the Attributor access to the protected methods.
3401 friend struct Attributor;
3402
3403protected:
3404 /// Hook for the Attributor to trigger an update of the internal state.
3405 ///
3406 /// If this attribute is already fixed, this method will return UNCHANGED,
3407 /// otherwise it delegates to `AbstractAttribute::updateImpl`.
3408 ///
3409 /// \Return CHANGED if the internal state changed, otherwise UNCHANGED.
3411
3412 /// Hook for the Attributor to trigger the manifestation of the information
3413 /// represented by the abstract attribute in the LLVM-IR.
3414 ///
3415 /// \Return CHANGED if the IR was altered, otherwise UNCHANGED.
3419
3420 /// Hook to enable custom statistic tracking, called after manifest that
3421 /// resulted in a change if statistics are enabled.
3422 ///
3423 /// We require subclasses to provide an implementation so we remember to
3424 /// add statistics for them.
3425 virtual void trackStatistics() const = 0;
3426
3427 /// The actual update/transfer function which has to be implemented by the
3428 /// derived classes.
3429 ///
3430 /// If it is called, the environment has changed and we have to determine if
3431 /// the current information is still valid or adjust it otherwise.
3432 ///
3433 /// \Return CHANGED if the internal state changed, otherwise UNCHANGED.
3435};
3436
3437/// Forward declarations of output streams for debug purposes.
3438///
3439///{
3445template <typename base_ty, base_ty BestState, base_ty WorstState>
3449 return OS << "(" << S.getKnown() << "-" << S.getAssumed() << ")"
3450 << static_cast<const AbstractState &>(S);
3451}
3452LLVM_ABI raw_ostream &operator<<(raw_ostream &OS,
3453 const IntegerRangeState &State);
3454///}
3455
3464
3465/// A more lightweight version of the Attributor which only runs attribute
3466/// inference but no simplifications.
3467struct AttributorLightPass : public OptionalPassInfoMixin<AttributorLightPass> {
3469};
3470
3471/// A more lightweight version of the Attributor which only runs attribute
3472/// inference but no simplifications.
3474 : public OptionalPassInfoMixin<AttributorLightCGSCCPass> {
3477 CGSCCUpdateResult &UR);
3478};
3479
3480/// Helper function to clamp a state \p S of type \p StateType with the
3481/// information in \p R and indicate/return if \p S did change (as-in update is
3482/// required to be run again).
3483template <typename StateType>
3484ChangeStatus clampStateAndIndicateChange(StateType &S, const StateType &R) {
3485 auto Assumed = S.getAssumed();
3486 S ^= R;
3487 return Assumed == S.getAssumed() ? ChangeStatus::UNCHANGED
3489}
3490
3491/// ----------------------------------------------------------------------------
3492/// Abstract Attribute Classes
3493/// ----------------------------------------------------------------------------
3494
3496 : public IRAttribute<Attribute::NoUnwind,
3497 StateWrapper<BooleanState, AbstractAttribute>,
3498 AANoUnwind> {
3500
3501 /// Returns true if nounwind is assumed.
3502 bool isAssumedNoUnwind() const { return getAssumed(); }
3503
3504 /// Returns true if nounwind is known.
3505 bool isKnownNoUnwind() const { return getKnown(); }
3506
3507 /// Create an abstract attribute view for the position \p IRP.
3509 Attributor &A);
3510
3511 /// See AbstractAttribute::getName()
3512 StringRef getName() const override { return "AANoUnwind"; }
3513
3514 /// See AbstractAttribute::getIdAddr()
3515 const char *getIdAddr() const override { return &ID; }
3516
3517 /// This function should return true if the type of the \p AA is AANoUnwind
3518 static bool classof(const AbstractAttribute *AA) {
3519 return (AA->getIdAddr() == &ID);
3520 }
3521
3522 /// Unique ID (due to the unique address)
3523 LLVM_ABI static const char ID;
3524};
3525
3527 : public IRAttribute<Attribute::NoSync,
3528 StateWrapper<BooleanState, AbstractAttribute>,
3529 AANoSync> {
3531
3532 static bool isImpliedByIR(Attributor &A, const IRPosition &IRP,
3533 Attribute::AttrKind ImpliedAttributeKind,
3534 bool IgnoreSubsumingPositions = false) {
3535 // Note: This is also run for non-IPO amendable functions.
3536 assert(ImpliedAttributeKind == Attribute::NoSync);
3537 if (A.hasAttr(IRP, {Attribute::NoSync}, IgnoreSubsumingPositions,
3538 Attribute::NoSync))
3539 return true;
3540
3541 // Check for readonly + non-convergent.
3542 // TODO: We should be able to use hasAttr for Attributes, not only
3543 // AttrKinds.
3545 if (!F || F->isConvergent())
3546 return false;
3547
3549 A.getAttrs(IRP, {Attribute::Memory}, Attrs, IgnoreSubsumingPositions);
3550
3552 for (const Attribute &Attr : Attrs)
3553 ME &= Attr.getMemoryEffects();
3554
3555 if (!ME.onlyReadsMemory())
3556 return false;
3557
3558 A.manifestAttrs(IRP, Attribute::get(F->getContext(), Attribute::NoSync));
3559 return true;
3560 }
3561
3562 /// See AbstractAttribute::isValidIRPositionForInit
3564 if (!IRP.isFunctionScope() &&
3566 return false;
3567 return IRAttribute::isValidIRPositionForInit(A, IRP);
3568 }
3569
3570 /// Returns true if "nosync" is assumed.
3571 bool isAssumedNoSync() const { return getAssumed(); }
3572
3573 /// Returns true if "nosync" is known.
3574 bool isKnownNoSync() const { return getKnown(); }
3575
3576 /// Helper function used to determine whether an instruction is non-relaxed
3577 /// atomic. In other words, if an atomic instruction does not have unordered
3578 /// or monotonic ordering
3579 LLVM_ABI static bool isNonRelaxedAtomic(const Instruction *I);
3580
3581 /// Helper function to determine if \p CB is an aligned (GPU) barrier. Aligned
3582 /// barriers have to be executed by all threads. The flag \p ExecutedAligned
3583 /// indicates if the call is executed by all threads in a (thread) block in an
3584 /// aligned way. If that is the case, non-aligned barriers are effectively
3585 /// aligned barriers.
3586 LLVM_ABI static bool isAlignedBarrier(const CallBase &CB,
3587 bool ExecutedAligned);
3588
3589 /// Create an abstract attribute view for the position \p IRP.
3591 Attributor &A);
3592
3593 /// See AbstractAttribute::getName()
3594 StringRef getName() const override { return "AANoSync"; }
3595
3596 /// See AbstractAttribute::getIdAddr()
3597 const char *getIdAddr() const override { return &ID; }
3598
3599 /// This function should return true if the type of the \p AA is AANoSync
3600 static bool classof(const AbstractAttribute *AA) {
3601 return (AA->getIdAddr() == &ID);
3602 }
3603
3604 /// Unique ID (due to the unique address)
3605 LLVM_ABI static const char ID;
3606};
3607
3608/// An abstract interface for all nonnull attributes.
3610 : public IRAttribute<Attribute::MustProgress,
3611 StateWrapper<BooleanState, AbstractAttribute>,
3612 AAMustProgress> {
3614
3615 static bool isImpliedByIR(Attributor &A, const IRPosition &IRP,
3616 Attribute::AttrKind ImpliedAttributeKind,
3617 bool IgnoreSubsumingPositions = false) {
3618 // Note: This is also run for non-IPO amendable functions.
3619 assert(ImpliedAttributeKind == Attribute::MustProgress);
3620 return A.hasAttr(IRP, {Attribute::MustProgress, Attribute::WillReturn},
3621 IgnoreSubsumingPositions, Attribute::MustProgress);
3622 }
3623
3624 /// Return true if we assume that the underlying value is nonnull.
3625 bool isAssumedMustProgress() const { return getAssumed(); }
3626
3627 /// Return true if we know that underlying value is nonnull.
3628 bool isKnownMustProgress() const { return getKnown(); }
3629
3630 /// Create an abstract attribute view for the position \p IRP.
3632 Attributor &A);
3633
3634 /// See AbstractAttribute::getName()
3635 StringRef getName() const override { return "AAMustProgress"; }
3636
3637 /// See AbstractAttribute::getIdAddr()
3638 const char *getIdAddr() const override { return &ID; }
3639
3640 /// This function should return true if the type of the \p AA is
3641 /// AAMustProgress
3642 static bool classof(const AbstractAttribute *AA) {
3643 return (AA->getIdAddr() == &ID);
3644 }
3645
3646 /// Unique ID (due to the unique address)
3647 LLVM_ABI static const char ID;
3648};
3649
3650/// An abstract interface for all nonnull attributes.
3652 : public IRAttribute<Attribute::NonNull,
3653 StateWrapper<BooleanState, AbstractAttribute>,
3654 AANonNull> {
3656
3657 /// See AbstractAttribute::hasTrivialInitializer.
3658 static bool hasTrivialInitializer() { return false; }
3659
3660 /// See IRAttribute::isImpliedByUndef.
3661 /// Undef is not necessarily nonnull as nonnull + noundef would cause poison.
3662 /// Poison implies nonnull though.
3663 static bool isImpliedByUndef() { return false; }
3664
3665 /// See AbstractAttribute::isValidIRPositionForInit
3668 return false;
3669 return IRAttribute::isValidIRPositionForInit(A, IRP);
3670 }
3671
3672 /// See AbstractAttribute::isImpliedByIR(...).
3673 LLVM_ABI static bool isImpliedByIR(Attributor &A, const IRPosition &IRP,
3674 Attribute::AttrKind ImpliedAttributeKind,
3675 bool IgnoreSubsumingPositions = false);
3676
3677 /// Return true if we assume that the underlying value is nonnull.
3678 bool isAssumedNonNull() const { return getAssumed(); }
3679
3680 /// Return true if we know that underlying value is nonnull.
3681 bool isKnownNonNull() const { return getKnown(); }
3682
3683 /// Create an abstract attribute view for the position \p IRP.
3685 Attributor &A);
3686
3687 /// See AbstractAttribute::getName()
3688 StringRef getName() const override { return "AANonNull"; }
3689
3690 /// See AbstractAttribute::getIdAddr()
3691 const char *getIdAddr() const override { return &ID; }
3692
3693 /// This function should return true if the type of the \p AA is AANonNull
3694 static bool classof(const AbstractAttribute *AA) {
3695 return (AA->getIdAddr() == &ID);
3696 }
3697
3698 /// Unique ID (due to the unique address)
3699 LLVM_ABI static const char ID;
3700};
3701
3702/// An abstract attribute for norecurse.
3704 : public IRAttribute<Attribute::NoRecurse,
3705 StateWrapper<BooleanState, AbstractAttribute>,
3706 AANoRecurse> {
3708
3709 /// Return true if "norecurse" is assumed.
3710 bool isAssumedNoRecurse() const { return getAssumed(); }
3711
3712 /// Return true if "norecurse" is known.
3713 bool isKnownNoRecurse() const { return getKnown(); }
3714
3715 /// Create an abstract attribute view for the position \p IRP.
3717 Attributor &A);
3718
3719 /// See AbstractAttribute::getName()
3720 StringRef getName() const override { return "AANoRecurse"; }
3721
3722 /// See AbstractAttribute::getIdAddr()
3723 const char *getIdAddr() const override { return &ID; }
3724
3725 /// This function should return true if the type of the \p AA is AANoRecurse
3726 static bool classof(const AbstractAttribute *AA) {
3727 return (AA->getIdAddr() == &ID);
3728 }
3729
3730 /// Unique ID (due to the unique address)
3731 LLVM_ABI static const char ID;
3732};
3733
3734/// An abstract attribute for willreturn.
3736 : public IRAttribute<Attribute::WillReturn,
3737 StateWrapper<BooleanState, AbstractAttribute>,
3738 AAWillReturn> {
3740
3741 static bool isImpliedByIR(Attributor &A, const IRPosition &IRP,
3742 Attribute::AttrKind ImpliedAttributeKind,
3743 bool IgnoreSubsumingPositions = false) {
3744 // Note: This is also run for non-IPO amendable functions.
3745 assert(ImpliedAttributeKind == Attribute::WillReturn);
3746 if (IRAttribute::isImpliedByIR(A, IRP, ImpliedAttributeKind,
3747 IgnoreSubsumingPositions))
3748 return true;
3750 return false;
3751 A.manifestAttrs(IRP, Attribute::get(IRP.getAnchorValue().getContext(),
3752 Attribute::WillReturn));
3753 return true;
3754 }
3755
3756 /// Check for `mustprogress` and `readonly` as they imply `willreturn`.
3758 const IRPosition &IRP) {
3759 // Check for `mustprogress` in the scope and the associated function which
3760 // might be different if this is a call site.
3761 if (!A.hasAttr(IRP, {Attribute::MustProgress}))
3762 return false;
3763
3765 A.getAttrs(IRP, {Attribute::Memory}, Attrs,
3766 /* IgnoreSubsumingPositions */ false);
3767
3769 for (const Attribute &Attr : Attrs)
3770 ME &= Attr.getMemoryEffects();
3771 return ME.onlyReadsMemory();
3772 }
3773
3774 /// Return true if "willreturn" is assumed.
3775 bool isAssumedWillReturn() const { return getAssumed(); }
3776
3777 /// Return true if "willreturn" is known.
3778 bool isKnownWillReturn() const { return getKnown(); }
3779
3780 /// Create an abstract attribute view for the position \p IRP.
3782 Attributor &A);
3783
3784 /// See AbstractAttribute::getName()
3785 StringRef getName() const override { return "AAWillReturn"; }
3786
3787 /// See AbstractAttribute::getIdAddr()
3788 const char *getIdAddr() const override { return &ID; }
3789
3790 /// This function should return true if the type of the \p AA is AAWillReturn
3791 static bool classof(const AbstractAttribute *AA) {
3792 return (AA->getIdAddr() == &ID);
3793 }
3794
3795 /// Unique ID (due to the unique address)
3796 LLVM_ABI static const char ID;
3797};
3798
3799/// An abstract attribute for undefined behavior.
3801 : public StateWrapper<BooleanState, AbstractAttribute> {
3804
3805 /// Return true if "undefined behavior" is assumed.
3806 bool isAssumedToCauseUB() const { return getAssumed(); }
3807
3808 /// Return true if "undefined behavior" is assumed for a specific instruction.
3809 virtual bool isAssumedToCauseUB(Instruction *I) const = 0;
3810
3811 /// Return true if "undefined behavior" is known.
3812 bool isKnownToCauseUB() const { return getKnown(); }
3813
3814 /// Return true if "undefined behavior" is known for a specific instruction.
3815 virtual bool isKnownToCauseUB(Instruction *I) const = 0;
3816
3817 /// Create an abstract attribute view for the position \p IRP.
3819 Attributor &A);
3820
3821 /// See AbstractAttribute::getName()
3822 StringRef getName() const override { return "AAUndefinedBehavior"; }
3823
3824 /// See AbstractAttribute::getIdAddr()
3825 const char *getIdAddr() const override { return &ID; }
3826
3827 /// This function should return true if the type of the \p AA is
3828 /// AAUndefineBehavior
3829 static bool classof(const AbstractAttribute *AA) {
3830 return (AA->getIdAddr() == &ID);
3831 }
3832
3833 /// Unique ID (due to the unique address)
3834 LLVM_ABI static const char ID;
3835};
3836
3837/// An abstract interface to determine reachability of point A to B.
3839 : public StateWrapper<BooleanState, AbstractAttribute> {
3842
3843 /// Returns true if 'From' instruction is assumed to reach, 'To' instruction.
3844 /// Users should provide two positions they are interested in, and the class
3845 /// determines (and caches) reachability.
3847 Attributor &A, const Instruction &From, const Instruction &To,
3848 const AA::InstExclusionSetTy *ExclusionSet = nullptr) const = 0;
3849
3850 /// Create an abstract attribute view for the position \p IRP.
3853
3854 /// See AbstractAttribute::getName()
3855 StringRef getName() const override { return "AAIntraFnReachability"; }
3856
3857 /// See AbstractAttribute::getIdAddr()
3858 const char *getIdAddr() const override { return &ID; }
3859
3860 /// This function should return true if the type of the \p AA is
3861 /// AAIntraFnReachability
3862 static bool classof(const AbstractAttribute *AA) {
3863 return (AA->getIdAddr() == &ID);
3864 }
3865
3866 /// Unique ID (due to the unique address)
3867 LLVM_ABI static const char ID;
3868};
3869
3870/// An abstract interface for all noalias attributes.
3872 : public IRAttribute<Attribute::NoAlias,
3873 StateWrapper<BooleanState, AbstractAttribute>,
3874 AANoAlias> {
3876
3877 /// See AbstractAttribute::isValidIRPositionForInit
3879 if (!IRP.getAssociatedType()->isPointerTy())
3880 return false;
3881 return IRAttribute::isValidIRPositionForInit(A, IRP);
3882 }
3883
3884 /// See IRAttribute::isImpliedByIR
3885 LLVM_ABI static bool isImpliedByIR(Attributor &A, const IRPosition &IRP,
3886 Attribute::AttrKind ImpliedAttributeKind,
3887 bool IgnoreSubsumingPositions = false);
3888
3889 /// See AbstractAttribute::requiresCallersForArgOrFunction
3890 static bool requiresCallersForArgOrFunction() { return true; }
3891
3892 /// Return true if we assume that the underlying value is alias.
3893 bool isAssumedNoAlias() const { return getAssumed(); }
3894
3895 /// Return true if we know that underlying value is noalias.
3896 bool isKnownNoAlias() const { return getKnown(); }
3897
3898 /// Create an abstract attribute view for the position \p IRP.
3900 Attributor &A);
3901
3902 /// See AbstractAttribute::getName()
3903 StringRef getName() const override { return "AANoAlias"; }
3904
3905 /// See AbstractAttribute::getIdAddr()
3906 const char *getIdAddr() const override { return &ID; }
3907
3908 /// This function should return true if the type of the \p AA is AANoAlias
3909 static bool classof(const AbstractAttribute *AA) {
3910 return (AA->getIdAddr() == &ID);
3911 }
3912
3913 /// Unique ID (due to the unique address)
3914 LLVM_ABI static const char ID;
3915};
3916
3917/// An AbstractAttribute for nofree.
3919 : public IRAttribute<Attribute::NoFree,
3920 StateWrapper<BooleanState, AbstractAttribute>,
3921 AANoFree> {
3923
3924 /// See IRAttribute::isImpliedByIR
3925 static bool isImpliedByIR(Attributor &A, const IRPosition &IRP,
3926 Attribute::AttrKind ImpliedAttributeKind,
3927 bool IgnoreSubsumingPositions = false) {
3928 // Note: This is also run for non-IPO amendable functions.
3929 assert(ImpliedAttributeKind == Attribute::NoFree);
3930 return A.hasAttr(
3931 IRP, {Attribute::ReadNone, Attribute::ReadOnly, Attribute::NoFree},
3932 IgnoreSubsumingPositions, Attribute::NoFree);
3933 }
3934
3935 /// See AbstractAttribute::isValidIRPositionForInit
3937 if (!IRP.isFunctionScope() &&
3939 return false;
3940 return IRAttribute::isValidIRPositionForInit(A, IRP);
3941 }
3942
3943 /// Return true if "nofree" is assumed.
3944 bool isAssumedNoFree() const { return getAssumed(); }
3945
3946 /// Return true if "nofree" is known.
3947 bool isKnownNoFree() const { return getKnown(); }
3948
3949 /// Create an abstract attribute view for the position \p IRP.
3951 Attributor &A);
3952
3953 /// See AbstractAttribute::getName()
3954 StringRef getName() const override { return "AANoFree"; }
3955
3956 /// See AbstractAttribute::getIdAddr()
3957 const char *getIdAddr() const override { return &ID; }
3958
3959 /// This function should return true if the type of the \p AA is AANoFree
3960 static bool classof(const AbstractAttribute *AA) {
3961 return (AA->getIdAddr() == &ID);
3962 }
3963
3964 /// Unique ID (due to the unique address)
3965 LLVM_ABI static const char ID;
3966};
3967
3968/// An AbstractAttribute for noreturn.
3970 : public IRAttribute<Attribute::NoReturn,
3971 StateWrapper<BooleanState, AbstractAttribute>,
3972 AANoReturn> {
3974
3975 /// Return true if the underlying object is assumed to never return.
3976 bool isAssumedNoReturn() const { return getAssumed(); }
3977
3978 /// Return true if the underlying object is known to never return.
3979 bool isKnownNoReturn() const { return getKnown(); }
3980
3981 /// Create an abstract attribute view for the position \p IRP.
3983 Attributor &A);
3984
3985 /// See AbstractAttribute::getName()
3986 StringRef getName() const override { return "AANoReturn"; }
3987
3988 /// See AbstractAttribute::getIdAddr()
3989 const char *getIdAddr() const override { return &ID; }
3990
3991 /// This function should return true if the type of the \p AA is AANoReturn
3992 static bool classof(const AbstractAttribute *AA) {
3993 return (AA->getIdAddr() == &ID);
3994 }
3995
3996 /// Unique ID (due to the unique address)
3997 LLVM_ABI static const char ID;
3998};
3999
4000/// An abstract interface for liveness abstract attribute.
4002 : public StateWrapper<BitIntegerState<uint8_t, 3, 0>, AbstractAttribute> {
4004 AAIsDead(const IRPosition &IRP, Attributor &A) : Base(IRP) {}
4005
4006 /// See AbstractAttribute::isValidIRPositionForInit
4009 return isa<Function>(IRP.getAnchorValue()) &&
4010 !cast<Function>(IRP.getAnchorValue()).isDeclaration();
4011 return true;
4012 }
4013
4014 /// State encoding bits. A set bit in the state means the property holds.
4015 enum {
4018
4020 };
4021 static_assert(IS_DEAD == getBestState(), "Unexpected BEST_STATE value");
4022
4023protected:
4024 /// The query functions are protected such that other attributes need to go
4025 /// through the Attributor interfaces: `Attributor::isAssumedDead(...)`
4026
4027 /// Returns true if the underlying value is assumed dead.
4028 virtual bool isAssumedDead() const = 0;
4029
4030 /// Returns true if the underlying value is known dead.
4031 virtual bool isKnownDead() const = 0;
4032
4033 /// Returns true if \p BB is known dead.
4034 virtual bool isKnownDead(const BasicBlock *BB) const = 0;
4035
4036 /// Returns true if \p I is assumed dead.
4037 virtual bool isAssumedDead(const Instruction *I) const = 0;
4038
4039 /// Returns true if \p I is known dead.
4040 virtual bool isKnownDead(const Instruction *I) const = 0;
4041
4042 /// Return true if the underlying value is a store that is known to be
4043 /// removable. This is different from dead stores as the removable store
4044 /// can have an effect on live values, especially loads, but that effect
4045 /// is propagated which allows us to remove the store in turn.
4046 virtual bool isRemovableStore() const { return false; }
4047
4048 /// This method is used to check if at least one instruction in a collection
4049 /// of instructions is live.
4050 template <typename T> bool isLiveInstSet(T begin, T end) const {
4051 for (const auto &I : llvm::make_range(begin, end)) {
4052 assert(I->getFunction() == getIRPosition().getAssociatedFunction() &&
4053 "Instruction must be in the same anchor scope function.");
4054
4055 if (!isAssumedDead(I))
4056 return true;
4057 }
4058
4059 return false;
4060 }
4061
4062public:
4063 /// Create an abstract attribute view for the position \p IRP.
4065 Attributor &A);
4066
4067 /// Determine if \p F might catch asynchronous exceptions.
4069 return F.hasPersonalityFn() && !canSimplifyInvokeNoUnwind(&F);
4070 }
4071
4072 /// Returns true if \p BB is assumed dead.
4073 virtual bool isAssumedDead(const BasicBlock *BB) const = 0;
4074
4075 /// Return if the edge from \p From BB to \p To BB is assumed dead.
4076 /// This is specifically useful in AAReachability.
4077 virtual bool isEdgeDead(const BasicBlock *From, const BasicBlock *To) const {
4078 return false;
4079 }
4080
4081 /// See AbstractAttribute::getName()
4082 StringRef getName() const override { return "AAIsDead"; }
4083
4084 /// See AbstractAttribute::getIdAddr()
4085 const char *getIdAddr() const override { return &ID; }
4086
4087 /// This function should return true if the type of the \p AA is AAIsDead
4088 static bool classof(const AbstractAttribute *AA) {
4089 return (AA->getIdAddr() == &ID);
4090 }
4091
4092 /// Unique ID (due to the unique address)
4093 LLVM_ABI static const char ID;
4094
4095 friend struct Attributor;
4096};
4097
4098/// State for dereferenceable attribute
4100
4101 static DerefState getBestState() { return DerefState(); }
4102 static DerefState getBestState(const DerefState &) { return getBestState(); }
4103
4104 /// Return the worst possible representable state.
4106 DerefState DS;
4108 return DS;
4109 }
4111 return getWorstState();
4112 }
4113
4114 /// State representing for dereferenceable bytes.
4116
4117 /// Map representing for accessed memory offsets and sizes.
4118 /// A key is Offset and a value is size.
4119 /// If there is a load/store instruction something like,
4120 /// p[offset] = v;
4121 /// (offset, sizeof(v)) will be inserted to this map.
4122 /// std::map is used because we want to iterate keys in ascending order.
4123 std::map<int64_t, uint64_t> AccessedBytesMap;
4124
4125 /// Helper function to calculate dereferenceable bytes from current known
4126 /// bytes and accessed bytes.
4127 ///
4128 /// int f(int *A){
4129 /// *A = 0;
4130 /// *(A+2) = 2;
4131 /// *(A+1) = 1;
4132 /// *(A+10) = 10;
4133 /// }
4134 /// ```
4135 /// In that case, AccessedBytesMap is `{0:4, 4:4, 8:4, 40:4}`.
4136 /// AccessedBytesMap is std::map so it is iterated in accending order on
4137 /// key(Offset). So KnownBytes will be updated like this:
4138 ///
4139 /// |Access | KnownBytes
4140 /// |(0, 4)| 0 -> 4
4141 /// |(4, 4)| 4 -> 8
4142 /// |(8, 4)| 8 -> 12
4143 /// |(40, 4) | 12 (break)
4144 void computeKnownDerefBytesFromAccessedMap() {
4145 int64_t KnownBytes = DerefBytesState.getKnown();
4146 for (auto &Access : AccessedBytesMap) {
4147 if (KnownBytes < Access.first)
4148 break;
4149 KnownBytes = std::max(KnownBytes, Access.first + (int64_t)Access.second);
4150 }
4151
4152 DerefBytesState.takeKnownMaximum(KnownBytes);
4153 }
4154
4155 /// State representing that whether the value is globaly dereferenceable.
4156 BooleanState GlobalState;
4157
4158 /// See AbstractState::isValidState()
4159 bool isValidState() const override { return DerefBytesState.isValidState(); }
4160
4161 /// See AbstractState::isAtFixpoint()
4162 bool isAtFixpoint() const override {
4163 return !isValidState() ||
4164 (DerefBytesState.isAtFixpoint() && GlobalState.isAtFixpoint());
4165 }
4166
4167 /// See AbstractState::indicateOptimisticFixpoint(...)
4169 DerefBytesState.indicateOptimisticFixpoint();
4170 GlobalState.indicateOptimisticFixpoint();
4172 }
4173
4174 /// See AbstractState::indicatePessimisticFixpoint(...)
4176 DerefBytesState.indicatePessimisticFixpoint();
4177 GlobalState.indicatePessimisticFixpoint();
4178 return ChangeStatus::CHANGED;
4179 }
4180
4181 /// Update known dereferenceable bytes.
4182 void takeKnownDerefBytesMaximum(uint64_t Bytes) {
4183 DerefBytesState.takeKnownMaximum(Bytes);
4184
4185 // Known bytes might increase.
4186 computeKnownDerefBytesFromAccessedMap();
4187 }
4188
4189 /// Update assumed dereferenceable bytes.
4190 void takeAssumedDerefBytesMinimum(uint64_t Bytes) {
4191 DerefBytesState.takeAssumedMinimum(Bytes);
4192 }
4193
4194 /// Add accessed bytes to the map.
4195 void addAccessedBytes(int64_t Offset, uint64_t Size) {
4196 uint64_t &AccessedBytes = AccessedBytesMap[Offset];
4197 AccessedBytes = std::max(AccessedBytes, Size);
4198
4199 // Known bytes might increase.
4200 computeKnownDerefBytesFromAccessedMap();
4201 }
4202
4203 /// Equality for DerefState.
4204 bool operator==(const DerefState &R) const {
4205 return this->DerefBytesState == R.DerefBytesState &&
4206 this->GlobalState == R.GlobalState;
4207 }
4208
4209 /// Inequality for DerefState.
4210 bool operator!=(const DerefState &R) const { return !(*this == R); }
4211
4212 /// See IntegerStateBase::operator^=
4213 DerefState operator^=(const DerefState &R) {
4214 DerefBytesState ^= R.DerefBytesState;
4215 GlobalState ^= R.GlobalState;
4216 return *this;
4217 }
4218
4219 /// See IntegerStateBase::operator+=
4220 DerefState operator+=(const DerefState &R) {
4221 DerefBytesState += R.DerefBytesState;
4222 GlobalState += R.GlobalState;
4223 return *this;
4224 }
4225
4226 /// See IntegerStateBase::operator&=
4227 DerefState operator&=(const DerefState &R) {
4228 DerefBytesState &= R.DerefBytesState;
4229 GlobalState &= R.GlobalState;
4230 return *this;
4231 }
4232
4233 /// See IntegerStateBase::operator|=
4234 DerefState operator|=(const DerefState &R) {
4235 DerefBytesState |= R.DerefBytesState;
4236 GlobalState |= R.GlobalState;
4237 return *this;
4238 }
4239};
4240
4241/// An abstract interface for all dereferenceable attribute.
4243 : public IRAttribute<Attribute::Dereferenceable,
4244 StateWrapper<DerefState, AbstractAttribute>,
4245 AADereferenceable> {
4247
4248 /// See AbstractAttribute::isValidIRPositionForInit
4250 if (!IRP.getAssociatedType()->isPointerTy())
4251 return false;
4252 return IRAttribute::isValidIRPositionForInit(A, IRP);
4253 }
4254
4255 /// Return true if we assume that underlying value is
4256 /// dereferenceable(_or_null) globally.
4257 bool isAssumedGlobal() const { return GlobalState.getAssumed(); }
4258
4259 /// Return true if we know that underlying value is
4260 /// dereferenceable(_or_null) globally.
4261 bool isKnownGlobal() const { return GlobalState.getKnown(); }
4262
4263 /// Return assumed dereferenceable bytes.
4265 return DerefBytesState.getAssumed();
4266 }
4267
4268 /// Return known dereferenceable bytes.
4270 return DerefBytesState.getKnown();
4271 }
4272
4273 /// Create an abstract attribute view for the position \p IRP.
4275 Attributor &A);
4276
4277 /// See AbstractAttribute::getName()
4278 StringRef getName() const override { return "AADereferenceable"; }
4279
4280 /// See AbstractAttribute::getIdAddr()
4281 const char *getIdAddr() const override { return &ID; }
4282
4283 /// This function should return true if the type of the \p AA is
4284 /// AADereferenceable
4285 static bool classof(const AbstractAttribute *AA) {
4286 return (AA->getIdAddr() == &ID);
4287 }
4288
4289 /// Unique ID (due to the unique address)
4290 LLVM_ABI static const char ID;
4291};
4292
4295/// An abstract interface for all align attributes.
4297 : public IRAttribute<Attribute::Alignment,
4298 StateWrapper<AAAlignmentStateType, AbstractAttribute>,
4299 AAAlign> {
4301
4302 /// See AbstractAttribute::isValidIRPositionForInit
4305 return false;
4306 return IRAttribute::isValidIRPositionForInit(A, IRP);
4307 }
4308
4309 /// Return assumed alignment.
4310 Align getAssumedAlign() const { return Align(getAssumed()); }
4311
4312 /// Return known alignment.
4313 Align getKnownAlign() const { return Align(getKnown()); }
4314
4315 /// See AbstractAttribute::getName()
4316 StringRef getName() const override { return "AAAlign"; }
4317
4318 /// See AbstractAttribute::getIdAddr()
4319 const char *getIdAddr() const override { return &ID; }
4320
4321 /// This function should return true if the type of the \p AA is AAAlign
4322 static bool classof(const AbstractAttribute *AA) {
4323 return (AA->getIdAddr() == &ID);
4324 }
4325
4326 /// Create an abstract attribute view for the position \p IRP.
4328 Attributor &A);
4329
4330 /// Unique ID (due to the unique address)
4331 LLVM_ABI static const char ID;
4332};
4333
4334/// An abstract interface to track if a value leaves it's defining function
4335/// instance.
4336/// TODO: We should make it a ternary AA tracking uniqueness, and uniqueness
4337/// wrt. the Attributor analysis separately.
4338struct AAInstanceInfo : public StateWrapper<BooleanState, AbstractAttribute> {
4341
4342 /// Return true if we know that the underlying value is unique in its scope
4343 /// wrt. the Attributor analysis. That means it might not be unique but we can
4344 /// still use pointer equality without risking to represent two instances with
4345 /// one `llvm::Value`.
4346 bool isKnownUniqueForAnalysis() const { return isKnown(); }
4347
4348 /// Return true if we assume 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 isAssumedUniqueForAnalysis() const { return isAssumed(); }
4353
4354 /// Create an abstract attribute view for the position \p IRP.
4356 Attributor &A);
4357
4358 /// See AbstractAttribute::getName()
4359 StringRef getName() const override { return "AAInstanceInfo"; }
4360
4361 /// See AbstractAttribute::getIdAddr()
4362 const char *getIdAddr() const override { return &ID; }
4363
4364 /// This function should return true if the type of the \p AA is
4365 /// AAInstanceInfo
4366 static bool classof(const AbstractAttribute *AA) {
4367 return (AA->getIdAddr() == &ID);
4368 }
4369
4370 /// Unique ID (due to the unique address)
4371 LLVM_ABI static const char ID;
4372};
4373
4374/// An abstract interface for all nocapture attributes.
4376 : public IRAttribute<
4377 Attribute::Captures,
4378 StateWrapper<BitIntegerState<uint16_t, 7, 0>, AbstractAttribute>,
4379 AANoCapture> {
4381
4382 /// See IRAttribute::isImpliedByIR
4383 LLVM_ABI static bool isImpliedByIR(Attributor &A, const IRPosition &IRP,
4384 Attribute::AttrKind ImpliedAttributeKind,
4385 bool IgnoreSubsumingPositions = false);
4386
4387 /// Update \p State according to the capture capabilities of \p F for position
4388 /// \p IRP.
4389 LLVM_ABI static void
4391 BitIntegerState &State);
4392
4393 /// See AbstractAttribute::isValidIRPositionForInit
4395 if (!IRP.getAssociatedType()->isPointerTy())
4396 return false;
4397 return IRAttribute::isValidIRPositionForInit(A, IRP);
4398 }
4399
4400 /// State encoding bits. A set bit in the state means the property holds.
4401 /// NO_CAPTURE is the best possible state, 0 the worst possible state.
4402 enum {
4406
4407 /// If we do not capture the value in memory or through integers we can only
4408 /// communicate it back as a derived pointer.
4410
4411 /// If we do not capture the value in memory, through integers, or as a
4412 /// derived pointer we know it is not captured.
4415 };
4416
4417 /// Return true if we know that the underlying value is not captured in its
4418 /// respective scope.
4419 bool isKnownNoCapture() const { return isKnown(NO_CAPTURE); }
4420
4421 /// Return true if we assume that the underlying value is not captured in its
4422 /// respective scope.
4423 bool isAssumedNoCapture() const { return isAssumed(NO_CAPTURE); }
4424
4425 /// Return true if we know that the underlying value is not captured in its
4426 /// respective scope but we allow it to escape through a "return".
4430
4431 /// Return true if we assume that the underlying value is not captured in its
4432 /// respective scope but we allow it to escape through a "return".
4436
4437 /// Create an abstract attribute view for the position \p IRP.
4439 Attributor &A);
4440
4441 /// See AbstractAttribute::getName()
4442 StringRef getName() const override { return "AANoCapture"; }
4443
4444 /// See AbstractAttribute::getIdAddr()
4445 const char *getIdAddr() const override { return &ID; }
4446
4447 /// This function should return true if the type of the \p AA is AANoCapture
4448 static bool classof(const AbstractAttribute *AA) {
4449 return (AA->getIdAddr() == &ID);
4450 }
4451
4452 /// Unique ID (due to the unique address)
4453 LLVM_ABI static const char ID;
4454};
4455
4457
4459
4464 return getBestState(VS.Ty);
4465 }
4466
4467 /// Return the worst possible representable state.
4470 DS.indicatePessimisticFixpoint();
4471 return DS;
4472 }
4475 return getWorstState(VS.Ty);
4476 }
4477
4478 /// See AbstractState::isValidState(...)
4479 bool isValidState() const override { return BS.isValidState(); }
4480
4481 /// See AbstractState::isAtFixpoint(...)
4482 bool isAtFixpoint() const override { return BS.isAtFixpoint(); }
4483
4484 /// Return the assumed state encoding.
4486 const ValueSimplifyStateType &getAssumed() const { return *this; }
4487
4488 /// See AbstractState::indicatePessimisticFixpoint(...)
4490 return BS.indicatePessimisticFixpoint();
4491 }
4492
4493 /// See AbstractState::indicateOptimisticFixpoint(...)
4495 return BS.indicateOptimisticFixpoint();
4496 }
4497
4498 /// "Clamp" this state with \p PVS.
4500 BS ^= VS.BS;
4501 unionAssumed(VS.SimplifiedAssociatedValue);
4502 return *this;
4503 }
4504
4506 if (isValidState() != RHS.isValidState())
4507 return false;
4508 if (!isValidState() && !RHS.isValidState())
4509 return true;
4510 return SimplifiedAssociatedValue == RHS.SimplifiedAssociatedValue;
4511 }
4512
4513protected:
4514 /// The type of the original value.
4516
4517 /// Merge \p Other into the currently assumed simplified value
4518 LLVM_ABI bool unionAssumed(std::optional<Value *> Other);
4519
4520 /// Helper to track validity and fixpoint
4522
4523 /// An assumed simplified value. Initially, it is set to std::nullopt, which
4524 /// means that the value is not clear under current assumption. If in the
4525 /// pessimistic state, getAssumedSimplifiedValue doesn't return this value but
4526 /// returns orignal associated value.
4527 std::optional<Value *> SimplifiedAssociatedValue;
4528};
4529
4530/// An abstract interface for value simplify abstract attribute.
4532 : public StateWrapper<ValueSimplifyStateType, AbstractAttribute, Type *> {
4535 : Base(IRP, IRP.getAssociatedType()) {}
4536
4537 /// Create an abstract attribute view for the position \p IRP.
4539 Attributor &A);
4540
4541 /// See AbstractAttribute::getName()
4542 StringRef getName() const override { return "AAValueSimplify"; }
4543
4544 /// See AbstractAttribute::getIdAddr()
4545 const char *getIdAddr() const override { return &ID; }
4546
4547 /// This function should return true if the type of the \p AA is
4548 /// AAValueSimplify
4549 static bool classof(const AbstractAttribute *AA) {
4550 return (AA->getIdAddr() == &ID);
4551 }
4552
4553 /// Unique ID (due to the unique address)
4554 LLVM_ABI static const char ID;
4555
4556private:
4557 /// Return an assumed simplified value if a single candidate is found. If
4558 /// there cannot be one, return original value. If it is not clear yet, return
4559 /// std::nullopt.
4560 ///
4561 /// Use `Attributor::getAssumedSimplified` for value simplification.
4562 virtual std::optional<Value *>
4563 getAssumedSimplifiedValue(Attributor &A) const = 0;
4564
4565 friend struct Attributor;
4566};
4567
4568struct AAHeapToStack : public StateWrapper<BooleanState, AbstractAttribute> {
4570 AAHeapToStack(const IRPosition &IRP, Attributor &A) : Base(IRP) {}
4571
4572 /// Returns true if HeapToStack conversion is assumed to be possible.
4573 virtual bool isAssumedHeapToStack(const CallBase &CB) const = 0;
4574
4575 /// Returns true if HeapToStack conversion is assumed and the CB is a
4576 /// callsite to a free operation to be removed.
4577 virtual bool isAssumedHeapToStackRemovedFree(CallBase &CB) const = 0;
4578
4579 /// Create an abstract attribute view for the position \p IRP.
4581 Attributor &A);
4582
4583 /// See AbstractAttribute::getName()
4584 StringRef getName() const override { return "AAHeapToStack"; }
4585
4586 /// See AbstractAttribute::getIdAddr()
4587 const char *getIdAddr() const override { return &ID; }
4588
4589 /// This function should return true if the type of the \p AA is AAHeapToStack
4590 static bool classof(const AbstractAttribute *AA) {
4591 return (AA->getIdAddr() == &ID);
4592 }
4593
4594 /// Unique ID (due to the unique address)
4595 LLVM_ABI static const char ID;
4596};
4597
4598/// An abstract interface for privatizability.
4599///
4600/// A pointer is privatizable if it can be replaced by a new, private one.
4601/// Privatizing pointer reduces the use count, interaction between unrelated
4602/// code parts.
4603///
4604/// In order for a pointer to be privatizable its value cannot be observed
4605/// (=nocapture), it is (for now) not written (=readonly & noalias), we know
4606/// what values are necessary to make the private copy look like the original
4607/// one, and the values we need can be loaded (=dereferenceable).
4609 : public StateWrapper<BooleanState, AbstractAttribute> {
4612
4613 /// See AbstractAttribute::isValidIRPositionForInit
4616 return false;
4618 }
4619
4620 /// Returns true if pointer privatization is assumed to be possible.
4621 bool isAssumedPrivatizablePtr() const { return getAssumed(); }
4622
4623 /// Returns true if pointer privatization is known to be possible.
4624 bool isKnownPrivatizablePtr() const { return getKnown(); }
4625
4626 /// See AbstractAttribute::requiresCallersForArgOrFunction
4627 static bool requiresCallersForArgOrFunction() { return true; }
4628
4629 /// Return the type we can choose for a private copy of the underlying
4630 /// value. std::nullopt means it is not clear yet, nullptr means there is
4631 /// none.
4632 virtual std::optional<Type *> getPrivatizableType() const = 0;
4633
4634 /// Create an abstract attribute view for the position \p IRP.
4636 Attributor &A);
4637
4638 /// See AbstractAttribute::getName()
4639 StringRef getName() const override { return "AAPrivatizablePtr"; }
4640
4641 /// See AbstractAttribute::getIdAddr()
4642 const char *getIdAddr() const override { return &ID; }
4643
4644 /// This function should return true if the type of the \p AA is
4645 /// AAPricatizablePtr
4646 static bool classof(const AbstractAttribute *AA) {
4647 return (AA->getIdAddr() == &ID);
4648 }
4649
4650 /// Unique ID (due to the unique address)
4651 LLVM_ABI static const char ID;
4652};
4653
4654/// An abstract interface for memory access kind related attributes
4655/// (readnone/readonly/writeonly).
4657 : public IRAttribute<
4658 Attribute::None,
4659 StateWrapper<BitIntegerState<uint8_t, 3>, AbstractAttribute>,
4660 AAMemoryBehavior> {
4662
4663 /// See AbstractAttribute::hasTrivialInitializer.
4664 static bool hasTrivialInitializer() { return false; }
4665
4666 /// See AbstractAttribute::isValidIRPositionForInit
4668 if (!IRP.isFunctionScope() && !IRP.getAssociatedType()->isPointerTy())
4669 return false;
4670 return IRAttribute::isValidIRPositionForInit(A, IRP);
4671 }
4672
4673 /// State encoding bits. A set bit in the state means the property holds.
4674 /// BEST_STATE is the best possible state, 0 the worst possible state.
4675 enum {
4676 NO_READS = 1 << 0,
4677 NO_WRITES = 1 << 1,
4679
4681 };
4682 static_assert(BEST_STATE == getBestState(), "Unexpected BEST_STATE value");
4683
4684 /// Return true if we know that the underlying value is not read or accessed
4685 /// in its respective scope.
4686 bool isKnownReadNone() const { return isKnown(NO_ACCESSES); }
4687
4688 /// Return true if we assume that the underlying value is not read or accessed
4689 /// in its respective scope.
4690 bool isAssumedReadNone() const { return isAssumed(NO_ACCESSES); }
4691
4692 /// Return true if we know that the underlying value is not accessed
4693 /// (=written) in its respective scope.
4694 bool isKnownReadOnly() const { return isKnown(NO_WRITES); }
4695
4696 /// Return true if we assume that the underlying value is not accessed
4697 /// (=written) in its respective scope.
4698 bool isAssumedReadOnly() const { return isAssumed(NO_WRITES); }
4699
4700 /// Return true if we know that the underlying value is not read in its
4701 /// respective scope.
4702 bool isKnownWriteOnly() const { return isKnown(NO_READS); }
4703
4704 /// Return true if we assume that the underlying value is not read in its
4705 /// respective scope.
4706 bool isAssumedWriteOnly() const { return isAssumed(NO_READS); }
4707
4708 /// Create an abstract attribute view for the position \p IRP.
4710 Attributor &A);
4711
4712 /// See AbstractAttribute::getName()
4713 StringRef getName() const override { return "AAMemoryBehavior"; }
4714
4715 /// See AbstractAttribute::getIdAddr()
4716 const char *getIdAddr() const override { return &ID; }
4717
4718 /// This function should return true if the type of the \p AA is
4719 /// AAMemoryBehavior
4720 static bool classof(const AbstractAttribute *AA) {
4721 return (AA->getIdAddr() == &ID);
4722 }
4723
4724 /// Unique ID (due to the unique address)
4725 LLVM_ABI static const char ID;
4726};
4727
4728/// An abstract interface for all memory location attributes
4729/// (readnone/argmemonly/inaccessiblememonly/inaccessibleorargmemonly).
4731 : public IRAttribute<
4732 Attribute::None,
4733 StateWrapper<BitIntegerState<uint32_t, 511>, AbstractAttribute>,
4734 AAMemoryLocation> {
4735 using MemoryLocationsKind = StateType::base_t;
4736
4738
4739 /// See AbstractAttribute::requiresCalleeForCallBase.
4740 static bool requiresCalleeForCallBase() { return true; }
4741
4742 /// See AbstractAttribute::hasTrivialInitializer.
4743 static bool hasTrivialInitializer() { return false; }
4744
4745 /// See AbstractAttribute::isValidIRPositionForInit
4747 if (!IRP.isFunctionScope() &&
4749 return false;
4750 return IRAttribute::isValidIRPositionForInit(A, IRP);
4751 }
4752
4753 /// Encoding of different locations that could be accessed by a memory
4754 /// access.
4755 enum {
4769
4770 // Helper bit to track if we gave up or not.
4772
4774 };
4775 static_assert(BEST_STATE == getBestState(), "Unexpected BEST_STATE value");
4776
4777 /// Return true if we know that the associated functions has no observable
4778 /// accesses.
4779 bool isKnownReadNone() const { return isKnown(NO_LOCATIONS); }
4780
4781 /// Return true if we assume that the associated functions has no observable
4782 /// accesses.
4783 bool isAssumedReadNone() const {
4785 }
4786
4787 /// Return true if we know that the associated functions has at most
4788 /// local/stack accesses.
4789 bool isKnowStackOnly() const {
4790 return isKnown(inverseLocation(NO_LOCAL_MEM, true, true));
4791 }
4792
4793 /// Return true if we assume that the associated functions has at most
4794 /// local/stack accesses.
4795 bool isAssumedStackOnly() const {
4796 return isAssumed(inverseLocation(NO_LOCAL_MEM, true, true));
4797 }
4798
4799 /// Return true if we know that the underlying value will only access
4800 /// inaccesible memory only (see Attribute::InaccessibleMemOnly).
4802 return isKnown(inverseLocation(NO_INACCESSIBLE_MEM, true, true));
4803 }
4804
4805 /// Return true if we assume that the underlying value will only access
4806 /// inaccesible memory only (see Attribute::InaccessibleMemOnly).
4808 return isAssumed(inverseLocation(NO_INACCESSIBLE_MEM, true, true));
4809 }
4810
4811 /// Return true if we know that the underlying value will only access
4812 /// argument pointees (see Attribute::ArgMemOnly).
4813 bool isKnownArgMemOnly() const {
4814 return isKnown(inverseLocation(NO_ARGUMENT_MEM, true, true));
4815 }
4816
4817 /// Return true if we assume that the underlying value will only access
4818 /// argument pointees (see Attribute::ArgMemOnly).
4819 bool isAssumedArgMemOnly() const {
4820 return isAssumed(inverseLocation(NO_ARGUMENT_MEM, true, true));
4821 }
4822
4823 /// Return true if we know that the underlying value will only access
4824 /// inaccesible memory or argument pointees (see
4825 /// Attribute::InaccessibleOrArgMemOnly).
4827 return isKnown(
4829 }
4830
4831 /// Return true if we assume that the underlying value will only access
4832 /// inaccesible memory or argument pointees (see
4833 /// Attribute::InaccessibleOrArgMemOnly).
4838
4839 /// Return true if the underlying value may access memory through arguement
4840 /// pointers of the associated function, if any.
4841 bool mayAccessArgMem() const { return !isAssumed(NO_ARGUMENT_MEM); }
4842
4843 /// Return true if only the memory locations specififed by \p MLK are assumed
4844 /// to be accessed by the associated function.
4846 return isAssumed(MLK);
4847 }
4848
4849 /// Return the locations that are assumed to be not accessed by the associated
4850 /// function, if any.
4854
4855 /// Return the inverse of location \p Loc, thus for NO_XXX the return
4856 /// describes ONLY_XXX. The flags \p AndLocalMem and \p AndConstMem determine
4857 /// if local (=stack) and constant memory are allowed as well. Most of the
4858 /// time we do want them to be included, e.g., argmemonly allows accesses via
4859 /// argument pointers or local or constant memory accesses.
4860 static MemoryLocationsKind
4861 inverseLocation(MemoryLocationsKind Loc, bool AndLocalMem, bool AndConstMem) {
4862 return NO_LOCATIONS & ~(Loc | (AndLocalMem ? NO_LOCAL_MEM : 0) |
4863 (AndConstMem ? NO_CONST_MEM : 0));
4864 };
4865
4866 /// Return the locations encoded by \p MLK as a readable string.
4868
4869 /// Simple enum to distinguish read/write/read-write accesses.
4871 NONE = 0,
4872 READ = 1 << 0,
4873 WRITE = 1 << 1,
4875 };
4876
4877 /// Check \p Pred on all accesses to the memory kinds specified by \p MLK.
4878 ///
4879 /// This method will evaluate \p Pred on all accesses (access instruction +
4880 /// underlying accessed memory pointer) and it will return true if \p Pred
4881 /// holds every time.
4883 function_ref<bool(const Instruction *, const Value *, AccessKind,
4885 Pred,
4886 MemoryLocationsKind MLK) const = 0;
4887
4888 /// Create an abstract attribute view for the position \p IRP.
4890 Attributor &A);
4891
4892 /// See AbstractState::getAsStr(Attributor).
4893 const std::string getAsStr(Attributor *A) const override {
4895 }
4896
4897 /// See AbstractAttribute::getName()
4898 StringRef getName() const override { return "AAMemoryLocation"; }
4899
4900 /// See AbstractAttribute::getIdAddr()
4901 const char *getIdAddr() const override { return &ID; }
4902
4903 /// This function should return true if the type of the \p AA is
4904 /// AAMemoryLocation
4905 static bool classof(const AbstractAttribute *AA) {
4906 return (AA->getIdAddr() == &ID);
4907 }
4908
4909 /// Unique ID (due to the unique address)
4910 LLVM_ABI static const char ID;
4911};
4912
4913/// An abstract interface for range value analysis.
4915 : public StateWrapper<IntegerRangeState, AbstractAttribute, uint32_t> {
4918 : Base(IRP, IRP.getAssociatedType()->getIntegerBitWidth()) {}
4919
4920 /// See AbstractAttribute::isValidIRPositionForInit
4922 if (!IRP.getAssociatedType()->isIntegerTy())
4923 return false;
4925 }
4926
4927 /// See AbstractAttribute::requiresCallersForArgOrFunction
4928 static bool requiresCallersForArgOrFunction() { return true; }
4929
4930 /// See AbstractAttribute::getState(...).
4931 IntegerRangeState &getState() override { return *this; }
4932 const IntegerRangeState &getState() const override { return *this; }
4933
4934 /// Create an abstract attribute view for the position \p IRP.
4936 Attributor &A);
4937
4938 /// Return an assumed range for the associated value a program point \p CtxI.
4939 /// If \p I is nullptr, simply return an assumed range.
4940 virtual ConstantRange
4942 const Instruction *CtxI = nullptr) const = 0;
4943
4944 /// Return a known range for the associated value at a program point \p CtxI.
4945 /// If \p I is nullptr, simply return a known 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
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< 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:213
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
Machine Check Debug Module
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
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:407
Functions, function parameters, and return types can have attributes to indicate how they should be t...
Definition Attributes.h:105
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:124
@ None
No attributes have been set.
Definition Attributes.h:126
static bool isEnumAttrKind(AttrKind Kind)
Definition Attributes.h:137
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:289
Analysis pass which computes a DominatorTree.
Definition Dominators.h:270
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:354
void setAttributes(AttributeList Attrs)
Set the attribute list for this Function.
Definition Function.h:357
size_t arg_size() const
Definition Function.h:901
Type * getReturnType() const
Returns the type of the ret val.
Definition Function.h:216
Argument * getArg(unsigned i) const
Definition Function.h:886
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition Function.cpp:724
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:587
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:67
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:106
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:339
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:282
bool isPtrOrPtrVectorTy() const
Return true if this is a pointer type or a vector of pointer types.
Definition Type.h:285
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:257
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:255
LLVMContext & getContext() const
All values hold a context through their type.
Definition Value.h:258
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)
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
NodeAddr< UseNode * > Use
Definition RDFGraph.h:385
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:558
FunctionAddr VTableAddr Value
Definition InstrProf.h:137
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:1668
LLVM_ABI unsigned MaxInitializationChainLength
The value passed to the line option that defines the maximal initialization chain length.
APInt operator&(APInt a, const APInt &b)
Definition APInt.h:2152
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:2142
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
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:1916
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:2172
BumpPtrAllocatorImpl<> BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
Definition Allocator.h:383
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:860
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
virtual ConstantRange getKnownConstantRange(Attributor &A, const Instruction *CtxI=nullptr) const =0
Return a known range for the associated value at a program point CtxI.
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
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