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