summaryrefslogtreecommitdiff
path: root/clang/lib/Analysis/Interval.cpp
diff options
context:
space:
mode:
authorZancanaro; Carlo <czan8762@plang3.cs.usyd.edu.au>2012-11-08 19:37:59 +1100
committerZancanaro; Carlo <czan8762@plang3.cs.usyd.edu.au>2012-11-08 19:37:59 +1100
commit1e907d883191571b5c374fd1c3b2f6c1fe11da83 (patch)
tree8faa72279b2ac8221b683f489840e89001494b04 /clang/lib/Analysis/Interval.cpp
parent6a15c4a790d35d1468f31209267be22ab437742a (diff)
A few fixes to the MCF solver, and equation stuff
General work on the equation systems. Trying to get them to generate correctly with the MCF stuff. It's harder than it seems!
Diffstat (limited to 'clang/lib/Analysis/Interval.cpp')
-rw-r--r--clang/lib/Analysis/Interval.cpp163
1 files changed, 136 insertions, 27 deletions
diff --git a/clang/lib/Analysis/Interval.cpp b/clang/lib/Analysis/Interval.cpp
index 7096d75..e643f5e 100644
--- a/clang/lib/Analysis/Interval.cpp
+++ b/clang/lib/Analysis/Interval.cpp
@@ -8,6 +8,8 @@
#include "clang/Analysis/Analyses/IntervalSolver/Complete.hpp"
#include "clang/Analysis/Analyses/IntervalSolver/VariableAssignment.hpp"
#include "clang/Analysis/Analyses/IntervalSolver/EquationSystem.hpp"
+
+#include "MCFSimplex.h"
#include "llvm/ADT/PostOrderIterator.h"
#include "llvm/ADT/DenseMap.h"
@@ -41,6 +43,11 @@ std::ostream& operator<<(std::ostream& cout, const std::pair<K,V>& v) {
cout << "(" << v.first << ", " << v.second << ")";
return cout;
}
+template<typename V>
+std::ostream& operator<<(std::ostream& cout, const std::pair<Variable<Complete<int64_t> >*, V>& v) {
+ cout << "(" << v.first->name() << ", " << v.second << ")";
+ return cout;
+}
template<typename V>
std::ostream& operator<<(std::ostream& cout, const std::vector<V>& v) {
@@ -485,6 +492,86 @@ Condition fromComparison(const BinaryOperator* op, bool negate) {
return cond;
}
+
+struct MinCostFlow : public Operator<ZBar> {
+ MinCostFlow(const std::vector<std::pair<EqnVar*, ZBar> >& supplies)
+ : solver(0, 0) {
+ assert(supplies.size() % 2 == 0);
+
+ if (supplies.size() == 0)
+ return;
+
+ MCFClass::FNumber* deficits = new MCFClass::FNumber[supplies.size()];
+ MCFClass::Index* starts = new MCFClass::Index[supplies.size()];
+ MCFClass::Index* ends = new MCFClass::Index[supplies.size()];
+
+ for (int i = 0, size = supplies.size(); i < size; i += 2) {
+ deficits[i] = -supplies[i].second.as<MCFClass::FNumber>();
+ deficits[i+1] = -supplies[i+1].second.as<MCFClass::FNumber>();
+
+ starts[i] = i+1;
+ ends[i] = i+2;
+
+ starts[i+1] = i+2;
+ ends[i+1] = i+1;
+
+ printableSupply.push_back(supplies[i].second);
+ printableSupply.push_back(supplies[i+1].second);
+ }
+
+ solver.LoadNet(supplies.size(), supplies.size(), // max nodes/arcs
+ supplies.size(), supplies.size(), // current nodes/arcs
+ NULL, NULL, // arcs have inf cap, zero cost (to begin)
+ deficits, // deficits for each node
+ starts, ends); // start/end of each edge
+
+ delete[] deficits;
+ delete[] starts;
+ delete[] ends;
+ }
+
+ ZBar eval(const std::vector<ZBar>& args) const {
+ if (args.size() == 0)
+ return 0;
+ for (int i = 0, size = args.size(); i < size; ++i) {
+ //if (args[i] == infinity<ZBar>()) {
+ // if (!solver.IsClosedArc(i))
+ // solver.CloseArc(i);
+ //} else {
+ // if (solver.IsClosedArc(i))
+ // solver.OpenArc(i);
+ solver.ChgCost(i, args[i].as<MCFClass::CNumber>());
+ //}
+ }
+ std::cerr << "MCF" << this << "<" << printableSupply << ">(" << args << ")" << " = ";
+ solver.SolveMCF();
+ if (solver.MCFGetStatus() == MCFClass::kUnfeasible){
+ std::cerr << -infinity<ZBar>() << std::endl;
+ return -infinity<ZBar>();
+ } else {
+ if (solver.MCFGetFO() == MCFClass::Inf<MCFClass::FONumber>()) {
+ std::cerr << infinity<ZBar>() << std::endl;
+ return infinity<ZBar>();
+ } else if (solver.MCFGetFO() == -MCFClass::Inf<MCFClass::FONumber>()) {
+ std::cerr << -infinity<ZBar>() << std::endl;
+ return -infinity<ZBar>();
+ } else {
+ ZBar result = solver.MCFGetFO();
+ std::cerr << result << std::endl;
+ return result;
+ }
+ }
+ }
+
+ virtual void print(std::ostream& cout) const {
+ cout << "MCF" << this << "<" << printableSupply << ">";
+ }
+
+ mutable MCFSimplex solver;
+ std::vector<ZBar> printableSupply;
+};
+
+
/* Blocks */
typedef std::map<std::string, unsigned int> Counters;
@@ -551,28 +638,41 @@ void runOnBlock(const CFGBlock* block, EqnSys& system, BlockVars& block_vars) {
if (negative) {
result = negate_result(result);
}
- EqnExpr* expression = &system.constant(result.second);
- for (Vector::iterator it = result.first.begin(),
- ei = result.first.end();
- it != ei;
- ++it) {
- if (!vars[it->first])
- vars[it->first] = &system.variable(it->first + '-' + block_id + "-pre");
- std::vector<EqnExpr*> additionArgs;
- additionArgs.push_back(expression);
-
- if (it->second == 1) {
- additionArgs.push_back(vars[it->first]);
- } else {
- std::vector<EqnExpr*> multiplicationArgs;
- multiplicationArgs.push_back(vars[it->first]);
- multiplicationArgs.push_back(&system.constant(it->second));
- additionArgs.push_back(&system.expression(new Multiplication<ZBar>(), multiplicationArgs));
- }
- expression = &system.expression(new Addition<ZBar>(), additionArgs);
+ EqnExpr* expression;
+
+ if (result.first.size() > 0) {
+ // set up the min-cost stuff
+ std::vector<EqnExpr*> minCostArgs;
+ std::vector<std::pair<EqnVar*, ZBar> > varCosts;
+ for (Vector::iterator it = result.first.begin(),
+ ei = result.first.end();
+ it != ei;
+ ++it) {
+ if (!vars[it->first])
+ vars[it->first] = &system.variable(it->first + '-' + block_id + "-pre");
+
+ EqnVar& var = *vars[it->first];
+ EqnVar& negVar = *vars[negate_string(it->first)];
+
+ varCosts.push_back(std::pair<EqnVar*, ZBar>(&var, it->second));
+ varCosts.push_back(std::pair<EqnVar*, ZBar>(&negVar, -it->second));
+
+ minCostArgs.push_back(&var);
+ minCostArgs.push_back(&negVar);
+ }
+ EqnExpr* minCostExpr = &system.expression(new MinCostFlow(varCosts), minCostArgs);
+
+ // add the constant factor to the min-cost bit
+ std::vector<EqnExpr*> additionArgs;
+ additionArgs.push_back(&system.constant(result.second));
+ additionArgs.push_back(minCostExpr);
+ expression = &system.expression(new Addition<ZBar>(), additionArgs);
+ } else {
+ expression = &system.constant(result.second);
}
-
+
+ // max(-inf, expr), so strategy iteration will work
std::vector<EqnExpr*> maxArgs;
maxArgs.push_back(&system.constant(-infinity<ZBar>()));
maxArgs.push_back(expression);
@@ -612,6 +712,7 @@ void runOnBlock(const CFGBlock* block, EqnSys& system, BlockVars& block_vars) {
EqnExpr* expr = NULL;
if (val == -infinity<ZBar>()) {
// don't do anything here: min(-inf, x) = -inf (for all x)
+ expr = &system.constant(-infinity<ZBar>());
} else if (val == infinity<ZBar>()) {
// no need to have a min here: min(inf, x) = x (for all x)
expr = jt->second;
@@ -623,7 +724,9 @@ void runOnBlock(const CFGBlock* block, EqnSys& system, BlockVars& block_vars) {
expr = &system.expression(new Minimum<ZBar>(), minArgs);
}
- if (expr) {
+ system[*var]->arguments().push_back(expr);
+
+ /*if (expr) {
std::set<std::string> ignore;
for (VarMap::iterator
variables = vars.begin(),
@@ -638,10 +741,13 @@ void runOnBlock(const CFGBlock* block, EqnSys& system, BlockVars& block_vars) {
for (int negate = 0; negate < 2; ++negate) {
std::string var_name = negate ? negate_string(variables->first) : variables->first;
if (cond[var_name] == infinity<ZBar>()) {
+ // min(x, inf) = x
plusArgs.push_back(vars[var_name]);
} else if (cond[var_name] == -infinity<ZBar>()) {
+ // min(x, -inf) = -inf
plusArgs.push_back(&system.constant(-infinity<ZBar>()));
} else {
+ // min(x, y) = ?
std::vector<EqnExpr*> minArgs;
minArgs.push_back(vars[var_name]);
minArgs.push_back(&system.constant(cond[var_name]));
@@ -656,7 +762,7 @@ void runOnBlock(const CFGBlock* block, EqnSys& system, BlockVars& block_vars) {
expr = &system.expression(new Guard<ZBar>(), guard_args);
}
system[*var]->arguments().push_back(expr);
- }
+ }*/
}
}
}
@@ -683,6 +789,7 @@ void IntervalAnalysis::runOnAllBlocks(const Decl& decl) {
BlockVars block_vars;
std::vector<EqnExpr*> infArg;
+ infArg.push_back(&system.constant(-infinity<ZBar>())); // left-most argument has to be -infinity
infArg.push_back(&system.constant(infinity<ZBar>()));
std::set<std::string>& function_arguments = block_vars[&cfg->getEntry()];
std::string block_id = toString(cfg->getEntry().getBlockID());
@@ -690,11 +797,13 @@ void IntervalAnalysis::runOnAllBlocks(const Decl& decl) {
for (unsigned int i = func->getNumParams(); i > 0; i--) {
std::string name = func->getParamDecl(i-1)->getNameAsString();
- function_arguments.insert(name); // add it to the first block's vars
- function_arguments.insert(negate_string(name)); // add it to the first block's vars
-
- system[system.variable(name + '-' + block_id + "-pre")] = &system.maxExpression(infArg); // set the vars to infinity in the system here
- system[system.variable(negate_string(name) + '-' + block_id + "-pre")] = &system.maxExpression(infArg); // set the vars to infinity in the system here
+ // add the variables to the first block
+ function_arguments.insert(name);
+ function_arguments.insert(negate_string(name));
+
+ // set the vars to infinity (unconstrained)
+ system[system.variable(name + '-' + block_id + "-pre")] = &system.maxExpression(infArg);
+ system[system.variable(negate_string(name) + '-' + block_id + "-pre")] = &system.maxExpression(infArg);
}
}