25#ifndef LLVM_LIB_TARGET_X86_IMMUTABLEGRAPH_H
26#define LLVM_LIB_TARGET_X86_IMMUTABLEGRAPH_H
82 : Nodes(
std::
move(Nodes)), Edges(
std::
move(Edges)), NodesSize(NodesSize),
83 EdgesSize(EdgesSize) {}
120 bool AlreadyExists = V.test(
Idx);
122 return !AlreadyExists;
169 Current = Set.V.find_next(Current);
174 : Set{Set}, Current{Begin} {}
186 return Set.G.nodes_begin() + Current;
189 assert(&this->Set == &other.Set);
190 return this->Current == other.Current;
208 bool AlreadyExists = V.test(
Idx);
210 return !AlreadyExists;
221 bool empty()
const {
return V.none(); }
257 Current = Set.V.find_next(Current);
262 : Set{Set}, Current{Begin} {}
274 return Set.G.edges_begin() + Current;
277 assert(&this->Set == &other.Set);
278 return this->Current == other.Current;
288 std::unique_ptr<Node[]> Nodes;
289 std::unique_ptr<Edge[]> Edges;
295 using node_value_type =
typename GraphT::node_value_type;
296 using edge_value_type =
typename GraphT::edge_value_type;
298 std::is_base_of<ImmutableGraph<node_value_type, edge_value_type>,
300 "Template argument to ImmutableGraphBuilder must derive from "
302 using size_type =
typename GraphT::size_type;
303 using NodeSet =
typename GraphT::NodeSet;
304 using Node =
typename GraphT::Node;
305 using EdgeSet =
typename GraphT::EdgeSet;
306 using Edge =
typename GraphT::Edge;
307 using BuilderEdge = std::pair<edge_value_type, size_type>;
308 using EdgeList = std::vector<BuilderEdge>;
309 using BuilderVertex = std::pair<node_value_type, EdgeList>;
310 using VertexVec = std::vector<BuilderVertex>;
316 auto I = AdjList.emplace(AdjList.end(), V, EdgeList{});
317 return std::distance(AdjList.begin(),
I);
322 AdjList[
From].second.emplace_back(
E, To);
325 bool empty()
const {
return AdjList.empty(); }
327 template <
typename... ArgT> std::unique_ptr<GraphT>
get(ArgT &&... Args) {
328 size_type VertexSize = AdjList.size(), EdgeSize = 0;
329 for (
const auto &V : AdjList) {
330 EdgeSize += V.second.size();
333 std::make_unique<Node[]>(VertexSize + 1 );
334 auto EdgeArray = std::make_unique<Edge[]>(EdgeSize);
335 size_type VI = 0, EI = 0;
336 for (; VI < VertexSize; ++VI) {
337 VertexArray[VI].Value = std::move(AdjList[VI].first);
338 VertexArray[VI].Edges = &EdgeArray[EI];
339 auto NumEdges =
static_cast<size_type
>(AdjList[VI].second.size());
340 for (size_type VEI = 0; VEI < NumEdges; ++VEI, ++EI) {
341 auto &
E = AdjList[VI].second[VEI];
342 EdgeArray[EI].Value = std::move(
E.first);
343 EdgeArray[EI].Dest = &VertexArray[
E.second];
346 assert(VI == VertexSize && EI == EdgeSize &&
"ImmutableGraph malformed");
347 VertexArray[VI].Edges = &EdgeArray[EdgeSize];
348 return std::make_unique<GraphT>(std::move(VertexArray),
349 std::move(EdgeArray), VertexSize, EdgeSize,
350 std::forward<ArgT>(Args)...);
353 template <
typename... ArgT>
354 static std::unique_ptr<GraphT>
trim(
const GraphT &
G,
const NodeSet &TrimNodes,
355 const EdgeSet &TrimEdges,
357 size_type NewVertexSize =
G.nodes_size() - TrimNodes.count();
358 size_type NewEdgeSize =
G.edges_size() - TrimEdges.count();
359 auto NewVertexArray =
360 std::make_unique<Node[]>(NewVertexSize + 1 );
361 auto NewEdgeArray = std::make_unique<Edge[]>(NewEdgeSize);
364 size_type NewNodeIndex = 0;
365 std::vector<size_type> RemappedNodeIndex(
G.nodes_size());
366 for (
const Node &
N :
G.nodes()) {
367 if (TrimNodes.contains(
N))
369 RemappedNodeIndex[
G.getNodeIndex(
N)] = NewNodeIndex++;
371 assert(NewNodeIndex == NewVertexSize &&
372 "Should have assigned NewVertexSize indices");
374 size_type VertexI = 0, EdgeI = 0;
375 for (
const Node &
N :
G.nodes()) {
376 if (TrimNodes.contains(
N))
378 NewVertexArray[VertexI].Value =
N.getValue();
379 NewVertexArray[VertexI].Edges = &NewEdgeArray[EdgeI];
380 for (
const Edge &
E :
N.edges()) {
381 if (TrimEdges.contains(
E))
383 NewEdgeArray[EdgeI].Value =
E.getValue();
384 size_type DestIdx =
G.getNodeIndex(*
E.getDest());
385 size_type NewIdx = RemappedNodeIndex[DestIdx];
386 assert(NewIdx < NewVertexSize);
387 NewEdgeArray[EdgeI].Dest = &NewVertexArray[NewIdx];
392 assert(VertexI == NewVertexSize && EdgeI == NewEdgeSize &&
393 "Gadget graph malformed");
394 NewVertexArray[VertexI].Edges = &NewEdgeArray[NewEdgeSize];
395 return std::make_unique<GraphT>(std::move(NewVertexArray),
396 std::move(NewEdgeArray), NewVertexSize,
397 NewEdgeSize, std::forward<ArgT>(Args)...);
404template <
typename NodeValueT,
typename EdgeValueT>
416 return {
N->edges_begin(), &edge_dest};
419 return {
N->edges_end(), &edge_dest};
426 return {
G->nodes_begin(), &
getNode};
435 return N->edges_begin();
438 return N->edges_end();
static msgpack::DocNode getNode(msgpack::DocNode DN, msgpack::Type Type, MCValue Val)
This file implements the BitVector class.
BlockVerifier::State From
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
Given that RA is a live value
This file defines the little GraphTraits<X> template class that should be specialized by classes that...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
const_set_bits_iterator_impl< BitVector > const_set_bits_iterator
std::unique_ptr< GraphT > get(ArgT &&... Args)
BuilderNodeRef addVertex(const node_value_type &V)
void addEdge(const edge_value_type &E, BuilderNodeRef From, BuilderNodeRef To)
static std::unique_ptr< GraphT > trim(const GraphT &G, const NodeSet &TrimNodes, const EdgeSet &TrimEdges, ArgT &&... Args)
iterator(const EdgeSet &Set, size_type Begin)
bool operator==(const iterator &other) const
bool operator!=(const iterator &other) const
EdgeSet & operator&=(const EdgeSet &RHS)
Set intersection.
index_iterator index_begin() const
EdgeSet(const ImmutableGraph &G, bool ContainsAll=false)
EdgeSet & operator^=(const EdgeSet &RHS)
Set disjoint union.
size_type count() const
Return the number of elements in the set.
void erase(const Edge &E)
bool contains(const Edge &E) const
bool insert(const Edge &E)
size_type size() const
Return the size of the set's domain.
EdgeSet & operator|=(const EdgeSet &RHS)
Set union.
void reset(size_type Idx)
index_iterator index_end() const
typename BitVector::const_set_bits_iterator index_iterator
const edge_value_type & getValue() const
const Node * getDest() const
iterator(const NodeSet &Set, size_type Begin)
bool operator!=(const iterator &other) const
bool operator==(const iterator &other) const
NodeSet & operator^=(const NodeSet &RHS)
Set disjoint union.
NodeSet & operator&=(const NodeSet &RHS)
Set intersection.
void reset(size_type Idx)
typename BitVector::const_set_bits_iterator index_iterator
bool contains(const Node &N) const
bool insert(const Node &N)
size_type count() const
Return the number of elements in the set.
NodeSet(const ImmutableGraph &G, bool ContainsAll=false)
NodeSet & operator|=(const NodeSet &RHS)
Set union.
index_iterator index_end() const
index_iterator index_begin() const
void erase(const Node &N)
size_type size() const
Return the size of the set's domain.
const Edge * edges_begin() const
const Edge * edges_end() const
const node_value_type & getValue() const
ArrayRef< Edge > edges() const
const Node * nodes_begin() const
ImmutableGraph & operator=(ImmutableGraph &&)=delete
ArrayRef< Edge > edges() const
const Node * nodes_end() const
const Edge * edges_begin() const
size_type nodes_size() const
size_type getNodeIndex(const Node &N) const
size_type getEdgeIndex(const Edge &E) const
ImmutableGraph(const ImmutableGraph &)=delete
ImmutableGraph(ImmutableGraph &&)=delete
const Edge * edges_end() const
ImmutableGraph & operator=(const ImmutableGraph &)=delete
size_type edges_size() const
EdgeValueT edge_value_type
NodeValueT node_value_type
ImmutableGraph(std::unique_ptr< Node[]> Nodes, std::unique_ptr< Edge[]> Edges, size_type NodesSize, size_type EdgesSize)
ArrayRef< Node > nodes() const
LLVM Value Representation.
This is an optimization pass for GlobalISel generic memory operations.
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Implement std::hash so that hash_code can be used in STL containers.
typename GraphT::Edge const * ChildEdgeIteratorType
static nodes_iterator nodes_end(GraphT *G)
static GraphT::size_type size(GraphT *G)
static nodes_iterator nodes_begin(GraphT *G)
static ChildIteratorType child_begin(NodeRef N)
static NodeRef edge_dest(EdgeRef E)
static NodeRef getNode(typename GraphT::Node const &N)
static ChildEdgeIteratorType child_edge_end(NodeRef N)
typename GraphT::Edge const & EdgeRef
static ChildEdgeIteratorType child_edge_begin(NodeRef N)
static ChildIteratorType child_end(NodeRef N)
typename GraphT::Node const * NodeRef
static NodeRef getEntryNode(GraphT *G)