souffle  2.0.2-371-g6315b36
Public Member Functions | Static Public Attributes | Private Member Functions | Private Attributes
souffle::ast::analysis::SCCGraphAnalysis Class Reference

Analysis pass computing the strongly connected component (SCC) graph for the datalog program. More...

#include <SCCGraph.h>

Inheritance diagram for souffle::ast::analysis::SCCGraphAnalysis:
Inheritance graph
Collaboration diagram for souffle::ast::analysis::SCCGraphAnalysis:
Collaboration graph

Public Member Functions

std::set< const Relation * > getExternalNonOutputPredecessorRelations (const size_t scc) const
 Get all external non-output predecessor relations of a given SCC. More...
 
std::set< const Relation * > getExternalOutputPredecessorRelations (const size_t scc) const
 Get all external output predecessor relations of a given SCC. More...
 
std::set< const Relation * > getExternalPredecessorRelations (const size_t scc) const
 Get all external predecessor relations of a given SCC. More...
 
std::set< const Relation * > getInternalInputRelations (const size_t scc) const
 Get all internal input relations of a given SCC. More...
 
std::set< const Relation * > getInternalNonOutputRelationsWithExternalSuccessors (const size_t scc) const
 Get all internal non-output relations of a given SCC with external successors. More...
 
std::set< const Relation * > getInternalOutputRelations (const size_t scc) const
 Get all internal output relations of a given SCC. More...
 
const std::set< const Relation * > & getInternalRelations (const size_t scc) const
 Get all internal relations of a given SCC. More...
 
std::set< const Relation * > getInternalRelationsWithExternalSuccessors (const size_t scc) const
 Get all internal relations of a given SCC with external successors. More...
 
size_t getNumberOfSCCs () const
 Get the number of SCCs in the graph. More...
 
std::set< size_t > getPredecessorSCCs (const Relation *relation) const
 Get all SCCs containing a predecessor of a given relation. More...
 
const std::set< size_t > & getPredecessorSCCs (const size_t scc) const
 Get all predecessor SCCs of a given SCC. More...
 
size_t getSCC (const Relation *rel) const
 Get the SCC of the given relation. More...
 
std::set< size_t > getSuccessorSCCs (const Relation *relation) const
 Get all SCCs containing a successor of a given relation. More...
 
const std::set< size_t > & getSuccessorSCCs (const size_t scc) const
 Get all successor SCCs of a given SCC. More...
 
bool isRecursive (const size_t scc) const
 Return if the given SCC is recursive. More...
 
void print (std::ostream &os) const override
 Print the SCC graph. More...
 
void run (const TranslationUnit &translationUnit) override
 run analysis for a Ast translation unit More...
 
 SCCGraphAnalysis ()
 
- Public Member Functions inherited from souffle::ast::analysis::Analysis
 Analysis (std::string identifier)
 
virtual const std::string & getName () const
 get name of the analysis More...
 
virtual ~Analysis ()=default
 

Static Public Attributes

static constexpr const char * name = "scc-graph"
 

Private Member Functions

void scR (const Relation *relation, std::map< const Relation *, size_t > &preOrder, size_t &counter, std::stack< const Relation * > &S, std::stack< const Relation * > &P, size_t &numSCCs)
 Recursive scR method for computing SCC. More...
 

Private Attributes

IOTypeAnalysisioType = nullptr
 
PrecedenceGraphAnalysisprecedenceGraph = nullptr
 
std::vector< std::set< size_t > > predecessors
 Predecessor set for the SCC graph. More...
 
std::map< const Relation *, size_t > relationToScc
 Map from node number to SCC number. More...
 
std::vector< std::set< const Relation * > > sccToRelation
 Relations contained in a SCC. More...
 
std::vector< std::set< size_t > > successors
 Adjacency lists for the SCC graph. More...
 

Additional Inherited Members

- Protected Attributes inherited from souffle::ast::analysis::Analysis
const std::string identifier
 

Detailed Description

Analysis pass computing the strongly connected component (SCC) graph for the datalog program.

Definition at line 50 of file SCCGraph.h.

Constructor & Destructor Documentation

◆ SCCGraphAnalysis()

souffle::ast::analysis::SCCGraphAnalysis::SCCGraphAnalysis ( )
inline

Definition at line 54 of file SCCGraph.h.

