diff --git a/src/Transformations/MoveOperators/move_operators.cpp b/src/Transformations/MoveOperators/move_operators.cpp index bc9b1e5..234c3c0 100644 --- a/src/Transformations/MoveOperators/move_operators.cpp +++ b/src/Transformations/MoveOperators/move_operators.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include "../../Utils/errors.h" #include "../../Utils/SgUtils.h" @@ -20,254 +21,124 @@ using namespace std; -set loop_tags = {FOR_NODE}; +set loop_tags = {FOR_NODE, WHILE_NODE, DO_WHILE_NODE}; set control_tags = {IF_NODE, ELSEIF_NODE, DO_WHILE_NODE, WHILE_NODE, LOGIF_NODE}; set control_end_tags = {CONTROL_END}; -namespace + +static bool isParentStmt(SgStatement* stmt, SgStatement* parent) { -enum class ArrayIndexCompareResult -{ - Equal, - NotEqual, - Unknown -}; - -// Structural key for array index / subscript analysis (stable across LOAD/STORE of the same access). -string buildStructuralExprKey(SgExpression* e) -{ - if (!e) - return string("_"); - - if (auto* ar = isSgArrayRefExp(e)) - { - 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) - { - key += ","; - key += buildStructuralExprKey(ar->subscript(i)); - } - key += ")"; - return key; - } - - 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) - { - char* fv = v->floatValue(); - return string("F(") + (fv ? string(fv) : string()) + ")"; - } - if (e->variant() == DOUBLE_VAL) - { - char* dv = v->doubleValue(); - if (!dv || !*dv) - return string("D()"); - char* endp = nullptr; - const double d = strtod(dv, &endp); - if (endp != dv && std::isfinite(d)) - { - const double r = std::round(d); - if (std::fabs(d - r) < 1e-12 && r >= static_cast(INT_MIN) && r <= static_cast(INT_MAX)) - return string("I(") + to_string(static_cast(r)) + ")"; - } - return string("D(") + string(dv) + ")"; - } - if (e->variant() == STRING_VAL) - return string("S(") + (v->stringValue() ? v->stringValue() : string()) + ")"; - } - - if (e->variant() == MULT_OP && e->lhs() && e->rhs()) - { - string a = buildStructuralExprKey(e->lhs()); - string b = buildStructuralExprKey(e->rhs()); - if (a > b) - swap(a, b); - return string("N(") + to_string(e->variant()) + ",L=" + a + ",R=" + b + ")"; - } - - string key = string("N(") + to_string(e->variant()); - if (e->lhs()) - key += ",L=" + buildStructuralExprKey(e->lhs()); - if (e->rhs()) - key += ",R=" + buildStructuralExprKey(e->rhs()); - key += ")"; - return key; + for (; stmt; stmt = stmt->controlParent()) + if (stmt == parent) + return true; + return false; } -// Prefer AST from IR instruction (same SgArrayRef for matching store/load); fallback to idxStack string. -string memexKeyForArrayLoadStore(const SAPFOR::Instruction* instr, const function& irStackKey) +static bool isStatementInFile(SgStatement* st, const string& fileName) { - if (!instr) - return string(); - SgExpression* ex = instr->getExpression(); - if (ex) - { - if (isSgArrayRefExp(ex)) - return string("MEMEX#") + buildStructuralExprKey(ex); - return string("MEMEX#") + buildStructuralExprKey(ex); - } - return irStackKey(); -} - -ArrayIndexCompareResult compareIndexExpressions(SgExpression* a, SgExpression* b) -{ - if (!a && !b) - return ArrayIndexCompareResult::Equal; - if (!a || !b) - return ArrayIndexCompareResult::NotEqual; - const string ka = buildStructuralExprKey(a); - const string kb = buildStructuralExprKey(b); - if (ka.empty() || kb.empty()) - return ArrayIndexCompareResult::Unknown; - if (ka == kb) - return ArrayIndexCompareResult::Equal; - return ArrayIndexCompareResult::NotEqual; -} - -ArrayIndexCompareResult compareArrayRefExpressions(SgArrayRefExp* a, SgArrayRefExp* b) -{ - if (!a && !b) - return ArrayIndexCompareResult::Equal; - if (!a || !b) - return ArrayIndexCompareResult::NotEqual; - SgSymbol* s1 = a->symbol() ? OriginalSymbol(a->symbol()) : nullptr; - SgSymbol* s2 = b->symbol() ? OriginalSymbol(b->symbol()) : nullptr; - if (s1 && s2) - { - if (strcmp(s1->identifier(), s2->identifier()) != 0) - return ArrayIndexCompareResult::NotEqual; - } - else if (s1 != s2) - return ArrayIndexCompareResult::NotEqual; - if (a->numberOfSubscripts() != b->numberOfSubscripts()) - return ArrayIndexCompareResult::NotEqual; - for (int i = 0; i < a->numberOfSubscripts(); ++i) - { - ArrayIndexCompareResult c = compareIndexExpressions(a->subscript(i), b->subscript(i)); - if (c != ArrayIndexCompareResult::Equal) - return c; - } - return ArrayIndexCompareResult::Equal; -} -} // namespace - -static vector findInstructionsFromStatement(SgStatement* st, const vector& blocks) -{ - vector result; if (!st) - return result; + return false; - const int stmtId = st->id(); - for (auto* bb : blocks) + const char* stmtFile = st->fileName(); + return stmtFile && fileName == stmtFile; +} + +static vector findLoopStatementsInFunction(SgStatement* funcStmt, const string& fileName) +{ + vector loops; + if (!funcStmt) + return loops; + + SgStatement* lastNode = funcStmt->lastNodeOfStmt(); + for (SgStatement* st = funcStmt; st && st != lastNode; st = st->lexNext()) + if (loop_tags.count(st->variant()) && isStatementInFile(st, fileName)) + loops.push_back(st); + + return loops; +} + +static SgStatement* firstSignificantOperatorInBlock(const SAPFOR::BasicBlock* bb, const string& fileName) +{ + if (!bb) + return nullptr; + + for (auto* ir : bb->getInstructions()) { - if (!bb) + if (!ir || !ir->getInstruction()) continue; - for (auto* ir : bb->getInstructions()) - { - if (!ir || !ir->getInstruction()) - continue; - - SgStatement* op = ir->getInstruction()->getOperator(); - if (op && op->id() == stmtId) - result.push_back(ir); - } + SgStatement* st = ir->getInstruction()->getOperator(); + if (isStatementInFile(st, fileName)) + return st; } - sort(result.begin(), result.end(), - [](const SAPFOR::IR_Block* a, const SAPFOR::IR_Block* b) { return a->getNumber() < b->getNumber(); }); - return result; + return nullptr; } -vector findFuncBlocksByFuncStatement(SgStatement *st, const map>& FullIR) { - vector result; - if (!st) - return result; +static SgStatement* lastSignificantOperatorInBlock(const SAPFOR::BasicBlock* bb, const string& fileName) +{ + if (!bb) + return nullptr; - Statement* forSt = (Statement*)st; - const string stmtFile = st->fileName(); - const int stmtLine = st->lineNumber(); - - for (auto& func: FullIR) { - if (!func.first || !func.first->funcPointer) + const auto& instructions = bb->getInstructions(); + for (auto it = instructions.rbegin(); it != instructions.rend(); ++it) + { + auto* ir = *it; + if (!ir || !ir->getInstruction()) 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; - } + SgStatement* st = ir->getInstruction()->getOperator(); + if (isStatementInFile(st, fileName)) + return st; } - return result; + + return nullptr; } -map> findAndAnalyzeLoops(SgStatement *st, const vector& blocks) { - map> result; - SgStatement *lastNode = st->lastNodeOfStmt(); - - while (st && st != lastNode) { - if (loop_tags.find(st -> variant()) != loop_tags.end()) { - SgForStmt *forSt = (SgForStmt*)st; - SgStatement *loopBody = forSt -> body(); - SgStatement *lastLoopNode = st->lastNodeOfStmt(); - set blocks_nums; - - while (loopBody && loopBody != lastLoopNode) { - vector irBlocks = findInstructionsFromStatement(loopBody, blocks); - if (!irBlocks.empty()) { - SAPFOR::IR_Block* IR = irBlocks.front(); - if (IR && IR->getBasicBlock()) { - if (blocks_nums.find(IR -> getBasicBlock() -> getNumber()) == blocks_nums.end()) { - result[forSt].push_back(IR -> getBasicBlock()); - blocks_nums.insert(IR -> getBasicBlock() -> getNumber()); - } - } - } - loopBody = loopBody -> lexNext(); - } - sort(result[forSt].begin(), result[forSt].end()); - } - st = st -> lexNext(); - } - return result; +static bool isBasicBlockInAnyLoop(const SAPFOR::BasicBlock* bb, const vector& loops, const string& fileName) +{ + SgStatement* first = firstSignificantOperatorInBlock(bb, fileName); + SgStatement* last = lastSignificantOperatorInBlock(bb, fileName); + if (!first || !last) + return false; + + + + for (auto* loop : loops) + if (loop && isParentStmt(first, loop) && isParentStmt(last, loop)) + return true; + + return false; } - -vector findBlocksInLoopsByFullIR( - SgStatement* funcStmt, +static vector findBlocksInLoopsByFullIR( + SgFile* file, const map>& FullIR) { vector result; - if (!funcStmt) + if (!file || !file->filename()) return result; - const vector funcBlocks = findFuncBlocksByFuncStatement(funcStmt, FullIR); - const auto loopsMapping = findAndAnalyzeLoops(funcStmt, funcBlocks); - + const string fileName = file->filename(); set uniq; - for (const auto& kv : loopsMapping) - for (auto* bb : kv.second) - if (bb) + + for (const auto& func : FullIR) + { + FuncInfo* funcInfo = func.first; + if (!funcInfo || !funcInfo->funcPointer) + continue; + + if (funcInfo->fileName != fileName) + continue; + + const vector loops = findLoopStatementsInFunction(funcInfo->funcPointer, fileName); + if (loops.empty()) + continue; + + for (auto* bb : func.second) + if (isBasicBlockInAnyLoop(bb, loops, fileName)) uniq.insert(bb); + } result.assign(uniq.begin(), uniq.end()); sort(result.begin(), result.end(), @@ -281,11 +152,10 @@ vector findBlocksInLoopsByFullIR( return result; } -static map> analyzeBasicBlockIntraDependencies(const SAPFOR::BasicBlock* bb) +static map> analyzeBasicBlockIntraDependencies(const SAPFOR::BasicBlock* bb) { - map> result; if (!bb) - return result; + return {}; auto isCompoundStmt = [](SgStatement* st) -> bool { @@ -295,306 +165,193 @@ static map> analyzeBasicBlockIntraDependencie return loop_tags.count(v) || control_tags.count(v) || control_end_tags.count(v); }; - auto isVarArg = [](const SAPFOR::Argument* a) -> bool + auto normalizeSageString = [](const string& src) -> string { - return a && a->getType() == SAPFOR::CFG_ARG_TYPE::VAR; + string normalized; + bool prevSpace = false; + + for (char ch : src) + { + const bool isSpace = std::isspace(static_cast(ch)); + if (isSpace) + { + if (!normalized.empty()) + prevSpace = true; + continue; + } + + if (prevSpace && !normalized.empty()) + normalized += ' '; + normalized += ch; + prevSpace = false; + } + + return normalized; }; - auto isArrayArg = [](const SAPFOR::Argument* a) -> bool + auto sageExprToString = [&](SgExpression* expr) -> string { - return a && a->getType() == SAPFOR::CFG_ARG_TYPE::ARRAY; - }; - - auto varKey = [&](const SAPFOR::Argument* a) -> string - { - if (!a) + if (!expr) return string(); - return a->getValue(); + + char* raw = expr->unparse(); + return normalizeSageString(raw ? string(raw) : string()); }; - auto parseIntConst = [](const SAPFOR::Argument* a, int& out) -> bool + auto arrayElementKey = [&](SgArrayRefExp* arrayRef) -> string { - if (!a || a->getType() != SAPFOR::CFG_ARG_TYPE::CONST) - return false; - try + if (!arrayRef) + return string(); + + string key; + SgSymbol* sym = arrayRef->symbol() ? OriginalSymbol(arrayRef->symbol()) : nullptr; + if (sym && sym->identifier()) + key = sym->identifier(); + else + return sageExprToString(arrayRef); + + if (key.empty()) + return string(); + + key += "("; + for (int i = 0; i < arrayRef->numberOfSubscripts(); ++i) { - out = stoi(a->getValue()); - return true; + if (i) + key += ", "; + key += sageExprToString(arrayRef->subscript(i)); } - catch (...) + key += ")"; + + return key; + }; + + function&)> collectUsedKeysFromExpression = + [&](SgExpression* expr, set& usedKeys) + { + if (!expr) + return; + + if (isSgValueExp(expr) || expr->variant() == CONST_REF) + return; + + if (auto* arrayRef = isSgArrayRefExp(expr)) { - return false; + const string key = arrayElementKey(arrayRef); + if (!key.empty()) + usedKeys.insert(key); + + for (int i = 0; i < arrayRef->numberOfSubscripts(); ++i) + collectUsedKeysFromExpression(arrayRef->subscript(i), usedKeys); + return; + } + + if (auto* call = isSgFunctionCallExp(expr)) + { + for (int i = 0; i < call->numberOfArgs(); ++i) + collectUsedKeysFromExpression(call->arg(i), usedKeys); + return; + } + + if (expr->variant() == VAR_REF) + { + SgSymbol* sym = expr->symbol() ? OriginalSymbol(expr->symbol()) : nullptr; + if (sym && sym->identifier()) + usedKeys.insert(sym->identifier()); + return; + } + + collectUsedKeysFromExpression(expr->lhs(), usedKeys); + collectUsedKeysFromExpression(expr->rhs(), usedKeys); + }; + + auto collectUsedKeysFromArraySubscripts = [&](SgArrayRefExp* arrayRef, set& usedKeys) + { + if (!arrayRef) + return; + + for (int i = 0; i < arrayRef->numberOfSubscripts(); ++i) + collectUsedKeysFromExpression(arrayRef->subscript(i), usedKeys); + }; + + auto addOperatorDependencies = [&](SgStatement* stmt, + const set& usedKeys, + const map& varDeclarations, + map>& 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 isBarrierInstr = [&](const SAPFOR::Instruction* instr) -> bool + auto declarationKeyFromLeftPart = [&](SgStatement* stmt) -> string { - if (!instr) - return true; - const auto op = instr->getOperation(); - switch (op) + if (!stmt || stmt->variant() != ASSIGN_STAT) + return string(); + + SgExpression* lhs = stmt->expr(0); + if (!lhs) + return string(); + + if (auto* arrayRef = isSgArrayRefExp(lhs)) + return arrayElementKey(arrayRef); + + if (lhs->variant() == VAR_REF) { - case SAPFOR::CFG_OP::F_CALL: - case SAPFOR::CFG_OP::IO_PARAM: - case SAPFOR::CFG_OP::DVM_DIR: - case SAPFOR::CFG_OP::SPF_DIR: - case SAPFOR::CFG_OP::POINTER_ASS: - case SAPFOR::CFG_OP::EXIT: - return true; - default: - return false; + SgSymbol* sym = lhs->symbol() ? OriginalSymbol(lhs->symbol()) : nullptr; + if (sym && sym->identifier()) + return sym->identifier(); } + + return string(); }; - map lastDef; - map lastMemDef; - map> depsSets; + vector operatorsOrder; + set seenOperators; - const auto& irs = bb->getInstructions(); - size_t i = 0; - while (i < irs.size()) + for (auto* ir : bb->getInstructions()) { - auto* ir = irs[i]; if (!ir || !ir->getInstruction()) - { - ++i; continue; - } - const SAPFOR::Instruction* firstInstr = ir->getInstruction(); - SgStatement* stmt = firstInstr->getOperator(); + const SAPFOR::Instruction* instr = ir->getInstruction(); + SgStatement* stmt = instr->getOperator(); if (!stmt || isCompoundStmt(stmt)) - { - ++i; continue; - } - vector group; - group.reserve(8); - bool isBarrierStmt = false; - - while (i < irs.size()) - { - auto* ir2 = irs[i]; - if (!ir2 || !ir2->getInstruction()) - { - ++i; - continue; - } - - const SAPFOR::Instruction* instr = ir2->getInstruction(); - if (instr->getOperator() != stmt) - break; - - group.push_back(instr); - if (isBarrierInstr(instr)) - isBarrierStmt = true; - ++i; - } - - if (!result.count(stmt)) - result[stmt] = {}; - - set usesVars; - set defsVars; - set usesMem; - set defsMem; - - vector idxStack; - idxStack.reserve(8); - - auto idxAtom = [&](const SAPFOR::Argument* a) -> string - { - if (!a) - return string(); - const auto t = a->getType(); - if (t == SAPFOR::CFG_ARG_TYPE::VAR || t == SAPFOR::CFG_ARG_TYPE::CONST || t == SAPFOR::CFG_ARG_TYPE::CONST_STR) - return a->getValue(); - return string("*"); - }; - - auto joinIdx = [&](const vector& idx) -> string - { - string s; - for (size_t k = 0; k < idx.size(); ++k) - { - if (k) - s += ","; - s += idx[k]; - } - return s; - }; - - auto popLastIdx = [&](int cnt) -> vector - { - vector idx; - if (cnt <= 0 || (size_t)cnt > idxStack.size()) - return idx; - idx.assign(idxStack.end() - cnt, idxStack.end()); - idxStack.erase(idxStack.end() - cnt, idxStack.end()); - return idx; - }; - - auto memKeyFromLoadStore = [&](const SAPFOR::Instruction* instr) -> string - { - if (!instr) - return string(); - SAPFOR::Argument* base = instr->getArg1(); - if (!isArrayArg(base)) - return string(); - - int cnt = 0; - if (!parseIntConst(instr->getArg2(), cnt)) - cnt = 0; - const auto idx = popLastIdx(cnt); - return base->getValue() + "[" + joinIdx(idx) + "]"; - }; - - string lastStoreKey; - string lastScalarDefKey; - - for (auto* instr : group) - { - if (!instr) - continue; - - if (isVarArg(instr->getArg1())) - usesVars.insert(varKey(instr->getArg1())); - if (isVarArg(instr->getArg2())) - usesVars.insert(varKey(instr->getArg2())); - - if (instr->getOperation() == SAPFOR::CFG_OP::RANGE && isVarArg(instr->getResult())) - usesVars.insert(varKey(instr->getResult())); - - if ((instr->getOperation() == SAPFOR::CFG_OP::STORE || instr->getOperation() == SAPFOR::CFG_OP::REC_REF_STORE) && - isVarArg(instr->getResult())) - { - usesVars.insert(varKey(instr->getResult())); - } - - if (instr->getOperation() == SAPFOR::CFG_OP::REF) - { - idxStack.push_back(idxAtom(instr->getArg1())); - } - else if (instr->getOperation() == SAPFOR::CFG_OP::RANGE) - { - idxStack.push_back(idxAtom(instr->getArg1()) + ":" + idxAtom(instr->getArg2()) + ":" + idxAtom(instr->getResult())); - } - else if (instr->getOperation() == SAPFOR::CFG_OP::LOAD || instr->getOperation() == SAPFOR::CFG_OP::STORE) - { - int dimCnt = 0; - if (!parseIntConst(instr->getArg2(), dimCnt)) - dimCnt = 0; - - string k; - if (instr->getExpression()) - { - k = memexKeyForArrayLoadStore(instr, []() { return string(); }); - if (!k.empty()) - popLastIdx(dimCnt); - } - if (k.empty()) - k = memKeyFromLoadStore(instr); - - if (!k.empty()) - { - if (instr->getOperation() == SAPFOR::CFG_OP::LOAD) - usesMem.insert(k); - else - { - defsMem.insert(k); - lastStoreKey = k; - } - } - } - else if (instr->getOperation() == SAPFOR::CFG_OP::REC_REF_LOAD || instr->getOperation() == SAPFOR::CFG_OP::REC_REF_STORE) - { - SAPFOR::Argument* base = instr->getArg1(); - if (base && (base->getType() == SAPFOR::CFG_ARG_TYPE::RECORD || base->getType() == SAPFOR::CFG_ARG_TYPE::VAR)) - { - const string k = base->getValue(); - if (instr->getOperation() == SAPFOR::CFG_OP::REC_REF_LOAD) - usesMem.insert(k); - else - { - defsMem.insert(k); - lastStoreKey = k; - } - } - } - } - - if (!group.empty()) - { - const SAPFOR::Instruction* last = group.back(); - if (last && last->getOperation() == SAPFOR::CFG_OP::ASSIGN && isVarArg(last->getResult())) - { - lastScalarDefKey = varKey(last->getResult()); - defsVars.insert(lastScalarDefKey); - } - else if (last && (last->getOperation() == SAPFOR::CFG_OP::STORE || last->getOperation() == SAPFOR::CFG_OP::REC_REF_STORE)) - { - if (!lastStoreKey.empty()) - defsMem.insert(lastStoreKey); - } - } - - auto addDepFromMap = [&](const map& m, const string& k) - { - auto it = m.find(k); - if (it == m.end()) - return; - if (it->second && it->second != stmt) - depsSets[stmt].insert(it->second); - }; - - for (const auto& k : usesVars) - addDepFromMap(lastDef, k); - for (const auto& k : usesMem) - addDepFromMap(lastMemDef, k); - - if (isBarrierStmt) - { - lastDef.clear(); - lastMemDef.clear(); - continue; - } - - for (const auto& k : defsVars) - { - addDepFromMap(lastDef, k); - lastDef[k] = stmt; - } - for (const auto& k : defsMem) - { - addDepFromMap(lastMemDef, k); - lastMemDef[k] = stmt; - } + if (seenOperators.insert(stmt).second) + operatorsOrder.push_back(stmt); } - for (auto& kv : result) + map varDeclarations; + map> operatorsDependencies; + + for (SgStatement* stmt : operatorsOrder) { - SgStatement* op = kv.first; - auto it = depsSets.find(op); - if (it == depsSets.end()) - continue; + set usedKeys; + if (stmt) + { + collectUsedKeysFromExpression(stmt->expr(1), usedKeys); + collectUsedKeysFromArraySubscripts(isSgArrayRefExp(stmt->expr(0)), usedKeys); + } + addOperatorDependencies(stmt, usedKeys, varDeclarations, operatorsDependencies); - kv.second.assign(it->second.begin(), it->second.end()); - sort(kv.second.begin(), kv.second.end(), - [](SgStatement* a, SgStatement* b) - { - const int la = a ? a->lineNumber() : -1; - const int lb = b ? b->lineNumber() : -1; - if (la != lb) - return la < lb; - return a < b; - }); + const string declarationKey = declarationKeyFromLeftPart(stmt); + if (!declarationKey.empty()) + varDeclarations[declarationKey] = stmt; } - return result; + return operatorsDependencies; } -static bool reorderOperatorsInBasicBlockUsingDeps(SAPFOR::BasicBlock* bb, const char* expectedFile) +static bool reorderOperatorsInBasicBlockUsingDeps( + SAPFOR::BasicBlock* bb, + const map>& operatorsDependencies) { if (!bb) return false; @@ -624,18 +381,6 @@ static bool reorderOperatorsInBasicBlockUsingDeps(SAPFOR::BasicBlock* bb, const 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; @@ -683,76 +428,72 @@ static bool reorderOperatorsInBasicBlockUsingDeps(SAPFOR::BasicBlock* bb, const return false; } - // Compute dependencies (inside BB) and build a new order by moving each statement - // as close as possible after its last dependency (if any). - const auto depsMap = analyzeBasicBlockIntraDependencies(bb); - vector order = ops; - const vector originalOrder = ops; - const int nOrig = (int)originalOrder.size(); + map originalIndex; + for (int i = 0; i < (int)ops.size(); ++i) + originalIndex[ops[i]] = i; - auto indexIn = [](const vector& v, SgStatement* s) -> int - { - for (int i = 0; i < (int)v.size(); ++i) - if (v[i] == s) - return i; - return -1; - }; + map> moveAfter; + set moved; - auto indexInOriginal = [&](SgStatement* s) -> int + for (SgStatement* st : ops) { - return indexIn(originalOrder, s); - }; - - for (SgStatement* s : ops) - { - auto itDeps = depsMap.find(s); - if (itDeps == depsMap.end() || itDeps->second.empty()) + auto itDeps = operatorsDependencies.find(st); + if (itDeps == operatorsDependencies.end() || itDeps->second.empty()) continue; - int lastDepOrigIdx = -1; + SgStatement* lastDep = nullptr; + int lastDepIdx = -1; for (SgStatement* dep : itDeps->second) { - const int j = indexInOriginal(dep); - if (j >= 0) - lastDepOrigIdx = max(lastDepOrigIdx, j); + auto itIdx = originalIndex.find(dep); + if (itIdx != originalIndex.end() && itIdx->second > lastDepIdx) + { + lastDep = dep; + lastDepIdx = itIdx->second; + } } - if (lastDepOrigIdx < 0) + if (!lastDep || lastDep == st) 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; - order.erase(order.begin() + posS); - order.push_back(s); - continue; - } - - 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); + moveAfter[lastDep].push_back(st); + moved.insert(st); } + vector order; + order.reserve(ops.size()); + set emitted; + set active; + bool invalidOrder = false; + + function emitStatement = [&](SgStatement* st) + { + if (!st || invalidOrder || emitted.count(st)) + return; + if (active.count(st)) + { + invalidOrder = true; + return; + } + + 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; + bool changed = false; for (size_t i = 0; i < ops.size(); ++i) if (ops[i] != order[i]) @@ -826,18 +567,14 @@ void moveOperators(SgFile* file, const mapfilename()) == -1) printInternalError(convertFileName(__FILE__).c_str(), __LINE__); - const int funcNum = file->numberOfFunctions(); - for (int i = 0; i < funcNum; ++i) - { - SgStatement* st = file->functions(i); + const auto loopBlocks = findBlocksInLoopsByFullIR(file, FullIR); - const auto loopBlocks = findBlocksInLoopsByFullIR(st, FullIR); - for (auto* bb : loopBlocks) - { - if (!bb) - continue; - if (reorderOperatorsInBasicBlockUsingDeps(bb, file->filename())) - countOfTransform += 1; - } + for (auto* bb : loopBlocks) + { + if (!bb) + continue; + const auto operatorsDependencies = analyzeBasicBlockIntraDependencies(bb); + if (reorderOperatorsInBasicBlockUsingDeps(bb, operatorsDependencies)) + countOfTransform += 1; } }