MicroModelicaCCompiler  4.5.3
compute_deps.cpp
Go to the documentation of this file.
1 /*****************************************************************************
2 
3  This file is part of QSS Solver.
4 
5  QSS Solver is free software: you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation, either version 3 of the License, or
8  (at your option) any later version.
9 
10  QSS Solver is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with QSS Solver. If not, see <http://www.gnu.org/licenses/>.
17 
18  ******************************************************************************/
19 
20 #include "compute_deps.hpp"
21 
22 #include <ir/helpers.hpp>
23 #include <util/model_config.hpp>
24 
25 namespace MicroModelica {
26 using namespace Deps;
27 using namespace SB;
28 using namespace Util;
29 namespace IR {
30 
31 Expression getUseExp(Variable variable, DepData dep_data)
32 {
33  if (variable.isScalar()) {
34  return Expression::generate(variable.name(), vector<string>());
35  }
36  Index use_idx(dep_data.var_dep.exp());
37  vector<string> vars = use_idx.variables();
38  if (dep_data.var_dep.isRecursive()) {
39  return Expression::generate(variable.name(), vars);
40  } else {
41  vector<string> exps = dep_data.var_dep.nMap().apply(vars);
42  return Expression::generate(variable.name(), exps);
43  }
44  assert(false);
45  return Expression::generate(variable.name(), vector<string>());
46 }
47 
48 bool findDep(DepsMap deps, DepData dep_data, bool multiple_nodes)
49 {
50  string var_name = dep_data.var_dep.var().name();
51  list<DepData> var_deps = deps[var_name];
52  for (DepData dep : var_deps) {
53  SB::Set dom = dep.var_dep.mapF().wholeDom();
54  SB::Set dep_eq_image = dep.var_dep.mapF().image(dom);
55  SB::Set new_dom = dep_data.var_dep.mapF().wholeDom();
56  SB::Set new_dep_eq_image = dep_data.var_dep.mapF().image(new_dom);
57  if ((dep.id == dep_data.id) && dep.var_dep.isRecursive() && dep_data.var_dep.isRecursive() && dep.var_dep.var().name() == var_name) {
58  return true;
59  }
60  if ((dep.id == dep_data.id) && (dep_eq_image == new_dep_eq_image) && (dep.var_dep.nMap() == dep_data.var_dep.nMap())) {
61  return true;
62  }
63  if (multiple_nodes) {
64  SB::Set dep_var_image = dep.var_dep.mapU().image(dom);
65  SB::Set new_dep_var_image = dep_data.var_dep.mapU().image(new_dom);
66  if ((dep.id == dep_data.id) && (dep_var_image == new_dep_var_image) && (dep.var_dep.nMap() == dep_data.var_dep.nMap())) {
67  return true;
68  }
69  }
70  }
71  return false;
72 }
73 
74 bool findAlgDep(PrintedDeps printed_deps, int id, SB::Set range, SB::Deps::LMapExp use_map, SB::Deps::LMapExp eq_use_map)
75 {
76  for (PrintedDep dep : printed_deps) {
77  if (dep.id == id && dep.range == range && dep.use_map == use_map) {
78  if (eq_use_map.constantExp()) {
79  return dep.eq_use_map == eq_use_map;
80  } else {
81  return true;
82  }
83  }
84  }
85  return false;
86 }
87 
88 bool checkAlgRecursiveDeps(Equation eq, AlgDepsMap alg_deps, AlgDepsMap deps)
89 {
90  AlgDeps algs = alg_deps[eq.id()];
91  bool recursive_deps = false;
92  for (DefAlgDepsUse alg : algs) {
93  recursive_deps = recursive_deps || checkAlgRecursiveDeps(alg.eq, deps, deps);
94  if (recursive_deps) {
95  return recursive_deps;
96  }
97  }
98  for (DefAlgDepsUse alg : algs) {
99  recursive_deps = recursive_deps || alg.recursive;
100  if (recursive_deps) {
101  return recursive_deps;
102  }
103  }
104  return recursive_deps;
105 }
106 string addAlgDeps(Equation eq, SB::Deps::LMapExp eq_use, AlgDepsMap alg_deps, AlgDepsMap deps, PrintedDeps& printed_deps,
107  bool comes_from_rec)
108 {
109  AlgDeps algs = alg_deps[eq.id()];
110  stringstream code;
111  for (DefAlgDepsUse alg : algs) {
112  code << addAlgDeps(alg.eq, alg.use_map, deps, deps, printed_deps, alg.recursive);
113  }
114  for (DefAlgDepsUse alg : algs) {
115  bool RECURSIVE = alg.recursive || comes_from_rec;
116  Index use(alg.exp);
117  vector<string> vars = use.variables();
118  SB::Set var_range = alg.use.image(alg.range);
119  Range range(var_range, alg.offset, vars);
121  Option<Equation> alg_eq = equations[alg.eq.id()];
122  assert(alg_eq);
123  Equation gen_eq = alg_eq.get();
124  SB::Deps::LMapExp eq_use_exp = eq_use;
125  if (!eq_use.constantExp()) {
126  eq_use_exp = eq_use.revert();
127  }
128  SB::Deps::LMapExp use_map = alg.use_map.compose(eq_use_exp);
129  if (!use_map.constantExp() && !alg.use_map.constantExp() && !alg.def_map.isEmpty()) {
130  use_map = alg.def_map.solve(use_map);
131  }
132  vector<string> exps = use_map.apply(vars);
133  if (findAlgDep(printed_deps, alg.eq.id(), var_range, use_map, eq_use)) {
134  continue;
135  }
136  PrintedDep printed_dep;
137  printed_dep.id = alg.eq.id();
138  printed_dep.range = var_range;
139  printed_dep.use_map = use_map;
140  printed_dep.eq_use_map = eq_use;
141  printed_deps.push_back(printed_dep);
142  Expression use_exp = Expression::generate(alg.exp.reference().get().name(), exps);
143  Index use_idx = Index(use_exp);
144  if (gen_eq.hasRange() && RECURSIVE) {
145  Range range = gen_eq.range().get();
146  range.update(gen_eq.LHSVariable()->offset());
147  code << range.print(true, true);
148  code << "_get" << gen_eq.LHSVariable().get() << "_idxs(" << range.getDimensionVarsString(true) << ");" << endl;
149  use_idx = Index(gen_eq.lhs());
150  }
151  FunctionPrinter printer;
152  if (use_idx.isConstant() && gen_eq.hasRange()) {
153  if (!gen_eq.range()->checkUsage(use_idx, gen_eq.index())) {
154  continue;
155  }
156  Equation a = gen_eq;
157  a.applyUsage(use_idx);
158  gen_eq = a;
159  }
160  code << printer.printAlgebraicGuards(gen_eq, use_idx);
161  code << TAB << gen_eq;
162  code << printer.endDimGuards(gen_eq.range());
163  if (gen_eq.hasRange() && RECURSIVE) {
164  code << TAB << gen_eq.range()->end() << endl;
165  }
166  }
167  return code.str();
168 }
169 
170 void insertAlg(AlgDepsMap& map, int id, DefAlgDepsUse new_dep)
171 {
172  AlgDeps algs = map[id];
173  algs.insert(new_dep);
174  map[id] = algs;
175 }
176 
177 bool checkEventRange(Index index, Range range)
178 {
179  vector<string> idx_vars = index.variables();
180  vector<string> range_vars = range.getIndexes();
181  for (string idx_var : idx_vars) {
182  bool found = false;
183  for (string range_var : range_vars) {
184  if (idx_var == range_var) {
185  found = true;
186  break;
187  }
188  }
189  if (!found) {
190  return false;
191  }
192  }
193  return true;
194 }
195 
196 vector<string> getVariables(Index index, Range range)
197 {
198  vector<string> index_vars = index.variables();
199  vector<string> ret_vars = range.getIndexes();
200  for (string idx_var : index_vars) {
201  ret_vars.push_back(idx_var);
202  }
203  sort(ret_vars.begin(), ret_vars.end());
204  ret_vars.erase(unique(ret_vars.begin(), ret_vars.end()), ret_vars.end());
205  return ret_vars;
206 }
207 
208 } // namespace IR
209 } // namespace MicroModelica
MicroModelica::IR::Range
Definition: index.hpp:164
MicroModelica::IR::DepData::var_dep
SB::Deps::VariableDep var_dep
Definition: compute_deps.hpp:153
MicroModelica::IR::addAlgDeps
string addAlgDeps(Equation eq, SB::Deps::LMapExp eq_use, AlgDepsMap alg_deps, AlgDepsMap deps, PrintedDeps &printed_deps, bool comes_from_rec)
Definition: compute_deps.cpp:123
MicroModelica::IR::findDep
bool findDep(DepsMap deps, DepData dep_data, bool multiple_nodes)
Definition: compute_deps.cpp:65
MicroModelica::IR::getUseExp
Expression getUseExp(Variable variable, DepData dep_data)
Definition: compute_deps.cpp:48
MicroModelica::IR::Equation::LHSVariable
Option< Util::Variable > LHSVariable() const
Definition: equation.cpp:165
MicroModelica::IR::DepsMap
std::map< std::string, DepsData > DepsMap
Definition: compute_deps.hpp:159
MicroModelica::IR::insertAlg
void insertAlg(AlgDepsMap &map, int id, DefAlgDepsUse new_dep)
Definition: compute_deps.cpp:187
MicroModelica::IR::EquationTable
ModelTable< int, Equation > EquationTable
Definition: equation.hpp:169
compute_deps.hpp
helpers.hpp
Option
Definition: util_types.hpp:32
MicroModelica::IR::Index::variables
std::vector< std::string > variables()
Definition: index.cpp:211
MicroModelica::IR::AlgDeps
set< DefAlgDepsUse, CompDef > AlgDeps
Definition: compute_deps.hpp:136
model_config.hpp
MicroModelica::IR::AlgDepsMap
std::map< int, AlgDeps > AlgDepsMap
Definition: compute_deps.hpp:138
MicroModelica::IR::checkEventRange
bool checkEventRange(Index index, Range range)
Definition: compute_deps.cpp:194
MicroModelica::IR::Expression::generate
static Expression generate(std::string var_name, std::vector< std::string > indices)
Definition: expression.cpp:162
MicroModelica::Util::ModelConfig::algebraics
IR::EquationTable algebraics()
Definition: model_config.hpp:96
MicroModelica::IR::Equation::lhs
Expression lhs() const
Definition: equation.hpp:78
MicroModelica::IR::PrintedDeps
list< PrintedDep > PrintedDeps
Definition: compute_deps.hpp:147
MicroModelica::IR::getVariables
vector< string > getVariables(Index index, Range range)
Definition: compute_deps.cpp:213
MicroModelica::IR::Equation
Definition: equation.hpp:67
MicroModelica::IR::Equation::range
Option< Range > range() const
Definition: equation.hpp:86
MicroModelica::IR::DefAlgDepsUse
Definition: compute_deps.hpp:67
TAB
#define TAB
Definition: util.hpp:79
MicroModelica::Util::ModelConfig::instance
static ModelConfig & instance()
Definition: model_config.hpp:87
MicroModelica::IR::Equation::id
int id() const
Definition: equation.hpp:88
MicroModelica::IR::Index
Definition: index.hpp:92
MicroModelica::Generator::MODEL_INSTANCE::Component::Deps
@ Deps
MicroModelica::IR::Equation::applyUsage
void applyUsage(Index usage)
Definition: equation.cpp:215
MicroModelica
Definition: files.cpp:45
MicroModelica::IR::DepData::id
int id
Definition: compute_deps.hpp:152
MicroModelica::IR::Equation::index
Index index() const
Definition: equation.cpp:191
MicroModelica::IR::Equation::hasRange
bool hasRange() const
Definition: equation.hpp:77
MicroModelica::IR::findAlgDep
bool findAlgDep(PrintedDeps printed_deps, int id, SB::Set range, SB::Deps::LMapExp use_map, SB::Deps::LMapExp eq_use_map)
Definition: compute_deps.cpp:91
MicroModelica::IR::DepData
Definition: compute_deps.hpp:149
MicroModelica::IR::checkAlgRecursiveDeps
bool checkAlgRecursiveDeps(Equation eq, AlgDepsMap alg_deps, AlgDepsMap deps)
Definition: compute_deps.cpp:105
MicroModelica::IR::Range::getIndexes
std::vector< std::string > getIndexes() const
Definition: index.cpp:622