souffle  2.0.2-371-g6315b36
ReorderLiterals.cpp
Go to the documentation of this file.
1 /*
2  * Souffle - A Datalog Compiler
3  * Copyright (c) 2018, The Souffle Developers. 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 ReorderLiterals.cpp
12  *
13  * Define classes and functionality related to the ReorderLiterals
14  * transformer.
15  *
16  ***********************************************************************/
17 
19 #include "Global.h"
20 #include "ast/Argument.h"
21 #include "ast/Atom.h"
22 #include "ast/Clause.h"
23 #include "ast/Program.h"
24 #include "ast/TranslationUnit.h"
25 #include "ast/Variable.h"
28 #include "ast/utility/SipsMetric.h"
29 #include "ast/utility/Utils.h"
30 #include <algorithm>
31 #include <memory>
32 #include <set>
33 #include <string>
34 #include <utility>
35 #include <vector>
36 
37 namespace souffle::ast::transform {
38 
39 Clause* ReorderLiteralsTransformer::reorderClauseWithSips(const SipsMetric& sips, const Clause* clause) {
40  // ignore clauses with fixed execution plans
41  if (clause->getExecutionPlan() != nullptr) {
42  return nullptr;
43  }
44 
45  // get the ordering corresponding to the SIPS
46  std::vector<unsigned int> newOrdering = sips.getReordering(clause);
47 
48  // check if we need a change
49  bool changeNeeded = false;
50  for (unsigned int i = 0; i < newOrdering.size(); i++) {
51  if (newOrdering[i] != i) {
52  changeNeeded = true;
53  }
54  }
55 
56  // reorder if needed
57  return changeNeeded ? reorderAtoms(clause, newOrdering) : nullptr;
58 }
59 
61  bool changed = false;
62  Program& program = translationUnit.getProgram();
63 
64  // --- SIPS-based static reordering ---
65  // ordering is based on the given SIPS
66 
67  // default SIPS to choose is 'all-bound'
68  std::string sipsChosen = "all-bound";
69  if (Global::config().has("SIPS")) {
70  sipsChosen = Global::config().get("SIPS");
71  }
72  auto sipsFunction = SipsMetric::create(sipsChosen, translationUnit);
73 
74  // literal reordering is a rule-local transformation
75  std::vector<Clause*> clausesToRemove;
76 
77  for (Clause* clause : program.getClauses()) {
78  Clause* newClause = reorderClauseWithSips(*sipsFunction, clause);
79  if (newClause != nullptr) {
80  // reordering needed - swap around
81  clausesToRemove.push_back(clause);
82  program.addClause(Own<Clause>(newClause));
83  }
84  }
85 
86  changed |= !clausesToRemove.empty();
87  for (auto* clause : clausesToRemove) {
88  program.removeClause(clause);
89  }
90 
91  // --- profile-guided reordering ---
92  if (Global::config().has("profile-use")) {
93  // parse supplied profile information
94  auto profilerSips = SipsMetric::create("profiler", translationUnit);
95 
96  // change the ordering of literals within clauses
97  std::vector<Clause*> clausesToRemove;
98  for (Clause* clause : program.getClauses()) {
99  Clause* newClause = reorderClauseWithSips(*profilerSips, clause);
100  if (newClause != nullptr) {
101  // reordering needed - swap around
102  clausesToRemove.push_back(clause);
103  program.addClause(Own<Clause>(newClause));
104  }
105  }
106 
107  changed |= !clausesToRemove.empty();
108  for (auto* clause : clausesToRemove) {
109  program.removeClause(clause);
110  }
111  }
112 
113  return changed;
114 }
115 
116 } // namespace souffle::ast::transform
TranslationUnit.h
souffle::ast::reorderAtoms
Clause * reorderAtoms(const Clause *clause, const std::vector< unsigned int > &newOrder)
Reorders the atoms of a clause to be in the given order.
Definition: Utils.cpp:264
souffle::Own
std::unique_ptr< A > Own
Definition: ContainerUtil.h:42
ProfileUse.h
souffle::ast::Clause
Intermediate representation of a horn clause.
Definition: Clause.h:51
souffle::ast::Program::getClauses
std::vector< Clause * > getClauses() const
Return clauses.
Definition: Program.h:65
souffle::ast::transform::ReorderLiteralsTransformer::transform
bool transform(TranslationUnit &translationUnit) override
Definition: ReorderLiterals.cpp:67
souffle::ast::SipsMetric::create
static std::unique_ptr< SipsMetric > create(const std::string &heuristic, const TranslationUnit &tu)
Create a SIPS metric based on a given heuristic.
Definition: SipsMetric.cpp:68
Utils.h
Global.h
Argument.h
souffle::ast::Program
The program class consists of relations, clauses and types.
Definition: Program.h:52
i
size_t i
Definition: json11.h:663
souffle::ast::transform::ReorderLiteralsTransformer::reorderClauseWithSips
static Clause * reorderClauseWithSips(const SipsMetric &sips, const Clause *clause)
Reorder the clause based on a given SIPS function.
Definition: ReorderLiterals.cpp:46
Atom.h
souffle::ast::TranslationUnit
Translation unit class for the translation pipeline.
Definition: TranslationUnit.h:51
souffle::ast::Program::addClause
void addClause(Own< Clause > clause)
Add a clause.
Definition: Program.cpp:62
souffle::ast::transform
Definition: Program.h:45
SipsMetric.h
souffle::Global::config
static MainConfig & config()
Definition: Global.h:141
ReorderLiterals.h
Program.h
BindingStore.h
Clause.h
souffle::ast::TranslationUnit::getProgram
Program & getProgram() const
Return the program.
Definition: TranslationUnit.h:84
souffle::ast::Program::removeClause
bool removeClause(const Clause *clause)
Remove a clause.
Definition: Program.cpp:68
Variable.h