56 {

References rel(), and relationToScc.

Here is the call graph for this function:

Member Function Documentation

◆ getExternalNonOutputPredecessorRelations()

std::set<const Relation*> souffle::ast::analysis::SCCGraphAnalysis::getExternalNonOutputPredecessorRelations ( const size_t  scc) const
inline

Get all external non-output predecessor relations of a given SCC.

Definition at line 123 of file SCCGraph.h.

128  {
129  std::set<const Relation*> externPreds;
130  for (const auto& relation : getInternalRelations(scc)) {
131  for (const auto& predecessor : precedenceGraph->graph().predecessors(relation)) {
132  if (relationToScc.at(predecessor) != scc) {
133  externPreds.insert(predecessor);

◆ getExternalOutputPredecessorRelations()

std::set<const Relation*> souffle::ast::analysis::SCCGraphAnalysis::getExternalOutputPredecessorRelations ( const size_t  scc) const
inline

Get all external output predecessor relations of a given SCC.

Definition at line 110 of file SCCGraph.h.

115  {
116  std::set<const Relation*> externNonOutPreds;
117  for (const auto& relation : getInternalRelations(scc)) {
118  for (const auto& predecessor : precedenceGraph->graph().predecessors(relation)) {
119  if (relationToScc.at(predecessor) != scc && !ioType->isOutput(predecessor)) {
120  externNonOutPreds.insert(predecessor);

◆ getExternalPredecessorRelations()

std::set<const Relation*> souffle::ast::analysis::SCCGraphAnalysis::getExternalPredecessorRelations ( const size_t  scc) const
inline

Get all external predecessor relations of a given SCC.

Definition at line 136 of file SCCGraph.h.

141  {
142  std::set<const Relation*> internOuts;
143  for (const auto& relation : getInternalRelations(scc)) {
144  if (ioType->isOutput(relation)) {
145  internOuts.insert(relation);
146  }

◆ getInternalInputRelations()

std::set<const Relation*> souffle::ast::analysis::SCCGraphAnalysis::getInternalInputRelations ( const size_t  scc) const
inline

Get all internal input relations of a given SCC.

Definition at line 190 of file SCCGraph.h.

193  {
194  const std::set<const Relation*>& sccRelations = sccToRelation.at(scc);
195  if (sccRelations.size() == 1) {
196  const Relation* singleRelation = *sccRelations.begin();
197  if (precedenceGraph->graph().predecessors(singleRelation).count(singleRelation) == 0u) {
198  return false;

◆ getInternalNonOutputRelationsWithExternalSuccessors()

std::set<const Relation*> souffle::ast::analysis::SCCGraphAnalysis::getInternalNonOutputRelationsWithExternalSuccessors ( const size_t  scc) const
inline

Get all internal non-output relations of a given SCC with external successors.

Definition at line 174 of file SCCGraph.h.

182  {
183  std::set<const Relation*> internIns;
184  for (const auto& relation : getInternalRelations(scc)) {
185  if (ioType->isInput(relation)) {
186  internIns.insert(relation);
187  }

◆ getInternalOutputRelations()

std::set<const Relation*> souffle::ast::analysis::SCCGraphAnalysis::getInternalOutputRelations ( const size_t  scc) const
inline

Get all internal output relations of a given SCC.

Definition at line 149 of file SCCGraph.h.

152  {
153  std::set<const Relation*> internsWithExternSuccs;
154  for (const auto& relation : getInternalRelations(scc)) {
155  for (const auto& successor : precedenceGraph->graph().successors(relation)) {
156  if (relationToScc.at(successor) != scc) {
157  internsWithExternSuccs.insert(relation);

◆ getInternalRelations()

const std::set<const Relation*>& souffle::ast::analysis::SCCGraphAnalysis::getInternalRelations ( const size_t  scc) const
inline

Get all internal relations of a given SCC.

Definition at line 105 of file SCCGraph.h.

105  : precedenceGraph->graph().predecessors(relation)) {
106  if (relationToScc.at(predecessor) != scc && ioType->isOutput(predecessor)) {
107  externOutPreds.insert(predecessor);

References ioType, souffle::ast::analysis::IOTypeAnalysis::isOutput(), and relationToScc.

Here is the call graph for this function:

◆ getInternalRelationsWithExternalSuccessors()

std::set<const Relation*> souffle::ast::analysis::SCCGraphAnalysis::getInternalRelationsWithExternalSuccessors ( const size_t  scc) const
inline

Get all internal relations of a given SCC with external successors.

Definition at line 160 of file SCCGraph.h.

166  {
167  std::set<const Relation*> internNonOutsWithExternSuccs;
168  for (const auto& relation : getInternalRelations(scc)) {
169  if (!ioType->isOutput(relation)) {
170  for (const auto& successor : precedenceGraph->graph().successors(relation)) {
171  if (relationToScc.at(successor) != scc) {

◆ getNumberOfSCCs()

size_t souffle::ast::analysis::SCCGraphAnalysis::getNumberOfSCCs ( ) const
inline

Get the number of SCCs in the graph.

Definition at line 59 of file SCCGraph.h.

61  {

References successors.

◆ getPredecessorSCCs() [1/2]

std::set<size_t> souffle::ast::analysis::SCCGraphAnalysis::getPredecessorSCCs ( const Relation relation) const
inline

Get all SCCs containing a predecessor of a given relation.

Definition at line 92 of file SCCGraph.h.

97  {
98  return sccToRelation.at(scc);
99  }
100 
101  /** Get all external output predecessor relations of a given SCC. */
102  std::set<const Relation*> getExternalOutputPredecessorRelations(const size_t scc) const {

◆ getPredecessorSCCs() [2/2]

const std::set<size_t>& souffle::ast::analysis::SCCGraphAnalysis::getPredecessorSCCs ( const size_t  scc) const
inline

Get all predecessor SCCs of a given SCC.

Definition at line 74 of file SCCGraph.h.

74  : precedenceGraph->graph().successors(relation)) {
75  const auto successorScc = relationToScc.at(successor);
76  if (successorScc != scc) {

References relationToScc.

Referenced by souffle::ast::analysis::TopologicallySortedSCCGraphAnalysis::run(), and souffle::ast::analysis::TopologicallySortedSCCGraphAnalysis::topologicalOrderingCost().

◆ getSCC()

size_t souffle::ast::analysis::SCCGraphAnalysis::getSCC ( const Relation rel) const
inline

Get the SCC of the given relation.

Definition at line 64 of file SCCGraph.h.

66  {

References predecessors.

◆ getSuccessorSCCs() [1/2]

std::set<size_t> souffle::ast::analysis::SCCGraphAnalysis::getSuccessorSCCs ( const Relation relation) const
inline

Get all SCCs containing a successor of a given relation.

Definition at line 79 of file SCCGraph.h.

84  {
85  std::set<size_t> predecessorSccs;
86  const auto scc = relationToScc.at(relation);
87  for (const auto& predecessor : precedenceGraph->graph().predecessors(relation)) {
88  const auto predecessorScc = relationToScc.at(predecessor);
89  if (predecessorScc != scc) {

◆ getSuccessorSCCs() [2/2]

const std::set<size_t>& souffle::ast::analysis::SCCGraphAnalysis::getSuccessorSCCs ( const size_t  scc) const
inline

◆ isRecursive()

bool souffle::ast::analysis::SCCGraphAnalysis::isRecursive ( const size_t  scc) const
inline

Return if the given SCC is recursive.

Definition at line 201 of file SCCGraph.h.

207  :
208  PrecedenceGraphAnalysis* precedenceGraph = nullptr;
209 
210  /** Map from node number to SCC number */

Referenced by souffle::ast::analysis::RelationScheduleAnalysis::run().

◆ print()

void souffle::ast::analysis::SCCGraphAnalysis::print ( std::ostream &  os) const
overridevirtual

Print the SCC graph.

Reimplemented from souffle::ast::analysis::Analysis.

Definition at line 124 of file SCCGraph.cpp.

125  { out << rel->getQualifiedName(); });
126  ss << "\" ];" << std::endl;
127  }
128  for (size_t scc = 0; scc < getNumberOfSCCs(); scc++) {
129  for (auto succ : getSuccessorSCCs(scc)) {
130  ss << "\t" << name << "_" << scc << " -> " << name << "_" << succ << ";" << std::endl;
131  }
132  }
133  ss << "}";
134  printHTMLGraph(os, ss.str(), getName());
135 }
136 
137 } // namespace souffle::ast::analysis

References rel().

Here is the call graph for this function:

◆ run()

void souffle::ast::analysis::SCCGraphAnalysis::run ( const TranslationUnit )
overridevirtual

run analysis for a Ast translation unit

Implements souffle::ast::analysis::Analysis.

Definition at line 44 of file SCCGraph.cpp.

52  : relations) {
53  relationToScc[relation] = preOrder[relation] = (size_t)-1;
54  }
55  for (const Relation* relation : relations) {
56  if (preOrder[relation] == (size_t)-1) {
57  scR(relation, preOrder, counter, S, P, numSCCs);
58  }
59  }
60 
61  /* Build SCC graph */
62  successors.resize(numSCCs);
63  predecessors.resize(numSCCs);
64  for (const Relation* u : relations) {
65  for (const Relation* v : precedenceGraph->graph().predecessors(u)) {
66  auto scc_u = relationToScc[u];
67  auto scc_v = relationToScc[v];
68  assert(scc_u < numSCCs && "Wrong range");
69  assert(scc_v < numSCCs && "Wrong range");
70  if (scc_u != scc_v) {
71  predecessors[scc_u].insert(scc_v);
72  successors[scc_v].insert(scc_u);
73  }
74  }
75  }
76 
77  /* Store the relations for each SCC */
78  sccToRelation.resize(numSCCs);
79  for (const Relation* relation : relations) {
81  }
82 }
83 
84 /* Compute strongly connected components using Gabow's algorithm (cf. Algorithms in
85  * Java by Robert Sedgewick / Part 5 / Graph * algorithms). The algorithm has linear
86  * runtime. */
87 void SCCGraphAnalysis::scR(const Relation* w, std::map<const Relation*, size_t>& preOrder, size_t& counter,
88  std::stack<const Relation*>& S, std::stack<const Relation*>& P, size_t& numSCCs) {
89  preOrder[w] = counter++;
90  S.push(w);

References relation, and relationToScc.

◆ scR()

void souffle::ast::analysis::SCCGraphAnalysis::scR ( const Relation relation,
std::map< const Relation *, size_t > &  preOrder,
size_t &  counter,
std::stack< const Relation * > &  S,
std::stack< const Relation * > &  P,
size_t &  numSCCs 
)
private

Recursive scR method for computing SCC.

Definition at line 95 of file SCCGraph.cpp.

95  {
96  while (preOrder[P.top()] > preOrder[t]) {
97  P.pop();
98  }
99  }
100  }
101  if (P.top() == w) {
102  P.pop();
103  } else {
104  return;
105  }
106 
107  const Relation* v;
108  do {
109  v = S.top();
110  S.pop();
111  relationToScc[v] = numSCCs;
112  } while (v != w);
113  numSCCs++;
114 }
115 
116 void SCCGraphAnalysis::print(std::ostream& os) const {
117  const std::string& name = Global::config().get("name");
118  std::stringstream ss;
119  /* Print SCC graph */
120  ss << "digraph {" << std::endl;
121  /* Print nodes of SCC graph */
122  for (size_t scc = 0; scc < getNumberOfSCCs(); scc++) {

Field Documentation

◆ ioType

IOTypeAnalysis* souffle::ast::analysis::SCCGraphAnalysis::ioType = nullptr
private

Definition at line 234 of file SCCGraph.h.

Referenced by getInternalRelations().

◆ name

constexpr const char* souffle::ast::analysis::SCCGraphAnalysis::name = "scc-graph"
staticconstexpr

Definition at line 52 of file SCCGraph.h.

◆ precedenceGraph

PrecedenceGraphAnalysis* souffle::ast::analysis::SCCGraphAnalysis::precedenceGraph = nullptr
private

Definition at line 216 of file SCCGraph.h.

◆ predecessors

std::vector<std::set<size_t> > souffle::ast::analysis::SCCGraphAnalysis::predecessors
private

Predecessor set for the SCC graph.

Definition at line 225 of file SCCGraph.h.

Referenced by getSCC().

◆ relationToScc

std::map<const Relation*, size_t> souffle::ast::analysis::SCCGraphAnalysis::relationToScc
private

Map from node number to SCC number.

Definition at line 219 of file SCCGraph.h.

Referenced by getInternalRelations(), getPredecessorSCCs(), getSuccessorSCCs(), run(), and SCCGraphAnalysis().

◆ sccToRelation

std::vector<std::set<const Relation*> > souffle::ast::analysis::SCCGraphAnalysis::sccToRelation
private

Relations contained in a SCC.

Definition at line 228 of file SCCGraph.h.

◆ successors

std::vector<std::set<size_t> > souffle::ast::analysis::SCCGraphAnalysis::successors
private

Adjacency lists for the SCC graph.

Definition at line 222 of file SCCGraph.h.

Referenced by getNumberOfSCCs().


The documentation for this class was generated from the following files:
souffle::ast::analysis::SCCGraphAnalysis::getExternalOutputPredecessorRelations
std::set< const Relation * > getExternalOutputPredecessorRelations(const size_t scc) const
Get all external output predecessor relations of a given SCC.
Definition: SCCGraph.h:110
souffle::ast::analysis::IOTypeAnalysis::isOutput
bool isOutput(const Relation *relation) const
Definition: IOType.h:53
S
#define S(x)
Definition: test.h:179
relation
Relation & relation
Definition: Reader.h:130
souffle::ast::analysis::SCCGraphAnalysis::print
void print(std::ostream &os) const override
Print the SCC graph.
Definition: SCCGraph.cpp:124
souffle::ast::analysis::PrecedenceGraphAnalysis::graph
const Graph< const Relation *, NameComparison > & graph() const
Definition: PrecedenceGraph.h:54
souffle::ast::analysis::SCCGraphAnalysis::scR
void scR(const Relation *relation, std::map< const Relation *, size_t > &preOrder, size_t &counter, std::stack< const Relation * > &S, std::stack< const Relation * > &P, size_t &numSCCs)
Recursive scR method for computing SCC.
Definition: SCCGraph.cpp:95
relations
std::vector< Own< Relation > > relations
Definition: ComponentInstantiation.cpp:65
souffle::ast::analysis::SCCGraphAnalysis::predecessors
std::vector< std::set< size_t > > predecessors
Predecessor set for the SCC graph.
Definition: SCCGraph.h:225
souffle::ast::analysis::SCCGraphAnalysis::precedenceGraph
PrecedenceGraphAnalysis * precedenceGraph
Definition: SCCGraph.h:216
souffle::printHTMLGraph
void printHTMLGraph(std::ostream &out, const std::string &dotSpec, const std::string &id)
Definition: GraphUtils.h:226
souffle::ast::analysis::Analysis::getName
virtual const std::string & getName() const
get name of the analysis
Definition: Analysis.h:50
souffle::ast::analysis::SCCGraphAnalysis::successors
std::vector< std::set< size_t > > successors
Adjacency lists for the SCC graph.
Definition: SCCGraph.h:222
souffle::ast::analysis::SCCGraphAnalysis::name
static constexpr const char * name
Definition: SCCGraph.h:52
souffle::ast::analysis::SCCGraphAnalysis::sccToRelation
std::vector< std::set< const Relation * > > sccToRelation
Relations contained in a SCC.
Definition: SCCGraph.h:228
souffle::ast::analysis::SCCGraphAnalysis::getNumberOfSCCs
size_t getNumberOfSCCs() const
Get the number of SCCs in the graph.
Definition: SCCGraph.h:59
souffle::ast::analysis::IOTypeAnalysis::isInput
bool isInput(const Relation *relation) const
Definition: IOType.h:49
souffle::Global::config
static MainConfig & config()
Definition: Global.h:141
souffle::ast::analysis::SCCGraphAnalysis::relationToScc
std::map< const Relation *, size_t > relationToScc
Map from node number to SCC number.
Definition: SCCGraph.h:219
souffle::ast::analysis::SCCGraphAnalysis::getSuccessorSCCs
const std::set< size_t > & getSuccessorSCCs(const size_t scc) const
Get all successor SCCs of a given SCC.
Definition: SCCGraph.h:69
rel
void rel(size_t limit, bool showLimit=true)
Definition: Tui.h:1086
souffle::ast::analysis::SCCGraphAnalysis::getInternalRelations
const std::set< const Relation * > & getInternalRelations(const size_t scc) const
Get all internal relations of a given SCC.
Definition: SCCGraph.h:105
souffle::ast::analysis::SCCGraphAnalysis::ioType
IOTypeAnalysis * ioType
Definition: SCCGraph.h:234
souffle::profile::ss
class souffle::profile::Tui ss
Definition: Tui.h:336