28#ifndef LLVM_ADT_GENERICCYCLEINFO_H
29#define LLVM_ADT_GENERICCYCLEINFO_H
55 static constexpr unsigned InvalidIndex = ~0u;
56 unsigned Index = InvalidIndex;
58 explicit CycleRef(
unsigned Index) : Index(Index) {}
65 bool isValid()
const {
return Index != InvalidIndex; }
67 bool operator==(CycleRef O)
const {
return Index == O.Index; }
68 bool operator!=(CycleRef O)
const {
return Index != O.Index; }
81 using BlockT =
typename ContextT::BlockT;
97 unsigned IdxBegin = 0, IdxEnd = 0;
106 unsigned NumDescendants = 0;
111 unsigned EntryBegin = 0, EntrySize = 0;
114 bool hasParent()
const {
return Parent.
isValid(); }
116 static_assert(std::is_trivially_destructible_v<Cycle>);
117 using CycleT = Cycle;
120 unsigned BlockNumberEpoch;
129 SmallVector<BlockT *, 8> BlockLayout;
134 std::unique_ptr<CycleT[]> Cycles;
135 unsigned NumCycles = 0;
142 unsigned getCycleIndex(
const CycleT &
C)
const {
return &
C - Cycles.get(); }
146 CycleT &deref(CycleRef
C) {
148 return Cycles[
C.Index];
150 const CycleT &deref(CycleRef
C)
const {
152 return Cycles[
C.Index];
155 CycleRef ref(
const CycleT &
C)
const {
return CycleRef(getCycleIndex(
C)); }
157 void verifyBlockNumberEpoch(
const FunctionT *Fn)
const {
158 assert(BlockNumberEpoch ==
159 GraphTraits<const FunctionT *>::getNumberEpoch(Fn) &&
160 "CycleInfo used with outdated block number epoch");
170 CycleRef, std::ptrdiff_t, CycleRef, CycleRef> {
210 verifyBlockNumberEpoch(
Block->getParent());
214 if (
Number >= BlockMap.size())
220 return BlockLayout[deref(
C).EntryBegin];
226 const CycleT &Cyc = deref(
C);
227 return Cyc.IdxEnd - Cyc.IdxBegin;
231 const CycleT &Cyc = deref(
C);
232 return ArrayRef(BlockLayout).slice(Cyc.EntryBegin, Cyc.EntrySize);
240 CycleT &Cyc = deref(
C);
241 Cyc.EntryBegin = BlockLayout.size();
242 BlockLayout.push_back(
Block);
247 const CycleT &O = deref(Outer);
248 const CycleT &
I = deref(Inner);
249 return O.IdxBegin <=
I.IdxBegin &&
I.IdxEnd <= O.IdxEnd;
252 unsigned First =
C.Index + 1;
261 Out << LS << Ctx.print(Entry);
273 const CycleT &Cyc = deref(
C);
275 BlockLayout.begin() + Cyc.IdxEnd);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file defines DenseMapInfo traits for DenseMap.
This file defines the little GenericSSAContext<X> template class that can be used to implement IR ana...
This file defines the little GraphTraits<X> template class that should be specialized by classes that...
Provides some synthesis utilities to produce sequences of values.
This file implements a set that has insertion order iteration characteristics.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Opaque handle to a cycle within a GenericCycleInfo that wraps the cycle's preorder index.
friend class GenericCycleInfoCompute
bool operator!=(CycleRef O) const
bool operator==(CycleRef O) const
friend class GenericCycleInfo
Helper class for computing cycle information.
Cycle information for a function.
typename ContextT::FunctionT FunctionT
GenericCycleInfo()=default
void verify() const
Verify that the entire cycle tree well-formed.
auto cycles() const
All cycles in forest preorder.
void getExitingBlocks(CycleRef C, SmallVectorImpl< BlockT * > &TmpStorage) const
Return all blocks of C that have a successor outside of C.
iterator_range< const_toplevel_iterator > toplevel_cycles() const
void verifyCycle(CycleRef C) const
Verify that C is actually a well-formed cycle in the CFG.
bool isReducible(CycleRef C) const
BlockT * getCyclePreheader(CycleRef C) const
Return the preheader block for C.
CycleRef getSmallestCommonCycle(CycleRef A, CycleRef B) const
Find the innermost cycle containing both given cycles.
CycleRef getParentCycle(CycleRef C) const
BlockT * getCyclePredecessor(CycleRef C) const
If C has exactly one entry with exactly one predecessor, return it, otherwise return nullptr.
friend class GenericCycleInfoCompute
const_toplevel_iterator toplevel_end() const
void verifyCycleNest(CycleRef C) const
Verify the parent-child relations of C.
const FunctionT * getFunction() const
const_child_iterator const_toplevel_iterator
Iteration over top-level cycles.
void print(raw_ostream &Out) const
Print the cycle info.
ArrayRef< BlockT * > getEntries(CycleRef C) const
GenericCycleInfo & operator=(GenericCycleInfo &&)=default
CycleRef getTopLevelParentCycle(const BlockT *Block) const
void setSingleEntry(CycleRef C, BlockT *Block)
void clear()
Reset the object to its initial state.
void addBlockToCycle(BlockT *Block, CycleRef C)
Assumes that C is the innermost cycle containing Block.
ArrayRef< BlockT * > getBlocks(CycleRef C) const
Return the blocks of C, including those of nested cycles.
Printable printEntries(CycleRef C, const ContextT &Ctx) const
unsigned getDepth(CycleRef C) const
void compute(FunctionT &F)
Compute the cycle info for a function.
void splitCriticalEdge(BlockT *Pred, BlockT *Succ, BlockT *New)
const ContextT & getSSAContext() const
bool contains(CycleRef Outer, CycleRef Inner) const
Returns true iff Outer contains Inner. O(1). Non-strict.
GenericCycleInfo(GenericCycleInfo &&)=default
void getExitBlocks(CycleRef C, SmallVectorImpl< BlockT * > &TmpStorage) const
Return all of the successor blocks of C: the blocks outside of C which are branched to from within it...
size_t getNumBlocks(CycleRef C) const
bool isEntry(CycleRef C, const BlockT *Block) const
unsigned getCycleDepth(const BlockT *Block) const
Return the depth of the innermost cycle containing Block, or 0 if it is not contained in any cycle.
BlockT * getHeader(CycleRef C) const
bool contains(CycleRef C, const BlockT *Block) const
Return whether Block is contained in C. O(1).
typename ContextT::BlockT BlockT
const_toplevel_iterator toplevel_begin() const
CycleRef getCycle(const BlockT *Block) const
Find the innermost cycle containing Block.
iterator_range< const_child_iterator > children(CycleRef C) const
A helper class to return the specified delimiter string after the first invocation of operator String...
Simple wrapper around std::function<void(raw_ostream&)>.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
CRTP base class which implements the entire standard iterator facade in terms of a minimal subset of ...
A range adaptor for a pair of iterators.
This class implements an extremely fast bulk output stream that can only output to a stream.
This is an optimization pass for GlobalISel generic memory operations.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
auto map_range(ContainerTy &&C, FuncTy F)
Return a range that applies F to the elements of C.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
ArrayRef(const T &OneElt) -> ArrayRef< T >
constexpr auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
static unsigned getHashValue(CycleRef C)
static bool isEqual(CycleRef A, CycleRef B)
An information struct used to provide DenseMap with the various necessary components for a given valu...
Iteration over child cycles, yielding handles.
const GenericCycleInfo * CI
CycleRef operator*() const
const_child_iterator()=default
const_child_iterator(const GenericCycleInfo &CI, unsigned Index)
bool operator==(const const_child_iterator &Other) const
const_child_iterator & operator++()