From 7fed8f13c37c6c08bf1551b200433ade2fd8a60a Mon Sep 17 00:00:00 2001 From: Egor Mayorov Date: Tue, 27 May 2025 01:41:50 +0300 Subject: [PATCH] Use more complex algorythm for building new order of statements --- src/SwapOperators/swapOperators.cpp | 223 ++++++++++++++-------------- 1 file changed, 109 insertions(+), 114 deletions(-) diff --git a/src/SwapOperators/swapOperators.cpp b/src/SwapOperators/swapOperators.cpp index d9483c7..bfe33a2 100644 --- a/src/SwapOperators/swapOperators.cpp +++ b/src/SwapOperators/swapOperators.cpp @@ -17,7 +17,8 @@ using namespace std; unordered_set loop_tags = {FOR_NODE/*, FORALL_NODE, WHILE_NODE, DO_WHILE_NODE*/}; -unordered_set importantDepsTags = {FOR_NODE, IF_NODE, ELSEIF_NODE}; +unordered_set importantDepsTags = {FOR_NODE, IF_NODE}; +unordered_set importantUpdDepsTags = {ELSEIF_NODE}; unordered_set importantEndTags = {CONTROL_END}; @@ -38,7 +39,7 @@ vector findInstructionsFromOperator(SgStatement* st, vector findFuncBlocksByFuncStatement(SgStatement *st, std::map>& FullIR) +vector findFuncBlocksByFuncStatement(SgStatement *st, map>& FullIR) { vector result; Statement* forSt = (Statement*)st; @@ -86,7 +87,7 @@ map> AnalyzeLoopAndFindDeps(SgForStmt* forStatem { map> result; for (SAPFOR::BasicBlock* bb: loopBlocks) { - std::map> blockReachingDefinitions = bb -> getRD_In(); + map> blockReachingDefinitions = bb -> getRD_In(); vector instructions = bb -> getInstructions(); for (SAPFOR::IR_Block* irBlock: instructions) { // TODO: Think about what to do with function calls and array references. Because there are also dependencies there that are not reflected in RD, but they must be taken into account @@ -100,7 +101,8 @@ map> AnalyzeLoopAndFindDeps(SgForStmt* forStatem SAPFOR::Instruction* foundInstruction = getInstructionAndBlockByNumber(FullIR, i).first; if (foundInstruction != NULL) { SgStatement* prevOp = foundInstruction -> getOperator(); - if (prevOp != forStatement && instr -> getOperator() != forStatement && instr -> getOperator() -> lineNumber() > prevOp -> lineNumber()) + if (prevOp != forStatement && instr -> getOperator() != forStatement && instr -> getOperator() -> lineNumber() > prevOp -> lineNumber() + && prevOp -> lineNumber() > forStatement -> lineNumber()) result[instr -> getOperator()].insert(prevOp); } } @@ -113,7 +115,8 @@ map> AnalyzeLoopAndFindDeps(SgForStmt* forStatem SAPFOR::Instruction* foundInstruction = getInstructionAndBlockByNumber(FullIR, i).first; if (foundInstruction != NULL) { SgStatement* prevOp = foundInstruction -> getOperator(); - if (prevOp != forStatement && instr -> getOperator() != forStatement && instr -> getOperator() -> lineNumber() > prevOp -> lineNumber()) + if (prevOp != forStatement && instr -> getOperator() != forStatement&& instr -> getOperator() -> lineNumber() > prevOp -> lineNumber() + && prevOp -> lineNumber() > forStatement -> lineNumber()) result[instr -> getOperator()].insert(prevOp); } } @@ -131,12 +134,13 @@ void buildAdditionalDeps(SgForStmt* forStatement, maplastNodeOfStmt(); vector importantDeps; SgStatement* st = (SgStatement*) forStatement; + st = st -> lexNext(); SgStatement* logIfOp = NULL; - importantDeps.push_back(st); while (st && st != lastNode) { - if (st != importantDeps.back()) { - dependencies[st].insert(importantDeps.back()); + if(importantDeps.size() != 0) + if (st != importantDeps.back()) { + dependencies[st].insert(importantDeps.back()); } if (logIfOp != NULL) { dependencies[st].insert(logIfOp); @@ -148,123 +152,117 @@ void buildAdditionalDeps(SgForStmt* forStatement, map variant()) != importantDepsTags.end()) { importantDeps.push_back(st); } - if (importantEndTags.find(st -> variant()) != importantEndTags.end()) { + if (importantUpdDepsTags.find(st -> variant()) != importantUpdDepsTags.end()) { importantDeps.pop_back(); + importantDeps.push_back(st); + } + if (importantEndTags.find(st -> variant()) != importantEndTags.end()) { + if(importantDeps.size() != 0) + importantDeps.pop_back(); } st = st -> lexNext(); } } -void GenNodesOfGraph( - const map>& dependencies, - set& allNodes, - map>& outEdges, - map>& inEdges) -{ - for (const auto& node: dependencies) { - SgStatement* u = node.first; - allNodes.insert(u); - for (SgStatement* v: node.second) { - allNodes.insert(v); - outEdges[v].insert(u); - inEdges[u].insert(v); - outEdges[u]; - inEdges[v]; - } - outEdges[u]; - inEdges[u]; +struct ReadyOp { + SgStatement* stmt; + int degree; + size_t arrival; + ReadyOp(SgStatement* s, int d, size_t a): stmt(s), degree(d), arrival(a) {} +}; + +struct ReadyOpCompare { + bool operator()(const ReadyOp& a, const ReadyOp& b) const { + if (a.degree != b.degree) + return a.degree > b.degree; + else + return a.arrival > b.arrival; } -} +}; -vector> FindLinksInGraph( - const set& allNodes, - const map>& outEdges, - const map>& inEdges) -{ - set visited; - vector> components; - for (SgStatement* v: allNodes) { - if (visited.count(v)) { - continue; - } - set component; - queue q; - q.push(v); - visited.insert(v); - - while (!q.empty()) { - SgStatement* curr = q.front(); - q.pop(); - component.insert(curr); - for (SgStatement* neighbour: outEdges.at(curr)) { - if (!visited.count(neighbour)) { - q.push(neighbour); visited.insert(neighbour); - } - } - for (SgStatement* neighbour: inEdges.at(curr)) { - if (!visited.count(neighbour)) { - q.push(neighbour); visited.insert(neighbour); - } +vector scheduleOperations( + const map>& dependencies +) { + // get all statements + unordered_set allStmtsSet; + for (const auto& pair : dependencies) { + allStmtsSet.insert(pair.first); + for (SgStatement* dep : pair.second) + allStmtsSet.insert(dep); + } + vector allStmts(allStmtsSet.begin(), allStmtsSet.end()); + // count deps and build reversed graph + unordered_map> graph; + unordered_map inDegree; + unordered_map degree; + for (auto op : allStmts) + inDegree[op] = 0; + // find and remember initial dependencies + unordered_set dependentStmts; + for (const auto& pair : dependencies) { + SgStatement* op = pair.first; + const auto& deps = pair.second; + degree[op] = deps.size(); + inDegree[op] = deps.size(); + if (!deps.empty()) + dependentStmts.insert(op); + for (auto dep : deps) + graph[dep].push_back(op); + } + for (SgStatement* op : allStmts) + if (!degree.count(op)) + degree[op] = 0; + // build queues + using PQ = priority_queue, ReadyOpCompare>; + PQ readyDependent; + queue readyIndependent; + size_t arrivalCounter = 0; + for (auto op : allStmts) { + if (inDegree[op] == 0) { + if (dependentStmts.count(op)) { + readyDependent.emplace(op, degree[op], arrivalCounter++); + } else { + readyIndependent.push(op); } } - components.push_back(component); } - return components; -} - -vector SortComponent( - const set& component, - const map>& outEdges, - const map>& inEdges) -{ - map inDegree; - for (auto v: component) { - inDegree[v] = inEdges.at(v).size(); - } - queue q; - for (auto v : component) { - if (inDegree[v] == 0) q.push(v); - } - vector result; - while (!q.empty()) { - auto curr = q.front(); - q.pop(); - result.push_back(curr); - for (SgStatement* neighbour: outEdges.at(curr)) { - if (component.count(neighbour)) { - inDegree[neighbour]--; - if (inDegree[neighbour] == 0) { - q.push(neighbour); + // main sort algorythm + vector executionOrder; + while (!readyDependent.empty() || !readyIndependent.empty()) { + SgStatement* current = nullptr; + if (!readyDependent.empty()) { + current = readyDependent.top().stmt; + readyDependent.pop(); + } else { + current = readyIndependent.front(); + readyIndependent.pop(); + } + executionOrder.push_back(current); + for (SgStatement* neighbor : graph[current]) { + inDegree[neighbor]--; + if (inDegree[neighbor] == 0) { + if (dependentStmts.count(neighbor)) { + readyDependent.emplace(neighbor, degree[neighbor], arrivalCounter++); + } else { + readyIndependent.push(neighbor); } } } } - return result; + return executionOrder; } -vector SortNoInterleaving(const map>& dependencies) -{ - set allNodes; - map> outEdges, inEdges; - GenNodesOfGraph(dependencies, allNodes, outEdges, inEdges); - auto components = FindLinksInGraph(allNodes, outEdges, inEdges); - vector totalOrder; - for (auto& comp : components) { - auto part = SortComponent(comp, outEdges, inEdges); - totalOrder.insert(totalOrder.end(), part.begin(), part.end()); - } - return totalOrder; -} + void runSwapOperators(SgFile *file, std::map>& loopGraph, std::map>& FullIR, int& countOfTransform) { std::cout << "SWAP_OPERATORS Pass" << std::endl; // to remove countOfTransform += 1; // to remove - const int funcNum = file->numberOfFunctions(); + const int funcNum = file -> numberOfFunctions(); for (int i = 0; i < funcNum; ++i) { - SgStatement *st = file->functions(i); + SgStatement *st = file -> functions(i); vector blocks = findFuncBlocksByFuncStatement(st, FullIR); map> loopsMapping = findAndAnalyzeLoops(st, blocks); for (pair> loopForAnalyze: loopsMapping) @@ -272,25 +270,22 @@ void runSwapOperators(SgFile *file, std::map> dependencyGraph = AnalyzeLoopAndFindDeps(loopForAnalyze.first, loopForAnalyze.second, FullIR); // TODO: Write a function that will go through the operators and update all dependencies so that there are no mix-ups and splits inside the semantic blocks (for if, do and may be some other cases) buildAdditionalDeps(loopForAnalyze.first, dependencyGraph); - cout << "\n\n"; + cout << endl; int firstLine = loopForAnalyze.first -> lineNumber(); int lastLine = loopForAnalyze.first -> lastNodeOfStmt() -> lineNumber(); - // for (auto v: dependencyGraph) { - // cout << "OPERATOR: " << v.first -> lineNumber() << "\nDEPENDS ON:" << endl; + cout << "LOOP ANALYZE FROM " << firstLine << " TO " << lastLine << " RES" << endl; + // for (auto &v: dependencyGraph) { + // cout << "OPERATOR: " << v.first -> lineNumber() << " " << v.first -> variant() << "\nDEPENDS ON:" << endl; // if (v.second.size() != 0) - // for (auto vv: v.second) { - // if (vv -> lineNumber() > firstLine) - // cout << vv -> lineNumber() << " "; - // } + // for (auto vv: v.second) + // cout << vv -> lineNumber() << " "; // cout << endl; // } - if (dependencyGraph.size() != 0) { - vector new_order = SortNoInterleaving(dependencyGraph); - cout << "\n\nLOOP ANALYZE FROM " << firstLine << " TO " << lastLine << " RES\n" << endl; - for (auto v: new_order) - if (v -> lineNumber() > firstLine) - cout << v -> lineNumber() << endl; - } + vector new_order = scheduleOperations(dependencyGraph); + cout << "RESULT ORDER:" << endl; + for (auto v: new_order) + if (v -> lineNumber() > firstLine) + cout << v -> lineNumber() << endl; } }