|
|
|
|
@@ -17,7 +17,6 @@
|
|
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
set<int> loop_tags = {FOR_NODE};
|
|
|
|
|
set<int> control_tags = {IF_NODE, ELSEIF_NODE, DO_WHILE_NODE, WHILE_NODE, LOGIF_NODE};
|
|
|
|
|
set<int> control_end_tags = {CONTROL_END};
|
|
|
|
|
@@ -53,13 +52,25 @@ static vector<SAPFOR::IR_Block*> findInstructionsFromStatement(SgStatement* st,
|
|
|
|
|
|
|
|
|
|
vector<SAPFOR::BasicBlock*> findFuncBlocksByFuncStatement(SgStatement *st, const map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& FullIR) {
|
|
|
|
|
vector<SAPFOR::BasicBlock*> result;
|
|
|
|
|
if (!st)
|
|
|
|
|
return result;
|
|
|
|
|
|
|
|
|
|
Statement* forSt = (Statement*)st;
|
|
|
|
|
const string stmtFile = st->fileName();
|
|
|
|
|
const int stmtLine = st->lineNumber();
|
|
|
|
|
|
|
|
|
|
for (auto& func: FullIR) {
|
|
|
|
|
if (func.first->funcPointer->getCurrProcessFile() == forSt->getCurrProcessFile()
|
|
|
|
|
&& func.first->funcPointer->lineNumber() == forSt->lineNumber())
|
|
|
|
|
if (!func.first || !func.first->funcPointer)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
const string funcFile = func.first->fileName;
|
|
|
|
|
const int funcLine = func.first->funcPointer->lineNumber();
|
|
|
|
|
|
|
|
|
|
// Important: select CFG blocks only for the same file and function header.
|
|
|
|
|
if (funcFile == stmtFile && funcLine == stmtLine)
|
|
|
|
|
{
|
|
|
|
|
result = func.second;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
@@ -160,40 +171,60 @@ static map<SgStatement*, vector<SgStatement*>> analyzeBasicBlockIntraDependencie
|
|
|
|
|
if (!instr)
|
|
|
|
|
return string();
|
|
|
|
|
SgExpression* ex = instr->getExpression();
|
|
|
|
|
if (!ex || !ex->unparse())
|
|
|
|
|
if (!ex)
|
|
|
|
|
return string();
|
|
|
|
|
auto normalizeExprText = [](const string& raw) -> string
|
|
|
|
|
{
|
|
|
|
|
string t;
|
|
|
|
|
t.reserve(raw.size());
|
|
|
|
|
for (unsigned char c : raw)
|
|
|
|
|
if (!std::isspace(c))
|
|
|
|
|
t.push_back((char)c);
|
|
|
|
|
|
|
|
|
|
auto stripOneLayer = [](const string& x) -> string
|
|
|
|
|
auto exprKey = [&](auto&& self, SgExpression* e) -> string
|
|
|
|
|
{
|
|
|
|
|
if (!e)
|
|
|
|
|
return string("_");
|
|
|
|
|
|
|
|
|
|
if (auto* ar = isSgArrayRefExp(e))
|
|
|
|
|
{
|
|
|
|
|
if (x.size() < 2 || x.front() != '(' || x.back() != ')')
|
|
|
|
|
return x;
|
|
|
|
|
int bal = 0;
|
|
|
|
|
for (size_t i = 0; i + 1 < x.size(); ++i)
|
|
|
|
|
SgSymbol* sym = ar->symbol() ? OriginalSymbol(ar->symbol()) : nullptr;
|
|
|
|
|
string key = string("A(") + (sym ? sym->identifier() : "?");
|
|
|
|
|
const int n = ar->numberOfSubscripts();
|
|
|
|
|
for (int i = 0; i < n; ++i)
|
|
|
|
|
{
|
|
|
|
|
if (x[i] == '(') bal++;
|
|
|
|
|
else if (x[i] == ')') bal--;
|
|
|
|
|
if (bal == 0 && i + 1 < x.size() - 1)
|
|
|
|
|
return x;
|
|
|
|
|
key += ",";
|
|
|
|
|
key += self(self, ar->subscript(i));
|
|
|
|
|
}
|
|
|
|
|
return x.substr(1, x.size() - 2);
|
|
|
|
|
};
|
|
|
|
|
while (true)
|
|
|
|
|
{
|
|
|
|
|
const string stripped = stripOneLayer(t);
|
|
|
|
|
if (stripped == t)
|
|
|
|
|
break;
|
|
|
|
|
t = stripped;
|
|
|
|
|
key += ")";
|
|
|
|
|
return key;
|
|
|
|
|
}
|
|
|
|
|
return t;
|
|
|
|
|
|
|
|
|
|
if (e->variant() == VAR_REF || e->variant() == CONST_REF)
|
|
|
|
|
{
|
|
|
|
|
SgSymbol* sym = e->symbol() ? OriginalSymbol(e->symbol()) : nullptr;
|
|
|
|
|
return string((e->variant() == VAR_REF) ? "V(" : "C(") + (sym ? sym->identifier() : "?") + ")";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (auto* v = isSgValueExp(e))
|
|
|
|
|
{
|
|
|
|
|
if (e->variant() == INT_VAL)
|
|
|
|
|
return string("I(") + to_string(v->intValue()) + ")";
|
|
|
|
|
if (e->variant() == BOOL_VAL)
|
|
|
|
|
return string("B(") + (v->boolValue() ? "1" : "0") + ")";
|
|
|
|
|
if (e->variant() == CHAR_VAL)
|
|
|
|
|
return string("CH(") + string(1, v->charValue()) + ")";
|
|
|
|
|
if (e->variant() == FLOAT_VAL)
|
|
|
|
|
return string("F(") + (v->floatValue() ? v->floatValue() : "") + ")";
|
|
|
|
|
if (e->variant() == DOUBLE_VAL)
|
|
|
|
|
return string("D(") + (v->doubleValue() ? v->doubleValue() : "") + ")";
|
|
|
|
|
if (e->variant() == STRING_VAL)
|
|
|
|
|
return string("S(") + (v->stringValue() ? v->stringValue() : "") + ")";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
string key = string("N(") + to_string(e->variant());
|
|
|
|
|
if (e->lhs())
|
|
|
|
|
key += ",L=" + self(self, e->lhs());
|
|
|
|
|
if (e->rhs())
|
|
|
|
|
key += ",R=" + self(self, e->rhs());
|
|
|
|
|
key += ")";
|
|
|
|
|
return key;
|
|
|
|
|
};
|
|
|
|
|
return "MEMEX#" + normalizeExprText(ex->unparse());
|
|
|
|
|
|
|
|
|
|
return "MEMEX#" + exprKey(exprKey, ex);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
auto isBarrier = [&](const SAPFOR::Instruction* instr) -> bool
|
|
|
|
|
@@ -296,6 +327,9 @@ static map<SgStatement*, vector<SgStatement*>> analyzeBasicBlockIntraDependencie
|
|
|
|
|
|
|
|
|
|
addDep(instr->getArg1());
|
|
|
|
|
addDep(instr->getArg2());
|
|
|
|
|
if (instr->getOperation() == SAPFOR::CFG_OP::RANGE)
|
|
|
|
|
addDep(instr->getResult());
|
|
|
|
|
|
|
|
|
|
if (instr->getOperation() == SAPFOR::CFG_OP::STORE || instr->getOperation() == SAPFOR::CFG_OP::REC_REF_STORE)
|
|
|
|
|
addDep(instr->getResult());
|
|
|
|
|
|
|
|
|
|
@@ -343,7 +377,7 @@ static map<SgStatement*, vector<SgStatement*>> analyzeBasicBlockIntraDependencie
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool reorderOperatorsInBasicBlockUsingDeps(SAPFOR::BasicBlock* bb)
|
|
|
|
|
static bool reorderOperatorsInBasicBlockUsingDeps(SAPFOR::BasicBlock* bb, const char* expectedFile)
|
|
|
|
|
{
|
|
|
|
|
if (!bb)
|
|
|
|
|
return false;
|
|
|
|
|
@@ -373,6 +407,18 @@ static bool reorderOperatorsInBasicBlockUsingDeps(SAPFOR::BasicBlock* bb)
|
|
|
|
|
if (ops.size() < 2)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
// Check that analyzed BB is in the same file as the expected file
|
|
|
|
|
const char* bbFile = ops.front()->fileName();
|
|
|
|
|
if (!bbFile)
|
|
|
|
|
bbFile = "(unknown)";
|
|
|
|
|
if (expectedFile && strcmp(expectedFile, bbFile) != 0)
|
|
|
|
|
return false;
|
|
|
|
|
for (auto* st : ops)
|
|
|
|
|
{
|
|
|
|
|
if (!st || !st->fileName() || strcmp(st->fileName(), bbFile) != 0)
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SgStatement* parent = ops.front()->controlParent();
|
|
|
|
|
if (!parent)
|
|
|
|
|
return false;
|
|
|
|
|
@@ -424,60 +470,70 @@ static bool reorderOperatorsInBasicBlockUsingDeps(SAPFOR::BasicBlock* bb)
|
|
|
|
|
// as close as possible after its last dependency (if any).
|
|
|
|
|
const auto depsMap = analyzeBasicBlockIntraDependencies(bb);
|
|
|
|
|
vector<SgStatement*> order = ops;
|
|
|
|
|
const vector<SgStatement*> originalOrder = ops;
|
|
|
|
|
const int nOrig = (int)originalOrder.size();
|
|
|
|
|
|
|
|
|
|
auto buildPos = [&](const vector<SgStatement*>& v)
|
|
|
|
|
auto indexIn = [](const vector<SgStatement*>& v, SgStatement* s) -> int
|
|
|
|
|
{
|
|
|
|
|
map<SgStatement*, int> pos;
|
|
|
|
|
for (int i = 0; i < (int)v.size(); ++i)
|
|
|
|
|
pos[v[i]] = i;
|
|
|
|
|
return pos;
|
|
|
|
|
if (v[i] == s)
|
|
|
|
|
return i;
|
|
|
|
|
return -1;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const int maxIterations = (int)order.size() * (int)order.size() + 10;
|
|
|
|
|
bool anyMove = false;
|
|
|
|
|
for (int iter = 0; iter < maxIterations; ++iter)
|
|
|
|
|
auto indexInOriginal = [&](SgStatement* s) -> int
|
|
|
|
|
{
|
|
|
|
|
bool movedThisIter = false;
|
|
|
|
|
const auto pos = buildPos(order);
|
|
|
|
|
return indexIn(originalOrder, s);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < (int)order.size(); ++i)
|
|
|
|
|
for (SgStatement* s : ops)
|
|
|
|
|
{
|
|
|
|
|
auto itDeps = depsMap.find(s);
|
|
|
|
|
if (itDeps == depsMap.end() || itDeps->second.empty())
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
int lastDepOrigIdx = -1;
|
|
|
|
|
for (SgStatement* dep : itDeps->second)
|
|
|
|
|
{
|
|
|
|
|
SgStatement* curSt = order[i];
|
|
|
|
|
auto it = depsMap.find(curSt);
|
|
|
|
|
if (it == depsMap.end() || it->second.empty())
|
|
|
|
|
const int j = indexInOriginal(dep);
|
|
|
|
|
if (j >= 0)
|
|
|
|
|
lastDepOrigIdx = max(lastDepOrigIdx, j);
|
|
|
|
|
}
|
|
|
|
|
if (lastDepOrigIdx < 0)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
SgStatement* successor = nullptr;
|
|
|
|
|
if (lastDepOrigIdx + 1 < nOrig)
|
|
|
|
|
successor = originalOrder[lastDepOrigIdx + 1];
|
|
|
|
|
|
|
|
|
|
int posS = indexIn(order, s);
|
|
|
|
|
if (posS < 0)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if (successor == nullptr)
|
|
|
|
|
{
|
|
|
|
|
if (posS == (int)order.size() - 1)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
int lastDepIdx = -1;
|
|
|
|
|
for (SgStatement* dep : it->second)
|
|
|
|
|
{
|
|
|
|
|
auto itP = pos.find(dep);
|
|
|
|
|
if (itP != pos.end())
|
|
|
|
|
lastDepIdx = max(lastDepIdx, itP->second);
|
|
|
|
|
}
|
|
|
|
|
if (lastDepIdx < 0)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
int target = lastDepIdx + 1;
|
|
|
|
|
if (target == i)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
SgStatement* moved = order[i];
|
|
|
|
|
order.erase(order.begin() + i);
|
|
|
|
|
if (target > i)
|
|
|
|
|
target -= 1;
|
|
|
|
|
if (target < 0)
|
|
|
|
|
target = 0;
|
|
|
|
|
if (target > (int)order.size())
|
|
|
|
|
target = (int)order.size();
|
|
|
|
|
order.insert(order.begin() + target, moved);
|
|
|
|
|
|
|
|
|
|
movedThisIter = true;
|
|
|
|
|
anyMove = true;
|
|
|
|
|
break;
|
|
|
|
|
order.erase(order.begin() + posS);
|
|
|
|
|
order.push_back(s);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!movedThisIter)
|
|
|
|
|
break;
|
|
|
|
|
if (successor == s)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
const int posSucc = indexIn(order, successor);
|
|
|
|
|
if (posSucc < 0)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if (posS + 1 == posSucc)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
order.erase(order.begin() + posS);
|
|
|
|
|
const int posSucc2 = indexIn(order, successor);
|
|
|
|
|
if (posSucc2 < 0)
|
|
|
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
order.insert(order.begin() + posSucc2, s);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool changed = false;
|
|
|
|
|
@@ -548,15 +604,14 @@ static bool reorderOperatorsInBasicBlockUsingDeps(SAPFOR::BasicBlock* bb)
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void moveOperators(SgFile *file, map<string, vector<LoopGraph*>>& loopGraph,
|
|
|
|
|
const map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& FullIR,
|
|
|
|
|
int& countOfTransform) {
|
|
|
|
|
void moveOperators(SgFile* file, const map<FuncInfo*, vector<SAPFOR::BasicBlock*>>& FullIR, int& countOfTransform) {
|
|
|
|
|
if (!file)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (SgFile::switchToFile(file->filename()) == -1)
|
|
|
|
|
printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
|
|
|
|
|
const int funcNum = file->numberOfFunctions();
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < funcNum; ++i) {
|
|
|
|
|
for (int i = 0; i < funcNum; ++i)
|
|
|
|
|
{
|
|
|
|
|
SgStatement* st = file->functions(i);
|
|
|
|
|
|
|
|
|
|
const auto loopBlocks = findBlocksInLoopsByFullIR(st, FullIR);
|
|
|
|
|
@@ -564,7 +619,7 @@ void moveOperators(SgFile *file, map<string, vector<LoopGraph*>>& loopGraph,
|
|
|
|
|
{
|
|
|
|
|
if (!bb)
|
|
|
|
|
continue;
|
|
|
|
|
if (reorderOperatorsInBasicBlockUsingDeps(bb))
|
|
|
|
|
if (reorderOperatorsInBasicBlockUsingDeps(bb, file->filename()))
|
|
|
|
|
countOfTransform += 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|