Merge pull request 'Улучшение прохода MOVE_OPERATORS' (#85) from egormayorov into master
This commit was merged in pull request #85.
This commit is contained in:
@@ -1,7 +1,6 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <iostream>
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
@@ -192,6 +191,94 @@ static map<SgStatement*, set<SgStatement*>> analyzeBasicBlockIntraDependencies(c
|
|||||||
return normalizeSageString(raw ? string(raw) : string());
|
return normalizeSageString(raw ? string(raw) : string());
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function<string(SgExpression*)> canonicalExprKey;
|
||||||
|
canonicalExprKey = [&](SgExpression* expr) -> string
|
||||||
|
{
|
||||||
|
if (!expr)
|
||||||
|
return string();
|
||||||
|
|
||||||
|
const int v = expr->variant();
|
||||||
|
|
||||||
|
if (v == ADD_OP)
|
||||||
|
{
|
||||||
|
vector<string> terms;
|
||||||
|
function<void(SgExpression*)> flattenAdd = [&](SgExpression* e)
|
||||||
|
{
|
||||||
|
if (!e)
|
||||||
|
return;
|
||||||
|
if (e->variant() == ADD_OP)
|
||||||
|
{
|
||||||
|
flattenAdd(e->lhs());
|
||||||
|
flattenAdd(e->rhs());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
terms.push_back(canonicalExprKey(e));
|
||||||
|
};
|
||||||
|
flattenAdd(expr);
|
||||||
|
sort(terms.begin(), terms.end());
|
||||||
|
string joined;
|
||||||
|
for (size_t i = 0; i < terms.size(); ++i)
|
||||||
|
{
|
||||||
|
if (i)
|
||||||
|
joined += " + ";
|
||||||
|
joined += terms[i];
|
||||||
|
}
|
||||||
|
return joined;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (v == MULT_OP)
|
||||||
|
{
|
||||||
|
vector<string> factors;
|
||||||
|
function<void(SgExpression*)> flattenMult = [&](SgExpression* e)
|
||||||
|
{
|
||||||
|
if (!e)
|
||||||
|
return;
|
||||||
|
if (e->variant() == MULT_OP)
|
||||||
|
{
|
||||||
|
flattenMult(e->lhs());
|
||||||
|
flattenMult(e->rhs());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
factors.push_back(canonicalExprKey(e));
|
||||||
|
};
|
||||||
|
flattenMult(expr);
|
||||||
|
sort(factors.begin(), factors.end());
|
||||||
|
string joined;
|
||||||
|
for (size_t i = 0; i < factors.size(); ++i)
|
||||||
|
{
|
||||||
|
if (i)
|
||||||
|
joined += " * ";
|
||||||
|
joined += factors[i];
|
||||||
|
}
|
||||||
|
return joined;
|
||||||
|
}
|
||||||
|
|
||||||
|
SgExpression *l = expr->lhs();
|
||||||
|
SgExpression *r = expr->rhs();
|
||||||
|
|
||||||
|
if (l && r)
|
||||||
|
{
|
||||||
|
if (v == SUBT_OP || v == SUB_OP)
|
||||||
|
return canonicalExprKey(l) + string(" - ") + canonicalExprKey(r);
|
||||||
|
if (v == DIV_OP || v == INTEGER_DIV_OP)
|
||||||
|
return canonicalExprKey(l) + string(" / ") + canonicalExprKey(r);
|
||||||
|
if (v == EXP_OP)
|
||||||
|
return canonicalExprKey(l) + string(" ** ") + canonicalExprKey(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (l && !r)
|
||||||
|
{
|
||||||
|
if (v == MINUS_OP)
|
||||||
|
return string("-") + canonicalExprKey(l);
|
||||||
|
if (v == UNARY_ADD_OP)
|
||||||
|
return canonicalExprKey(l);
|
||||||
|
if (v == CAST_OP)
|
||||||
|
return canonicalExprKey(l);
|
||||||
|
}
|
||||||
|
|
||||||
|
return sageExprToString(expr);
|
||||||
|
};
|
||||||
|
|
||||||
auto arrayElementKey = [&](SgArrayRefExp* arrayRef) -> string
|
auto arrayElementKey = [&](SgArrayRefExp* arrayRef) -> string
|
||||||
{
|
{
|
||||||
if (!arrayRef)
|
if (!arrayRef)
|
||||||
@@ -212,7 +299,7 @@ static map<SgStatement*, set<SgStatement*>> analyzeBasicBlockIntraDependencies(c
|
|||||||
{
|
{
|
||||||
if (i)
|
if (i)
|
||||||
key += ", ";
|
key += ", ";
|
||||||
key += sageExprToString(arrayRef->subscript(i));
|
key += canonicalExprKey(arrayRef->subscript(i));
|
||||||
}
|
}
|
||||||
key += ")";
|
key += ")";
|
||||||
|
|
||||||
@@ -267,22 +354,6 @@ static map<SgStatement*, set<SgStatement*>> analyzeBasicBlockIntraDependencies(c
|
|||||||
collectUsedKeysFromExpression(arrayRef->subscript(i), usedKeys);
|
collectUsedKeysFromExpression(arrayRef->subscript(i), usedKeys);
|
||||||
};
|
};
|
||||||
|
|
||||||
auto addOperatorDependencies = [&](SgStatement* stmt,
|
|
||||||
const set<string>& usedKeys,
|
|
||||||
const map<string, SgStatement*>& varDeclarations,
|
|
||||||
map<SgStatement*, set<SgStatement*>>& operatorsDependencies)
|
|
||||||
{
|
|
||||||
if (!stmt)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (const string& key : usedKeys)
|
|
||||||
{
|
|
||||||
auto it = varDeclarations.find(key);
|
|
||||||
if (it != varDeclarations.end() && it->second && it->second != stmt)
|
|
||||||
operatorsDependencies[stmt].insert(it->second);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
auto declarationKeyFromLeftPart = [&](SgStatement* stmt) -> string
|
auto declarationKeyFromLeftPart = [&](SgStatement* stmt) -> string
|
||||||
{
|
{
|
||||||
if (!stmt || stmt->variant() != ASSIGN_STAT)
|
if (!stmt || stmt->variant() != ASSIGN_STAT)
|
||||||
@@ -305,6 +376,31 @@ static map<SgStatement*, set<SgStatement*>> analyzeBasicBlockIntraDependencies(c
|
|||||||
return string();
|
return string();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
auto addOperatorDependencies = [&](SgStatement* stmt,
|
||||||
|
const set<string>& usedKeys,
|
||||||
|
const map<string, SgStatement*>& varDeclarations,
|
||||||
|
const map<string, SgStatement*>& varUsages,
|
||||||
|
map<SgStatement*, set<SgStatement*>>& operatorsDependencies)
|
||||||
|
{
|
||||||
|
if (!stmt)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (const string& key : usedKeys)
|
||||||
|
{
|
||||||
|
auto it = varDeclarations.find(key);
|
||||||
|
if (it != varDeclarations.end() && it->second && it->second != stmt)
|
||||||
|
operatorsDependencies[stmt].insert(it->second);
|
||||||
|
}
|
||||||
|
|
||||||
|
const string defKey = declarationKeyFromLeftPart(stmt);
|
||||||
|
if (!defKey.empty())
|
||||||
|
{
|
||||||
|
auto itu = varUsages.find(defKey);
|
||||||
|
if (itu != varUsages.end() && itu->second && itu->second != stmt)
|
||||||
|
operatorsDependencies[stmt].insert(itu->second);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
vector<SgStatement*> operatorsOrder;
|
vector<SgStatement*> operatorsOrder;
|
||||||
set<SgStatement*> seenOperators;
|
set<SgStatement*> seenOperators;
|
||||||
|
|
||||||
@@ -323,6 +419,7 @@ static map<SgStatement*, set<SgStatement*>> analyzeBasicBlockIntraDependencies(c
|
|||||||
}
|
}
|
||||||
|
|
||||||
map<string, SgStatement*> varDeclarations;
|
map<string, SgStatement*> varDeclarations;
|
||||||
|
map<string, SgStatement*> varUsages;
|
||||||
map<SgStatement*, set<SgStatement*>> operatorsDependencies;
|
map<SgStatement*, set<SgStatement*>> operatorsDependencies;
|
||||||
|
|
||||||
for (SgStatement* stmt : operatorsOrder)
|
for (SgStatement* stmt : operatorsOrder)
|
||||||
@@ -333,11 +430,14 @@ static map<SgStatement*, set<SgStatement*>> analyzeBasicBlockIntraDependencies(c
|
|||||||
collectUsedKeysFromExpression(stmt->expr(1), usedKeys);
|
collectUsedKeysFromExpression(stmt->expr(1), usedKeys);
|
||||||
collectUsedKeysFromArraySubscripts(isSgArrayRefExp(stmt->expr(0)), usedKeys);
|
collectUsedKeysFromArraySubscripts(isSgArrayRefExp(stmt->expr(0)), usedKeys);
|
||||||
}
|
}
|
||||||
addOperatorDependencies(stmt, usedKeys, varDeclarations, operatorsDependencies);
|
addOperatorDependencies(stmt, usedKeys, varDeclarations, varUsages, operatorsDependencies);
|
||||||
|
|
||||||
const string declarationKey = declarationKeyFromLeftPart(stmt);
|
const string declarationKey = declarationKeyFromLeftPart(stmt);
|
||||||
if (!declarationKey.empty())
|
if (!declarationKey.empty())
|
||||||
varDeclarations[declarationKey] = stmt;
|
varDeclarations[declarationKey] = stmt;
|
||||||
|
|
||||||
|
for (const string& key : usedKeys)
|
||||||
|
varUsages[key] = stmt;
|
||||||
}
|
}
|
||||||
|
|
||||||
return operatorsDependencies;
|
return operatorsDependencies;
|
||||||
@@ -422,71 +522,53 @@ static bool reorderOperatorsInBasicBlockUsingDeps(
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
map<SgStatement*, int> originalIndex;
|
map<SgStatement*, int> newIndex;
|
||||||
|
map<SgStatement*, int> movesCount;
|
||||||
|
vector<SgStatement*> order = ops;
|
||||||
for (int i = 0; i < (int)ops.size(); ++i)
|
for (int i = 0; i < (int)ops.size(); ++i)
|
||||||
originalIndex[ops[i]] = i;
|
{
|
||||||
|
newIndex[ops[i]] = i;
|
||||||
map<SgStatement*, vector<SgStatement*>> moveAfter;
|
movesCount[ops[i]] = 0;
|
||||||
set<SgStatement*> moved;
|
}
|
||||||
|
|
||||||
for (SgStatement* st : ops)
|
for (SgStatement* st : ops)
|
||||||
{
|
{
|
||||||
auto itDeps = operatorsDependencies.find(st);
|
auto itDeps = operatorsDependencies.find(st);
|
||||||
if (itDeps == operatorsDependencies.end() || itDeps->second.empty())
|
if (itDeps != operatorsDependencies.end() && !itDeps->second.empty())
|
||||||
continue;
|
{
|
||||||
|
|
||||||
SgStatement* lastDep = nullptr;
|
SgStatement* lastDep = nullptr;
|
||||||
int lastDepIdx = -1;
|
int lastDepIdx = -1;
|
||||||
for (SgStatement* dep : itDeps->second)
|
for (SgStatement* dep : itDeps->second)
|
||||||
{
|
{
|
||||||
auto itIdx = originalIndex.find(dep);
|
auto itIdx = newIndex.find(dep);
|
||||||
if (itIdx != originalIndex.end() && itIdx->second > lastDepIdx)
|
if (itIdx != newIndex.end() && itIdx->second > lastDepIdx)
|
||||||
{
|
{
|
||||||
lastDep = dep;
|
lastDep = dep;
|
||||||
lastDepIdx = itIdx->second;
|
lastDepIdx = itIdx->second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!lastDep || lastDep == st)
|
if (lastDep && lastDep != st)
|
||||||
continue;
|
|
||||||
|
|
||||||
moveAfter[lastDep].push_back(st);
|
|
||||||
moved.insert(st);
|
|
||||||
}
|
|
||||||
|
|
||||||
vector<SgStatement*> order;
|
|
||||||
order.reserve(ops.size());
|
|
||||||
set<SgStatement*> emitted;
|
|
||||||
set<SgStatement*> active;
|
|
||||||
bool invalidOrder = false;
|
|
||||||
|
|
||||||
function<void(SgStatement*)> emitStatement = [&](SgStatement* st)
|
|
||||||
{
|
{
|
||||||
if (!st || invalidOrder || emitted.count(st))
|
const int stPos = newIndex[st];
|
||||||
return;
|
const int ldPos = newIndex[lastDep];
|
||||||
if (active.count(st))
|
if (stPos > ldPos)
|
||||||
{
|
{
|
||||||
invalidOrder = true;
|
auto itSt = find(order.begin(), order.end(), st);
|
||||||
return;
|
auto itLd = find(order.begin(), order.end(), lastDep);
|
||||||
}
|
if (itSt == order.end() || itLd == order.end())
|
||||||
|
|
||||||
active.insert(st);
|
|
||||||
emitted.insert(st);
|
|
||||||
order.push_back(st);
|
|
||||||
|
|
||||||
auto itMovedAfter = moveAfter.find(st);
|
|
||||||
if (itMovedAfter != moveAfter.end())
|
|
||||||
for (SgStatement* dependent : itMovedAfter->second)
|
|
||||||
emitStatement(dependent);
|
|
||||||
|
|
||||||
active.erase(st);
|
|
||||||
};
|
|
||||||
|
|
||||||
for (SgStatement* st : ops)
|
|
||||||
if (!moved.count(st))
|
|
||||||
emitStatement(st);
|
|
||||||
|
|
||||||
if (invalidOrder || order.size() != ops.size())
|
|
||||||
return false;
|
return false;
|
||||||
|
order.erase(itSt);
|
||||||
|
itLd = find(order.begin(), order.end(), lastDep);
|
||||||
|
if (itLd == order.end())
|
||||||
|
return false;
|
||||||
|
order.insert(itLd + 1 + movesCount[lastDep], st);
|
||||||
|
for (int i = 0; i < (int)order.size(); ++i)
|
||||||
|
newIndex[order[i]] = i;
|
||||||
|
movesCount[lastDep] += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
for (size_t i = 0; i < ops.size(); ++i)
|
for (size_t i = 0; i < ops.size(); ++i)
|
||||||
|
|||||||
Reference in New Issue
Block a user