14#ifndef LLVM_SUPPORT_CFGDIFF_H
15#define LLVM_SUPPORT_CFGDIFF_H
36template <
typename Range>
38 return std::forward<Range>(R);
41template <
typename Range>
48 std::integral_constant<bool, B>{});
57template <
typename NodePtr,
bool InverseGraph = false>
class GraphDiff {
58 struct DeletesInserts {
69 bool UpdatedAreReverseApplied;
77 StringRef DIText[2] = {
"Delete",
"Insert"};
79 for (
unsigned IsInsert = 0; IsInsert <= 1; ++IsInsert) {
80 OS << DIText[IsInsert] <<
" edges: \n";
81 for (
auto Child : Pair.second.DI[IsInsert]) {
83 Pair.first->printAsOperand(
OS,
false);
85 Child->printAsOperand(
OS,
false);
96 bool ReverseApplyUpdates =
false) {
97 cfg::LegalizeUpdates<NodePtr>(Updates, LegalizedUpdates, InverseGraph);
98 for (
auto U : LegalizedUpdates) {
101 Succ[U.getFrom()].DI[IsInsert].push_back(U.getTo());
102 Pred[U.getTo()].DI[IsInsert].push_back(U.getFrom());
104 UpdatedAreReverseApplied = ReverseApplyUpdates;
114 assert(!LegalizedUpdates.
empty() &&
"No updates to apply!");
118 auto &SuccDIList = Succ[U.getFrom()];
119 auto &SuccList = SuccDIList.DI[IsInsert];
120 assert(SuccList.back() == U.getTo());
122 if (SuccList.empty() && SuccDIList.DI[!IsInsert].empty())
123 Succ.
erase(U.getFrom());
125 auto &PredDIList = Pred[U.getTo()];
126 auto &PredList = PredDIList.DI[IsInsert];
127 assert(PredList.back() == U.getFrom());
129 if (PredList.empty() && PredDIList.DI[!IsInsert].empty())
130 Pred.
erase(U.getTo());
136 using DirectedNodeT =
137 std::conditional_t<InverseEdge, Inverse<NodePtr>, NodePtr>;
138 auto R = children<DirectedNodeT>(
N);
144 auto &Children = (InverseEdge != InverseGraph) ? Pred : Succ;
145 auto It = Children.find(
N);
146 if (It == Children.end())
150 for (
auto *Child : It->second.DI[0])
154 auto &AddedChildren = It->second.DI[1];
161 OS <<
"===== GraphDiff: CFG edge changes to create a CFG snapshot. \n"
162 "===== (Note: notion of children/inverse_children depends on "
163 "the direction of edges and the graph.)\n";
164 OS <<
"Children to delete/insert:\n\t";
166 OS <<
"Inverse_children to delete/insert:\n\t";
171#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
This file defines the little GraphTraits<X> template class that should be specialized by classes that...
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
bool erase(const KeyT &Val)
auto getLegalizedUpdates() const
SmallVector< NodePtr, 8 > VectRet
void print(raw_ostream &OS) const
LLVM_DUMP_METHOD void dump() const
VectRet getChildren(NodePtr N) const
GraphDiff(ArrayRef< cfg::Update< NodePtr > > Updates, bool ReverseApplyUpdates=false)
cfg::Update< NodePtr > popUpdateForIncrementalUpdates()
unsigned getNumLegalizedUpdates() const
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
This class implements an extremely fast bulk output stream that can only output to a stream.
This provides a very simple, boring adaptor for a begin and end iterator into a range type.
auto reverse_if(Range &&R)
auto reverse_if_helper(Range &&R, std::integral_constant< bool, false >)
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.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
void erase(Container &C, ValueType V)
Wrapper function to remove a value from a container:
auto reverse(ContainerTy &&C)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.