#include #include #include #include #include #include "../Utils/errors.h" #include "../Utils/SgUtils.h" #include "../GraphCall/graph_calls.h" #include "../GraphCall/graph_calls_func.h" #include "../CFGraph/CFGraph.h" #include "../CFGraph/IR.h" #include "../GraphLoop/graph_loops.h" #include "swapOperators.h" using namespace std; unordered_set loop_tags = {FOR_NODE/*, FORALL_NODE, WHILE_NODE, DO_WHILE_NODE*/}; vector findInstructionsFromOperator(SgStatement* st, vector Blocks) { vector result; string filename = st -> fileName(); for (auto& block: Blocks) { vector instructionsInBlock = block -> getInstructions(); for (auto& instruction: instructionsInBlock) { SgStatement* curOperator = instruction -> getInstruction() -> getOperator(); if (curOperator -> lineNumber() == st -> lineNumber()) result.push_back(instruction); } } return result; } vector findFuncBlocksByFuncStatement(SgStatement *st, std::map>& FullIR) { vector result; Statement* forSt = (Statement*)st; for (auto& func : FullIR) { if (func.first -> funcPointer -> getCurrProcessFile() == forSt -> getCurrProcessFile() && func.first -> funcPointer -> lineNumber() == forSt -> lineNumber()) result = func.second; } return result; } map> findAndAnalyzeLoops(SgStatement *st, vector blocks) { map> result; SgStatement *lastNode = st->lastNodeOfStmt(); while (st && st != lastNode) { if (loop_tags.find(st -> variant()) != loop_tags.end()) { // part with find statements of loop SgForStmt *forSt = (SgForStmt*)st; SgStatement *loopBody = forSt -> body(); SgStatement *lastLoopNode = st->lastNodeOfStmt(); // part with find blocks and instructions of loops unordered_set blocks_nums; while (loopBody && loopBody != lastLoopNode) { SAPFOR::IR_Block* IR = findInstructionsFromOperator(loopBody, blocks).front(); 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(); } std::sort(result[forSt].begin(), result[forSt].end()); } st = st -> lexNext(); } return result; } map> AnalyzeLoopAndFindDeps(SgForStmt* forStatement, vector loopBlocks, map>& FullIR) { map> result; for (SAPFOR::BasicBlock* bb: loopBlocks) { std::map> blockReachingDefinitions = bb -> getRD_In(); vector instructions = bb -> getInstructions(); for (SAPFOR::IR_Block* irBlock: instructions) { SAPFOR::Instruction* instr = irBlock -> getInstruction(); // take Argument 1 and it's RD and push operators to final set if (instr -> getArg1() != NULL) { SAPFOR::Argument* arg = instr -> getArg1(); set prevInstructionsNumbers = blockReachingDefinitions[arg]; for (int i: prevInstructionsNumbers) { 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()) result[instr -> getOperator()].insert(prevOp); } } } // take Argument 2 (if exists) and it's RD and push operators to final set if (instr -> getArg2() != NULL) { SAPFOR::Argument* arg = instr -> getArg2(); set prevInstructionsNumbers = blockReachingDefinitions[arg]; for (int i: prevInstructionsNumbers) { 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()) result[instr -> getOperator()].insert(prevOp); } } } // update RD if (instr -> getResult() != NULL) blockReachingDefinitions[instr -> getResult()] = {instr -> getNumber()}; } } return result; } int RebuildLoop(int firstLine, int lastLine, map> moveRules) { // only cout done yet (( cout << "LOOP ANALYZE FROM " << firstLine << " TO " << lastLine << " RES\n" << endl; for (auto r: moveRules) { cout << "OPERATOR: " << endl; cout << r.first -> lineNumber() << r.first -> sunparse(); cout << "DEPENDS FROM NEXT: " << endl; for (SgStatement* st: r.second) cout << st -> lineNumber() << endl; } cout << "\n\n\n"; return 0; } 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(); for (int i = 0; i < funcNum; ++i) { SgStatement *st = file->functions(i); vector blocks = findFuncBlocksByFuncStatement(st, FullIR); map> loopsMapping = findAndAnalyzeLoops(st, blocks); for (pair> loopForAnalyze: loopsMapping) { map> moveRules = AnalyzeLoopAndFindDeps(loopForAnalyze.first, loopForAnalyze.second, FullIR); if (moveRules.size() != 0) { int firstLine = loopForAnalyze.first -> lineNumber(); int lastLine = loopForAnalyze.first -> lastNodeOfStmt() -> lineNumber(); countOfTransform += RebuildLoop(firstLine, lastLine, moveRules); } } } return; };