28#ifndef LLVM_ADT_GENERICCYCLEINFO_H
29#define LLVM_ADT_GENERICCYCLEINFO_H
54 static constexpr unsigned InvalidIndex = ~0u;
55 unsigned Index = InvalidIndex;
57 explicit CycleRef(
unsigned Index) : Index(Index) {}
64 bool isValid()
const {
return Index != InvalidIndex; }
66 bool operator==(CycleRef O)
const {
return Index == O.Index; }
67 bool operator!=(CycleRef O)
const {
return Index != O.Index; }
80 using BlockT =
typename ContextT::BlockT;
96 unsigned IdxBegin = 0, IdxEnd = 0;
105 unsigned NumDescendants = 0;
110 unsigned EntryBegin = 0, EntrySize = 0;
113 bool hasParent()
const {
return Parent.
isValid(); }
115 static_assert(std::is_trivially_destructible_v<Cycle>);
116 using CycleT = Cycle;
119 unsigned BlockNumberEpoch;
128 SmallVector<BlockT *, 8> BlockLayout;
133 std::unique_ptr<CycleT[]> Cycles;
134 unsigned NumCycles = 0;
141 unsigned getCycleIndex(
const CycleT &
C)
const {
return &
C - Cycles.get(); }
145 CycleT &deref(CycleRef
C) {
147 return Cycles[
C.Index];
149 const CycleT &deref(CycleRef
C)
const {
151 return Cycles[
C.Index];
154 CycleRef ref(
const CycleT &
C)
const {
return CycleRef(getCycleIndex(
C)); }
156 void verifyBlockNumberEpoch(
const FunctionT *Fn)
const {
157 assert(BlockNumberEpoch ==
158 GraphTraits<const FunctionT *>::getNumberEpoch(Fn) &&
159 "CycleInfo used with outdated block number epoch");
169 CycleRef, std::ptrdiff_t, CycleRef, CycleRef> {
209 verifyBlockNumberEpoch(
Block->getParent());
213 if (
Number >= BlockMap.size())
219 return BlockLayout[deref(
C).EntryBegin];
225 const CycleT &Cyc = deref(
C);
226 return Cyc.IdxEnd - Cyc.IdxBegin;
230 const CycleT &Cyc = deref(
C);
231 return ArrayRef(BlockLayout).slice(Cyc.EntryBegin, Cyc.EntrySize);
239 CycleT &Cyc = deref(
C);
240 Cyc.EntryBegin = BlockLayout.size();
241 BlockLayout.push_back(
Block);
246 const CycleT &O = deref(Outer);
247 const CycleT &
I = deref(Inner);
248 return O.IdxBegin <=
I.IdxBegin &&
I.IdxEnd <= O.IdxEnd;
251 unsigned First =
C.Index + 1;
260 Out << LS << Ctx.print(Entry);
272 const CycleT &Cyc = deref(
C);
274 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.
@ C
The default llvm calling convention, compatible with C.
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++()