fix freezing
This commit is contained in:
@@ -808,6 +808,47 @@ static map<SgStatement*, vector<SgStatement*>> analyzeBasicBlockIntraDependencie
|
|||||||
return to_string((int)a->getType()) + "#" + to_string((int)a->getMemType()) + "#" + a->getValue();
|
return to_string((int)a->getType()) + "#" + to_string((int)a->getMemType()) + "#" + a->getValue();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
auto memKeyFromInstr = [&](const SAPFOR::Instruction* instr) -> string
|
||||||
|
{
|
||||||
|
if (!instr)
|
||||||
|
return string();
|
||||||
|
SgExpression* ex = instr->getExpression();
|
||||||
|
if (!ex || !ex->unparse())
|
||||||
|
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
|
||||||
|
{
|
||||||
|
if (x.size() < 2 || x.front() != '(' || x.back() != ')')
|
||||||
|
return x;
|
||||||
|
int bal = 0;
|
||||||
|
for (size_t i = 0; i + 1 < x.size(); ++i)
|
||||||
|
{
|
||||||
|
if (x[i] == '(') bal++;
|
||||||
|
else if (x[i] == ')') bal--;
|
||||||
|
if (bal == 0 && i + 1 < x.size() - 1)
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
return x.substr(1, x.size() - 2);
|
||||||
|
};
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
const string stripped = stripOneLayer(t);
|
||||||
|
if (stripped == t)
|
||||||
|
break;
|
||||||
|
t = stripped;
|
||||||
|
}
|
||||||
|
return t;
|
||||||
|
};
|
||||||
|
return "MEMEX#" + normalizeExprText(ex->unparse());
|
||||||
|
};
|
||||||
|
|
||||||
auto isBarrier = [&](const SAPFOR::Instruction* instr) -> bool
|
auto isBarrier = [&](const SAPFOR::Instruction* instr) -> bool
|
||||||
{
|
{
|
||||||
if (!instr)
|
if (!instr)
|
||||||
@@ -816,8 +857,6 @@ static map<SgStatement*, vector<SgStatement*>> analyzeBasicBlockIntraDependencie
|
|||||||
switch (op)
|
switch (op)
|
||||||
{
|
{
|
||||||
case SAPFOR::CFG_OP::F_CALL:
|
case SAPFOR::CFG_OP::F_CALL:
|
||||||
case SAPFOR::CFG_OP::STORE:
|
|
||||||
case SAPFOR::CFG_OP::REC_REF_STORE:
|
|
||||||
case SAPFOR::CFG_OP::IO_PARAM:
|
case SAPFOR::CFG_OP::IO_PARAM:
|
||||||
case SAPFOR::CFG_OP::DVM_DIR:
|
case SAPFOR::CFG_OP::DVM_DIR:
|
||||||
case SAPFOR::CFG_OP::SPF_DIR:
|
case SAPFOR::CFG_OP::SPF_DIR:
|
||||||
@@ -847,6 +886,7 @@ static map<SgStatement*, vector<SgStatement*>> analyzeBasicBlockIntraDependencie
|
|||||||
// Reaching definitions inside the BasicBlock in straight-line order:
|
// Reaching definitions inside the BasicBlock in straight-line order:
|
||||||
// lastDef[var] = last operator in this block that defined it.
|
// lastDef[var] = last operator in this block that defined it.
|
||||||
map<string, pair<SgStatement*, const SAPFOR::Argument*>> lastDef;
|
map<string, pair<SgStatement*, const SAPFOR::Argument*>> lastDef;
|
||||||
|
map<string, pair<SgStatement*, const SAPFOR::Argument*>> lastMemDef;
|
||||||
map<SgStatement*, set<SgStatement*>> depsSets;
|
map<SgStatement*, set<SgStatement*>> depsSets;
|
||||||
|
|
||||||
for (auto* ir : bb->getInstructions())
|
for (auto* ir : bb->getInstructions())
|
||||||
@@ -856,7 +896,9 @@ static map<SgStatement*, vector<SgStatement*>> analyzeBasicBlockIntraDependencie
|
|||||||
|
|
||||||
const SAPFOR::Instruction* instr = ir->getInstruction();
|
const SAPFOR::Instruction* instr = ir->getInstruction();
|
||||||
SgStatement* opStmt = instr->getOperator();
|
SgStatement* opStmt = instr->getOperator();
|
||||||
if (!opStmt || isCompoundStmt(opStmt))
|
if (!opStmt)
|
||||||
|
continue;
|
||||||
|
if (isCompoundStmt(opStmt))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (isBarrier(instr))
|
if (isBarrier(instr))
|
||||||
@@ -869,6 +911,14 @@ static map<SgStatement*, vector<SgStatement*>> analyzeBasicBlockIntraDependencie
|
|||||||
else
|
else
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
|
for (auto it = lastMemDef.begin(); it != lastMemDef.end();)
|
||||||
|
{
|
||||||
|
const SAPFOR::Argument* a = it->second.second;
|
||||||
|
if (!a || a->isMemGlobal() || a->isParameter())
|
||||||
|
it = lastMemDef.erase(it);
|
||||||
|
else
|
||||||
|
++it;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!result.count(opStmt))
|
if (!result.count(opStmt))
|
||||||
@@ -878,18 +928,50 @@ static map<SgStatement*, vector<SgStatement*>> analyzeBasicBlockIntraDependencie
|
|||||||
{
|
{
|
||||||
if (!isTrackable(use))
|
if (!isTrackable(use))
|
||||||
return;
|
return;
|
||||||
auto it = lastDef.find(argKey(use));
|
const string k = argKey(use);
|
||||||
|
auto it = lastDef.find(k);
|
||||||
if (it == lastDef.end())
|
if (it == lastDef.end())
|
||||||
return; // only deps inside this BB are needed
|
return;
|
||||||
|
if (it->second.first && it->second.first != opStmt)
|
||||||
|
depsSets[opStmt].insert(it->second.first);
|
||||||
|
};
|
||||||
|
|
||||||
|
auto addMemDep = [&](const string& key)
|
||||||
|
{
|
||||||
|
if (key.empty())
|
||||||
|
return;
|
||||||
|
auto it = lastMemDef.find(key);
|
||||||
|
if (it == lastMemDef.end())
|
||||||
|
return;
|
||||||
if (it->second.first && it->second.first != opStmt)
|
if (it->second.first && it->second.first != opStmt)
|
||||||
depsSets[opStmt].insert(it->second.first);
|
depsSets[opStmt].insert(it->second.first);
|
||||||
};
|
};
|
||||||
|
|
||||||
addDep(instr->getArg1());
|
addDep(instr->getArg1());
|
||||||
addDep(instr->getArg2());
|
addDep(instr->getArg2());
|
||||||
|
if (instr->getOperation() == SAPFOR::CFG_OP::STORE || instr->getOperation() == SAPFOR::CFG_OP::REC_REF_STORE)
|
||||||
|
addDep(instr->getResult());
|
||||||
|
|
||||||
|
if (instr->getOperation() == SAPFOR::CFG_OP::LOAD || instr->getOperation() == SAPFOR::CFG_OP::REC_REF_LOAD)
|
||||||
|
{
|
||||||
|
const string memKey = memKeyFromInstr(instr);
|
||||||
|
addMemDep(memKey);
|
||||||
|
}
|
||||||
|
|
||||||
if (isDef(instr))
|
if (isDef(instr))
|
||||||
lastDef[argKey(instr->getResult())] = { opStmt, instr->getResult() };
|
{
|
||||||
|
const string dk = argKey(instr->getResult());
|
||||||
|
lastDef[dk] = { opStmt, instr->getResult() };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (instr->getOperation() == SAPFOR::CFG_OP::STORE || instr->getOperation() == SAPFOR::CFG_OP::REC_REF_STORE)
|
||||||
|
{
|
||||||
|
const string k = memKeyFromInstr(instr);
|
||||||
|
SAPFOR::Argument* base = instr->getArg1();
|
||||||
|
if (!k.empty() && base)
|
||||||
|
lastMemDef[k] = { opStmt, base };
|
||||||
|
addMemDep(k);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& kv : result)
|
for (auto& kv : result)
|
||||||
@@ -961,8 +1043,11 @@ static bool reorderOperatorsInBasicBlockUsingDeps(SAPFOR::BasicBlock* bb)
|
|||||||
SgStatement* scan = parent->lexNext();
|
SgStatement* scan = parent->lexNext();
|
||||||
SgStatement* end = lastNode;
|
SgStatement* end = lastNode;
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
set<SgStatement*> visited;
|
||||||
while (scan && scan != end)
|
while (scan && scan != end)
|
||||||
{
|
{
|
||||||
|
if (!visited.insert(scan).second)
|
||||||
|
return false;
|
||||||
if (scan == ops.front())
|
if (scan == ops.front())
|
||||||
{
|
{
|
||||||
found = true;
|
found = true;
|
||||||
@@ -977,14 +1062,9 @@ static bool reorderOperatorsInBasicBlockUsingDeps(SAPFOR::BasicBlock* bb)
|
|||||||
while (cur && cur != lastNode && idx < ops.size())
|
while (cur && cur != lastNode && idx < ops.size())
|
||||||
{
|
{
|
||||||
if (cur == ops[idx])
|
if (cur == ops[idx])
|
||||||
{
|
|
||||||
++idx;
|
++idx;
|
||||||
}
|
else if (isSgExecutableStatement(cur) && !opSet.count(cur))
|
||||||
else
|
return false;
|
||||||
{
|
|
||||||
if (isSgExecutableStatement(cur) && !opSet.count(cur))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (idx == ops.size())
|
if (idx == ops.size())
|
||||||
break;
|
break;
|
||||||
cur = cur->lexNext();
|
cur = cur->lexNext();
|
||||||
@@ -998,50 +1078,59 @@ static bool reorderOperatorsInBasicBlockUsingDeps(SAPFOR::BasicBlock* bb)
|
|||||||
const auto depsMap = analyzeBasicBlockIntraDependencies(bb);
|
const auto depsMap = analyzeBasicBlockIntraDependencies(bb);
|
||||||
vector<SgStatement*> order = ops;
|
vector<SgStatement*> order = ops;
|
||||||
|
|
||||||
map<SgStatement*, int> pos;
|
auto buildPos = [&](const vector<SgStatement*>& v)
|
||||||
for (int i = 0; i < (int)order.size(); ++i)
|
|
||||||
pos[order[i]] = i;
|
|
||||||
|
|
||||||
for (int i = 0; i < (int)order.size(); ++i)
|
|
||||||
{
|
{
|
||||||
SgStatement* cur = order[i];
|
map<SgStatement*, int> pos;
|
||||||
auto it = depsMap.find(cur);
|
for (int i = 0; i < (int)v.size(); ++i)
|
||||||
if (it == depsMap.end() || it->second.empty())
|
pos[v[i]] = i;
|
||||||
continue;
|
return pos;
|
||||||
|
};
|
||||||
|
|
||||||
int lastDepIdx = -1;
|
const int maxIterations = (int)order.size() * (int)order.size() + 10;
|
||||||
for (SgStatement* dep : it->second)
|
bool anyMove = false;
|
||||||
|
for (int iter = 0; iter < maxIterations; ++iter)
|
||||||
|
{
|
||||||
|
bool movedThisIter = false;
|
||||||
|
const auto pos = buildPos(order);
|
||||||
|
|
||||||
|
for (int i = 0; i < (int)order.size(); ++i)
|
||||||
{
|
{
|
||||||
auto itP = pos.find(dep);
|
SgStatement* curSt = order[i];
|
||||||
if (itP != pos.end())
|
auto it = depsMap.find(curSt);
|
||||||
lastDepIdx = max(lastDepIdx, itP->second);
|
if (it == depsMap.end() || it->second.empty())
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lastDepIdx < 0)
|
if (!movedThisIter)
|
||||||
continue;
|
break;
|
||||||
|
|
||||||
const int target = lastDepIdx + 1;
|
|
||||||
if (target == i)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
SgStatement* moved = order[i];
|
|
||||||
order.erase(order.begin() + i);
|
|
||||||
|
|
||||||
int insertIdx = target;
|
|
||||||
if (target > i)
|
|
||||||
insertIdx = target - 1;
|
|
||||||
if (insertIdx < 0)
|
|
||||||
insertIdx = 0;
|
|
||||||
if (insertIdx > (int)order.size())
|
|
||||||
insertIdx = (int)order.size();
|
|
||||||
|
|
||||||
order.insert(order.begin() + insertIdx, moved);
|
|
||||||
|
|
||||||
pos.clear();
|
|
||||||
for (int k = 0; k < (int)order.size(); ++k)
|
|
||||||
pos[order[k]] = k;
|
|
||||||
|
|
||||||
i = max(-1, min(i, insertIdx) - 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
|
|||||||
Reference in New Issue
Block a user