souffle  2.0.2-371-g6315b36
RelationSchedule.cpp
Go to the documentation of this file.
1 /*
2  * Souffle - A Datalog Compiler
3  * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved
4  * Licensed under the Universal Permissive License v 1.0 as shown at:
5  * - https://opensource.org/licenses/UPL
6  * - <souffle root>/licenses/SOUFFLE-UPL.txt
7  */
8 
9 /************************************************************************
10  *
11  * @file RelationSchedule.cpp
12  *
13  * Implements method of precedence graph to build the precedence graph,
14  * compute strongly connected components of the precedence graph, and
15  * build the strongly connected component graph.
16  *
17  ***********************************************************************/
18 
20 #include "GraphUtils.h"
21 #include "ast/QualifiedName.h"
22 #include "ast/Relation.h"
23 #include "ast/TranslationUnit.h"
25 #include "ast/analysis/SCCGraph.h"
27 #include <algorithm>
28 #include <cstddef>
29 #include <iterator>
30 #include <memory>
31 #include <set>
32 
33 namespace souffle::ast::analysis {
34 
35 void RelationScheduleAnalysisStep::print(std::ostream& os) const {
36  os << "computed: ";
37  for (const Relation* compRel : computed()) {
38  os << compRel->getQualifiedName() << ", ";
39  }
40  os << "\nexpired: ";
41  for (const Relation* compRel : expired()) {
42  os << compRel->getQualifiedName() << ", ";
43  }
44  os << "\n";
45  if (recursive()) {
46  os << "recursive";
47  } else {
48  os << "not recursive";
49  }
50  os << "\n";
51 }
52 
53 void RelationScheduleAnalysis::run(const TranslationUnit& translationUnit) {
54  topsortSCCGraphAnalysis = translationUnit.getAnalysis<TopologicallySortedSCCGraphAnalysis>();
55  precedenceGraph = translationUnit.getAnalysis<PrecedenceGraphAnalysis>();
56 
57  size_t numSCCs = translationUnit.getAnalysis<SCCGraphAnalysis>()->getNumberOfSCCs();
58  std::vector<std::set<const Relation*>> relationExpirySchedule =
59  computeRelationExpirySchedule(translationUnit);
60 
62  for (size_t i = 0; i < numSCCs; i++) {
63  auto scc = topsortSCCGraphAnalysis->order()[i];
64  const std::set<const Relation*> computedRelations =
65  translationUnit.getAnalysis<SCCGraphAnalysis>()->getInternalRelations(scc);
66  relationSchedule.emplace_back(computedRelations, relationExpirySchedule[i],
67  translationUnit.getAnalysis<SCCGraphAnalysis>()->isRecursive(scc));
68  }
69 }
70 
71 std::vector<std::set<const Relation*>> RelationScheduleAnalysis::computeRelationExpirySchedule(
72  const TranslationUnit& translationUnit) {
73  std::vector<std::set<const Relation*>> relationExpirySchedule;
74  /* Compute for each step in the reverse topological order
75  of evaluating the SCC the set of alive relations. */
76  size_t numSCCs = topsortSCCGraphAnalysis->order().size();
77 
78  /* Alive set for each step */
79  std::vector<std::set<const Relation*>> alive(numSCCs);
80  /* Resize expired relations sets */
81  relationExpirySchedule.resize(numSCCs);
82  const auto& sccGraph = translationUnit.getAnalysis<SCCGraphAnalysis>();
83 
84  /* Compute all alive relations by iterating over all steps in reverse order
85  determine the dependencies */
86  for (size_t orderedSCC = 1; orderedSCC < numSCCs; orderedSCC++) {
87  /* Add alive set of previous step */
88  alive[orderedSCC].insert(alive[orderedSCC - 1].begin(), alive[orderedSCC - 1].end());
89 
90  /* Add predecessors of relations computed in this step */
91  auto scc = topsortSCCGraphAnalysis->order()[numSCCs - orderedSCC];
92  for (const Relation* r : sccGraph->getInternalRelations(scc)) {
93  for (const Relation* predecessor : precedenceGraph->graph().predecessors(r)) {
94  alive[orderedSCC].insert(predecessor);
95  }
96  }
97 
98  /* Compute expired relations in reverse topological order using the set difference of the alive sets
99  between steps. */
100  std::set_difference(alive[orderedSCC].begin(), alive[orderedSCC].end(), alive[orderedSCC - 1].begin(),
101  alive[orderedSCC - 1].end(),
102  std::inserter(relationExpirySchedule[numSCCs - orderedSCC],
103  relationExpirySchedule[numSCCs - orderedSCC].end()));
104  }
105 
106  return relationExpirySchedule;
107 }
108 
109 void RelationScheduleAnalysis::print(std::ostream& os) const {
110  os << "begin schedule\n";
111  for (const RelationScheduleAnalysisStep& step : relationSchedule) {
112  os << step;
113  os << "computed: ";
114  for (const Relation* compRel : step.computed()) {
115  os << compRel->getQualifiedName() << ", ";
116  }
117  os << "\nexpired: ";
118  for (const Relation* compRel : step.expired()) {
119  os << compRel->getQualifiedName() << ", ";
120  }
121  os << "\n";
122  if (step.recursive()) {
123  os << "recursive";
124  } else {
125  os << "not recursive";
126  }
127  os << "\n";
128  }
129  os << "end schedule\n";
130 }
131 
132 } // namespace souffle::ast::analysis
souffle::ast::analysis::RelationScheduleAnalysisStep::recursive
bool recursive() const
Definition: RelationSchedule.h:69
RelationSchedule.h
TranslationUnit.h
souffle::ast::analysis::TopologicallySortedSCCGraphAnalysis::order
const std::vector< size_t > & order() const
Definition: TopologicallySortedSCCGraph.h:57
souffle::ast::analysis::RelationScheduleAnalysisStep::print
void print(std::ostream &os) const
Definition: RelationSchedule.cpp:43
souffle::ast::analysis::RelationScheduleAnalysis::print
void print(std::ostream &os) const override
Dump this relation schedule to standard error.
Definition: RelationSchedule.cpp:117
souffle::ast::analysis::RelationScheduleAnalysis::computeRelationExpirySchedule
std::vector< std::set< const Relation * > > computeRelationExpirySchedule(const TranslationUnit &translationUnit)
Definition: RelationSchedule.cpp:79
souffle::ast::Relation
Defines a relation with a name, attributes, qualifiers, and internal representation.
Definition: Relation.h:49
souffle::ast::analysis::PrecedenceGraphAnalysis::graph
const Graph< const Relation *, NameComparison > & graph() const
Definition: PrecedenceGraph.h:54
Relation.h
SCCGraph.h
souffle::ast::analysis::RelationScheduleAnalysis::relationSchedule
std::vector< RelationScheduleAnalysisStep > relationSchedule
Relations computed and expired relations at each step.
Definition: RelationSchedule.h:102
i
size_t i
Definition: json11.h:663
souffle::ast::analysis::SCCGraphAnalysis::isRecursive
bool isRecursive(const size_t scc) const
Return if the given SCC is recursive.
Definition: SCCGraph.h:201
TopologicallySortedSCCGraph.h
souffle::ast::analysis::RelationScheduleAnalysis::topsortSCCGraphAnalysis
TopologicallySortedSCCGraphAnalysis * topsortSCCGraphAnalysis
Definition: RelationSchedule.h:98
souffle::ast::analysis::RelationScheduleAnalysis::precedenceGraph
PrecedenceGraphAnalysis * precedenceGraph
Definition: RelationSchedule.h:99
souffle::ast::TranslationUnit
Translation unit class for the translation pipeline.
Definition: TranslationUnit.h:51
GraphUtils.h
souffle::ast::analysis::RelationScheduleAnalysisStep::computed
const std::set< const Relation * > & computed() const
Definition: RelationSchedule.h:61
souffle::ast::TranslationUnit::getAnalysis
Analysis * getAnalysis() const
get analysis: analysis is generated on the fly if not present
Definition: TranslationUnit.h:60
QualifiedName.h
souffle::ast::analysis::RelationScheduleAnalysis::run
void run(const TranslationUnit &translationUnit) override
run analysis for a Ast translation unit
Definition: RelationSchedule.cpp:61
souffle::ast::analysis::SCCGraphAnalysis
Analysis pass computing the strongly connected component (SCC) graph for the datalog program.
Definition: SCCGraph.h:50
souffle::ast::analysis::RelationScheduleAnalysisStep::expired
const std::set< const Relation * > & expired() const
Definition: RelationSchedule.h:65
souffle::ast::analysis
Definition: Aggregate.cpp:39
PrecedenceGraph.h