From 2969f92013005d65c98495073a52dc9a1e92fa94 Mon Sep 17 00:00:00 2001 From: ALEXks Date: Fri, 30 May 2025 17:33:57 +0300 Subject: [PATCH] moved code, fixed style --- CMakeLists.txt | 12 +- src/CFGraph/CFGraph.h | 4 + src/CFGraph/IR.cpp | 426 ----------------- src/CFGraph/IR.h | 2 - src/CFGraph/{IRSSAForm.cpp => IR_SSAForm.cpp} | 21 +- src/CFGraph/{IRSSAForm.h => IR_SSAForm.h} | 0 src/LoopAnalyzer/implicit_loops_analyzer.cpp | 449 ++++++++++++++++++ src/LoopAnalyzer/implicit_loops_analyzer.h | 7 + src/PrivateAnalyzer/private_arrays_search.cpp | 2 +- src/PrivateAnalyzer/private_arrays_search.h | 2 +- src/Sapfor.cpp | 13 +- src/Sapfor.h | 4 +- src/SapforData.h | 6 +- src/Utils/PassManager.h | 4 +- 14 files changed, 490 insertions(+), 462 deletions(-) rename src/CFGraph/{IRSSAForm.cpp => IR_SSAForm.cpp} (93%) rename src/CFGraph/{IRSSAForm.h => IR_SSAForm.h} (100%) create mode 100644 src/LoopAnalyzer/implicit_loops_analyzer.cpp create mode 100644 src/LoopAnalyzer/implicit_loops_analyzer.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 81d0dee..f50eb72 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -219,16 +219,14 @@ set(CFG src/CFGraph/IR.cpp src/CFGraph/live_variable_analysis.h src/CFGraph/private_variables_analysis.cpp src/CFGraph/private_variables_analysis.h - src/CFGraph/IRSSAForm.cpp - src/CFGraph/IRSSAForm.h - ) + src/CFGraph/IR_SSAForm.cpp + src/CFGraph/IR_SSAForm.h) set(DATA_FLOW src/CFGraph/DataFlow/data_flow.h src/CFGraph/DataFlow/data_flow_impl.h src/CFGraph/DataFlow/backward_data_flow.h - src/CFGraph/DataFlow/backward_data_flow_impl.h - ) + src/CFGraph/DataFlow/backward_data_flow_impl.h) set(CREATE_INTER_T src/CreateInterTree/CreateInterTree.cpp src/CreateInterTree/CreateInterTree.h) @@ -311,7 +309,9 @@ set(INLINER src/Inliner/inliner.cpp set(LOOP_ANALYZER src/LoopAnalyzer/allocations_prepoc.cpp src/LoopAnalyzer/dep_analyzer.cpp src/LoopAnalyzer/loop_analyzer.cpp - src/LoopAnalyzer/loop_analyzer.h) + src/LoopAnalyzer/loop_analyzer.h + src/LoopAnalyzer/implicit_loops_analyzer.cpp + src/LoopAnalyzer/implicit_loops_analyzer.h) set(RENAME_SYMBOLS src/RenameSymbols/rename_symbols.cpp src/RenameSymbols/rename_symbols.h) diff --git a/src/CFGraph/CFGraph.h b/src/CFGraph/CFGraph.h index 31ceb2b..369c1d7 100644 --- a/src/CFGraph/CFGraph.h +++ b/src/CFGraph/CFGraph.h @@ -6,6 +6,10 @@ #include #include "IR.h" +#include "../Utils/errors.h" +#include "../Utils/utils.h" +#include "../Utils/CommonBlock.h" +#include "../GraphCall/graph_calls.h" namespace SAPFOR { diff --git a/src/CFGraph/IR.cpp b/src/CFGraph/IR.cpp index 4b24610..a46226b 100644 --- a/src/CFGraph/IR.cpp +++ b/src/CFGraph/IR.cpp @@ -1613,429 +1613,3 @@ vector buildIR(SgStatement* function, const FuncInfo* func, const vec return blocks; } - -enum VisitState { UNVISITED = 0, VISITING = 1, VISITED = 2 }; - -void dfs(SAPFOR::BasicBlock* block, map& visit, vector>& startAndEnd, SAPFOR::BasicBlock* prev) { - if (!block) return; - - if (visit[block->getNumber()] == VISITED) { - cout << "error"; - return; - } - - if (visit[block->getNumber()] == VISITING) { - visit[block->getNumber()] = VISITED; - startAndEnd.push_back(make_pair(prev, block)); - return; - } - - visit[block->getNumber()] = VISITING; - for (auto i : block->getNext()) { - dfs(i, visit, startAndEnd, block); - } -} - -static void printBlock(SAPFOR::BasicBlock* block) { - cout << "block - " << block->getNumber() << endl; - cout << "next -"; - for (auto i : block->getNext()) - { - cout << " " << i->getNumber(); - } - cout << endl << "prev -"; - for (auto i : block->getPrev()) - { - cout << " " << i->getNumber(); - } - cout << endl; - - for (auto i : block->getInstructions()) - { - string resValue = ""; - string arg1Value = ""; - string arg2Value = ""; - if (i->getInstruction()->getResult() != nullptr && i->getInstruction()->getResult()->getType() == CFG_ARG_TYPE::VAR) { - resValue = i->getInstruction()->getResult()->getValue(); - i->getInstruction()->getResult()->setValue(i->getInstruction()->getResult()->getValue() + to_string(i->getInstruction()->getResult()->getNumber())); - } - if (i->getInstruction()->getArg1() != nullptr && i->getInstruction()->getArg1()->getType() == CFG_ARG_TYPE::VAR) { - arg1Value = i->getInstruction()->getArg1()->getValue(); - i->getInstruction()->getArg1()->setValue(i->getInstruction()->getArg1()->getValue() + to_string(i->getInstruction()->getArg1()->getNumber())); - } - if (i->getInstruction()->getArg2() != nullptr && i->getInstruction()->getArg2()->getType() == CFG_ARG_TYPE::VAR) { - arg2Value = i->getInstruction()->getArg2()->getValue(); - i->getInstruction()->getArg2()->setValue(i->getInstruction()->getArg2()->getValue() + to_string(i->getInstruction()->getArg2()->getNumber())); - } - - cout << i->getNumber() << " " << i->getInstruction()->dump() << endl; - - if (i->getInstruction()->getResult() != nullptr && i->getInstruction()->getResult()->getType() == CFG_ARG_TYPE::VAR) { - i->getInstruction()->getResult()->setValue(resValue); - } - if (i->getInstruction()->getArg1() != nullptr && i->getInstruction()->getArg1()->getType() == CFG_ARG_TYPE::VAR) { - i->getInstruction()->getArg1()->setValue(arg1Value); - } - if (i->getInstruction()->getArg2() != nullptr && i->getInstruction()->getArg2()->getType() == CFG_ARG_TYPE::VAR) { - i->getInstruction()->getArg2()->setValue(arg2Value); - } - } - - cout << endl; -} - -void getLoopBody(SAPFOR::BasicBlock* loopHeader, const std::set& loopExits, std::vector& loopBody) { - std::set visited; - std::stack stack; - - stack.push(loopHeader); - - while (!stack.empty()) { - auto block = stack.top(); - stack.pop(); - - if (visited.count(block)) continue; - visited.insert(block); - - for (auto succ : block->getNext()) { - if (loopExits.count(succ)) continue; - if (!visited.count(succ)) { - stack.push(succ); - } - } - } - - std::set backReachable; - std::stack reverseStack; - reverseStack.push(loopHeader); - - while (!reverseStack.empty()) { - auto block = reverseStack.top(); - reverseStack.pop(); - - if (backReachable.count(block)) continue; - backReachable.insert(block); - - for (auto pred : block->getPrev()) { - if (visited.count(pred) && !backReachable.count(pred)) { - reverseStack.push(pred); - } - } - } - - for (auto block : visited) { - if (backReachable.count(block)) { - loopBody.push_back(block); - } - } -} - - -set findRegisterSourceVariables(const std::vector& blocks, SAPFOR::Argument* var) { - std::set result; - std::set visited; - std::stack workStack; - workStack.push(var); - - auto isBinaryOp = [](SAPFOR::CFG_OP op) { - return op == SAPFOR::CFG_OP::ADD || op == SAPFOR::CFG_OP::SUBT || - op == SAPFOR::CFG_OP::MULT || op == SAPFOR::CFG_OP::DIV || - op == SAPFOR::CFG_OP::POW || - op == SAPFOR::CFG_OP::GE || op == SAPFOR::CFG_OP::LE || - op == SAPFOR::CFG_OP::GT || op == SAPFOR::CFG_OP::LT || - op == SAPFOR::CFG_OP::EQ || op == SAPFOR::CFG_OP::NEQV || - op == SAPFOR::CFG_OP::EQV || op == SAPFOR::CFG_OP::EMPTY || - op == SAPFOR::CFG_OP::OR || op == SAPFOR::CFG_OP::AND; - }; - - auto isUnaryOp = [](SAPFOR::CFG_OP op) { - return op == SAPFOR::CFG_OP::UN_ADD || op == SAPFOR::CFG_OP::UN_MINUS || - op == SAPFOR::CFG_OP::NOT || op == SAPFOR::CFG_OP::ASSIGN; - }; - - while (!workStack.empty()) { - auto variable = workStack.top(); - workStack.pop(); - if (!variable || visited.count(variable)) - continue; - - visited.insert(variable); - - for (auto block : blocks) { - for (auto instrWrapper : block->getInstructions()) { - auto instr = instrWrapper->getInstruction(); - if (!instr || instr->getResult() != variable) - continue; - - auto op = instr->getOperation(); - auto arg1 = instr->getArg1(); - auto arg2 = instr->getArg2(); - - if (isBinaryOp(op) && arg1 && arg2) { - if (arg1->getType() == CFG_ARG_TYPE::VAR) - result.insert(arg1); - else if (arg1->getType() == CFG_ARG_TYPE::REG) - workStack.push(arg1); - - if (arg2->getType() == CFG_ARG_TYPE::VAR) - result.insert(arg2); - else if (arg2->getType() == CFG_ARG_TYPE::REG) - workStack.push(arg2); - } - else if (isUnaryOp(op) && arg1) { - if (arg1->getType() == CFG_ARG_TYPE::VAR) - result.insert(arg1); - else if (arg1->getType() == CFG_ARG_TYPE::REG) - workStack.push(arg1); - } - } - } - } - - return result; -} - -std::vector getPhiArguments(SAPFOR::BasicBlock* block, SAPFOR::Instruction* phiInstr) { - std::vector result; - - auto& instructions = block->getInstructions(); - bool collecting = false; - for (int i = instructions.size() - 1; i >= 0; --i) { - auto instr = instructions[i]->getInstruction(); - - if (collecting) { - if (instr->getOperation() == SAPFOR::CFG_OP::PARAM) { - auto arg = instr->getArg1(); - if (arg) { - result.push_back(instr); - } - } - else { - break; - } - } - - if (!instr) continue; - - if (instr == phiInstr) { - collecting = true; - continue; - } - } - - std::reverse(result.begin(), result.end()); - return result; -} - -SAPFOR::BasicBlock* findInstructionBlock(SAPFOR::Instruction* targetInstr, const std::vector& blocks) { - for (auto block : blocks) { - for (auto instrWrapper : block->getInstructions()) { - auto instr = instrWrapper->getInstruction(); - if (instr == targetInstr) { - return block; - } - } - } - return nullptr; -} - -SAPFOR::BasicBlock* findInstructionBlockByNumber(int number, const std::vector& blocks) { - for (auto block : blocks) { - for (auto instrWrapper : block->getInstructions()) { - auto instr = instrWrapper->getInstruction(); - if (instr->getNumber() == number) { - return block; - } - } - } - return nullptr; -} - - -void findInductiveVars(const std::vector& blocks, const std::vector& Loopblocks, SAPFOR::BasicBlock* loopHeader, const std::set& loopExits) { - std::set inductiveVars; - std::set relevantBlocks = { loopHeader }; - - for (auto block : relevantBlocks) { - - for (auto instrWrapper : block->getInstructions()) { - auto instr = instrWrapper->getInstruction(); - if (!instr) continue; - - auto op = instr->getOperation(); - auto res = instr->getResult(); - auto arg1 = instr->getArg1(); - auto arg2 = instr->getArg2(); - - if (op == CFG_OP::JUMP_IF) { - if (arg1 && arg1->getType() == CFG_ARG_TYPE::VAR) { - inductiveVars.insert(arg1->getValue()); - } - if (arg1 && arg1->getType() == CFG_ARG_TYPE::REG) { - auto foundVariables = findRegisterSourceVariables(blocks, arg1); - for (auto var : foundVariables) { - inductiveVars.insert(var->getValue()); - } - } - } - } - } - - std::set finalInductiveVars; - - for (auto instrWrapper : loopHeader->getInstructions()) { - auto instr = instrWrapper->getInstruction(); - if (!instr || instr->getOperation() != SAPFOR::CFG_OP::F_CALL || !instr->getArg1() || instr->getArg1()->getValue() != "FI_FUNCTION") continue; - - auto phiRes = instr->getResult(); - if (!phiRes || !inductiveVars.count(phiRes->getValue())) continue; - - auto currentBlock = findInstructionBlock(instr, blocks); - if (!currentBlock) continue; - - auto phiArgs = getPhiArguments(currentBlock, instr); - - bool hasInLoopDefinition = false; - - for (const auto& argInstr : phiArgs) { - if (!argInstr) continue; - - int definitionInstrNumber = stoi(argInstr->getArg1()->getValue()); - if (definitionInstrNumber == -1) continue; - - auto phiBlock = findInstructionBlockByNumber(definitionInstrNumber, blocks); - if (!phiBlock) continue; - - if (std::find(Loopblocks.begin(), Loopblocks.end(), phiBlock) != Loopblocks.end()) { - hasInLoopDefinition = true; - } - } - - if (hasInLoopDefinition) { - finalInductiveVars.insert(phiRes->getValue()); - } - } - - for (auto i : finalInductiveVars) { - std::cout << "Confirmed inductive variable: " << i << std::endl; - } - - if (finalInductiveVars.empty()) { - std::cout << "No confirmed inductive variables found." << std::endl; - } -} - -Instruction* findInstructionAfterLoop(const std::vector& loopBody) { - std::set loopSet(loopBody.begin(), loopBody.end()); - - for (auto block : loopBody) { - for (auto succ : block->getNext()) { - if (!loopSet.count(succ)) { - // Нашли выход из цикла — возьмём первую инструкцию - auto instructions = succ->getInstructions(); - for (auto wrapper : instructions) { - if (auto instr = wrapper->getInstruction()) { - return instr; - } - } - } - } - } - - return nullptr; // не нашли -} - -bool isEqual(const char* cstr, const std::string& str) { - return str == cstr; -} - -void exploreLoops(map>* fullIR, const char* fileName) { - for (auto& i : *fullIR) - { - //for (auto j : i.second) - // printblock(j); - - if (!isEqual(fileName, i.first->fileName)) - continue; - - map visited; - for (auto i : i.second) - visited[i->getNumber()] = UNVISITED; - - //vector visited(i.second.size(), UNVISITED); - vector> startAndEnd; - dfs(i.second[0], visited, startAndEnd, NULL); - - vector loops; - - for (auto& [tail, header] : startAndEnd) { - set loopExits; - - for (auto succ : tail->getNext()) { - if (succ != header) { - loopExits.insert(succ); - } - } - - vector loopBody; - getLoopBody(header, loopExits, loopBody); - - cout << "LOOP DETECTED:" << endl; - cout << " Header: " << header->getNumber() << endl; - cout << " Tail: " << tail->getNumber() << endl; - cout << " Body blocks: "; - for (auto block : loopBody) { - cout << block->getNumber() << " "; - } - cout << endl; - - findInductiveVars(i.second, loopBody, header, loopExits); - - - Instruction* instructionAfterLoop = findInstructionAfterLoop(loopBody); - - if (instructionAfterLoop == NULL) { - cout << "Warning: instruction after loop not found!" << endl; - continue; - } - auto firstInstruction = header->getInstructions()[0]->getInstruction(); - auto lastInstruction = tail->getInstructions().back()->getInstruction(); - - cout << "first - " << firstInstruction->getNumber() << " last - " << lastInstruction->getNumber() << " after - " << instructionAfterLoop->getNumber() << endl; - auto x = firstInstruction->getOperator(); - - auto tmpLoop = new LoopGraph(); - tmpLoop->isFor = true; - tmpLoop->lineNum = firstInstruction->getOperator()->lineNumber(); - tmpLoop->lineNumAfterLoop = instructionAfterLoop->getOperator()->lineNumber(); - - if (firstInstruction->getOperator()->variant() == FOR_NODE) { - SgForStmt* stmt = isSgForStmt(firstInstruction->getOperator()); - - cout << "for loop" << endl;// << stmt->sunparse() << endl; - } - else if (firstInstruction->getOperator()->variant() == WHILE_NODE) { - SgWhileStmt* stmt = isSgWhileStmt(firstInstruction->getOperator()); - - cout << (stmt->conditional() == NULL ? "infinit" : "") << "while loop" << endl;//<< stmt->sunparse() << endl; - } - else if (firstInstruction->getOperator()->variant() == DO_WHILE_NODE) { - SgWhileStmt* stmt = isSgDoWhileStmt(firstInstruction->getOperator()); - - cout << "do while loop" << endl;// << stmt->sunparse() << endl; - } - else if (firstInstruction->getOperator()->variant() == LOOP_NODE) { - cout << "not known loop" << endl;// << firstInstruction->getOperator()->sunparse() << endl; - } - else { - - cout << "goto loop" << endl;// firstInstruction->getOperator()->sunparse() << endl; - } - - cout << "loop start line " << tmpLoop->lineNum << endl; - cout << "after loop line " << tmpLoop->lineNumAfterLoop << endl << endl; - - loops.push_back(tmpLoop); - } - } -} \ No newline at end of file diff --git a/src/CFGraph/IR.h b/src/CFGraph/IR.h index 4c31182..bcb68e4 100644 --- a/src/CFGraph/IR.h +++ b/src/CFGraph/IR.h @@ -351,5 +351,3 @@ SAPFOR::Instruction* getInstructionByNumber(const std::vector std::pair getInstructionAndBlockByNumber(const std::map>& CFGraph, int num); std::pair getInstructionAndBlockByStatement(const std::map>& CFGraph, SgStatement* stmt); int getParamIndex(SAPFOR::Argument* func_param, int max_index); - -void exploreLoops(std::map>* fullIR, const char* fileName); \ No newline at end of file diff --git a/src/CFGraph/IRSSAForm.cpp b/src/CFGraph/IR_SSAForm.cpp similarity index 93% rename from src/CFGraph/IRSSAForm.cpp rename to src/CFGraph/IR_SSAForm.cpp index fbbed60..f751a63 100644 --- a/src/CFGraph/IRSSAForm.cpp +++ b/src/CFGraph/IR_SSAForm.cpp @@ -365,10 +365,7 @@ static void getBlocksWithFiFunctions(vector blocks, set glo //return blocksWithFiFunctions; } - - - -string ToString(CFG_ARG_TYPE type) { +static string ToString(CFG_ARG_TYPE type) { switch (type) { case CFG_ARG_TYPE::NONE: return "NONE"; case CFG_ARG_TYPE::REG: return "REG"; @@ -385,7 +382,7 @@ string ToString(CFG_ARG_TYPE type) { } } -void restoreConnections(const vector& originalBlocks, vector& copiedBlocks) { +static void restoreConnections(const vector& originalBlocks, vector& copiedBlocks) { // Создаем отображение оригинальных блоков в их копии map blockMapping; for (size_t i = 0; i < originalBlocks.size(); ++i) { @@ -421,7 +418,7 @@ void restoreConnections(const vector& originalBlocks, vector& } -BArgument* NewName(BArgument* var, map& counter, map>& stack, int number) { +static BArgument* NewName(BArgument* var, map& counter, map>& stack, int number) { //int index = counter[var->getValue()]; counter[var->getValue()]++; @@ -430,7 +427,7 @@ BArgument* NewName(BArgument* var, map& counter, map& counter, map>& stack) { +static void RenameFiFunctionResultVar(BBlock* block, map& counter, map>& stack) { for (auto irBlock : block->getInstructions()) { auto instruction = irBlock->getInstruction(); if (instruction->getOperation() == CFG_OP::F_CALL && instruction->getArg1() != nullptr && instruction->getArg1()->getValue() == "FI_FUNCTION" && instruction->getResult() != nullptr) { @@ -439,7 +436,7 @@ void RenameFiFunctionResultVar(BBlock* block, map& counter, map& counter, map>& stack) { +static void RenameInstructionVars(BBlock* block, map& counter, map>& stack) { for (auto irBlock : block->getInstructions()) { auto instruction = irBlock->getInstruction(); @@ -457,7 +454,7 @@ void RenameInstructionVars(BBlock* block, map& counter, map>& stack) { +static void RenameFiFunctionArgsVar(BBlock* block, map>& stack) { auto size = block->getInstructions().size(); auto& instructions = block->getInstructions(); for (auto i = 0; i < size; i++) { @@ -485,7 +482,7 @@ void RenameFiFunctionArgsVar(BBlock* block, map>& stac } } -vector findBlocksWithValue(map& iDominators, BBlock* x) { +static vector findBlocksWithValue(map& iDominators, BBlock* x) { vector result; // Проходим по всем элементам map @@ -499,7 +496,7 @@ vector findBlocksWithValue(map& iDominators, BBlock* return result; } -void RenameIR(BBlock* block, map& iDominators, map& counter, map>& stack) { +static void RenameIR(BBlock* block, map& iDominators, map& counter, map>& stack) { RenameFiFunctionResultVar(block, counter, stack); @@ -630,4 +627,4 @@ void buildIRSSAForm(map> fullIR, map +#include +#include +#include +#include +#include + +#include "../CFGraph/IR.h" +#include "GraphCall/graph_calls.h" +#include "implicit_loops_analyzer.h" + +using std::map; +using std::set; +using std::vector; +using std::pair; +using std::string; +using std::cout; +using std::endl; +using std::make_pair; +using std::to_string; + +enum VisitState { UNVISITED = 0, VISITING = 1, VISITED = 2 }; + +void dfs(SAPFOR::BasicBlock* block, map& visit, vector>& startAndEnd, SAPFOR::BasicBlock* prev) { + if (!block) return; + + if (visit[block->getNumber()] == VISITED) { + cout << "error"; + return; + } + + if (visit[block->getNumber()] == VISITING) { + visit[block->getNumber()] = VISITED; + startAndEnd.push_back(make_pair(prev, block)); + return; + } + + visit[block->getNumber()] = VISITING; + for (auto i : block->getNext()) { + dfs(i, visit, startAndEnd, block); + } +} + +static void printBlock(SAPFOR::BasicBlock* block) { + cout << "block - " << block->getNumber() << endl; + cout << "next -"; + for (auto i : block->getNext()) + { + cout << " " << i->getNumber(); + } + cout << endl << "prev -"; + for (auto i : block->getPrev()) + { + cout << " " << i->getNumber(); + } + cout << endl; + + for (auto i : block->getInstructions()) + { + string resValue = ""; + string arg1Value = ""; + string arg2Value = ""; + if (i->getInstruction()->getResult() != nullptr && i->getInstruction()->getResult()->getType() == SAPFOR::CFG_ARG_TYPE::VAR) { + resValue = i->getInstruction()->getResult()->getValue(); + i->getInstruction()->getResult()->setValue(i->getInstruction()->getResult()->getValue() + to_string(i->getInstruction()->getResult()->getNumber())); + } + if (i->getInstruction()->getArg1() != nullptr && i->getInstruction()->getArg1()->getType() == SAPFOR::CFG_ARG_TYPE::VAR) { + arg1Value = i->getInstruction()->getArg1()->getValue(); + i->getInstruction()->getArg1()->setValue(i->getInstruction()->getArg1()->getValue() + to_string(i->getInstruction()->getArg1()->getNumber())); + } + if (i->getInstruction()->getArg2() != nullptr && i->getInstruction()->getArg2()->getType() == SAPFOR::CFG_ARG_TYPE::VAR) { + arg2Value = i->getInstruction()->getArg2()->getValue(); + i->getInstruction()->getArg2()->setValue(i->getInstruction()->getArg2()->getValue() + to_string(i->getInstruction()->getArg2()->getNumber())); + } + + cout << i->getNumber() << " " << i->getInstruction()->dump() << endl; + + if (i->getInstruction()->getResult() != nullptr && i->getInstruction()->getResult()->getType() == SAPFOR::CFG_ARG_TYPE::VAR) { + i->getInstruction()->getResult()->setValue(resValue); + } + if (i->getInstruction()->getArg1() != nullptr && i->getInstruction()->getArg1()->getType() == SAPFOR::CFG_ARG_TYPE::VAR) { + i->getInstruction()->getArg1()->setValue(arg1Value); + } + if (i->getInstruction()->getArg2() != nullptr && i->getInstruction()->getArg2()->getType() == SAPFOR::CFG_ARG_TYPE::VAR) { + i->getInstruction()->getArg2()->setValue(arg2Value); + } + } + + cout << endl; +} + +void getLoopBody(SAPFOR::BasicBlock* loopHeader, const set& loopExits, std::vector& loopBody) { + set visited; + std::stack stack; + + stack.push(loopHeader); + + while (!stack.empty()) { + auto block = stack.top(); + stack.pop(); + + if (visited.count(block)) continue; + visited.insert(block); + + for (auto succ : block->getNext()) { + if (loopExits.count(succ)) continue; + if (!visited.count(succ)) { + stack.push(succ); + } + } + } + + set backReachable; + std::stack reverseStack; + reverseStack.push(loopHeader); + + while (!reverseStack.empty()) { + auto block = reverseStack.top(); + reverseStack.pop(); + + if (backReachable.count(block)) continue; + backReachable.insert(block); + + for (auto pred : block->getPrev()) { + if (visited.count(pred) && !backReachable.count(pred)) { + reverseStack.push(pred); + } + } + } + + for (auto block : visited) { + if (backReachable.count(block)) { + loopBody.push_back(block); + } + } +} + + +set findRegisterSourceVariables(const std::vector& blocks, SAPFOR::Argument* var) +{ + set result; + set visited; + std::stack workStack; + workStack.push(var); + + auto isBinaryOp = [](SAPFOR::CFG_OP op) { + return op == SAPFOR::CFG_OP::ADD || op == SAPFOR::CFG_OP::SUBT || + op == SAPFOR::CFG_OP::MULT || op == SAPFOR::CFG_OP::DIV || + op == SAPFOR::CFG_OP::POW || + op == SAPFOR::CFG_OP::GE || op == SAPFOR::CFG_OP::LE || + op == SAPFOR::CFG_OP::GT || op == SAPFOR::CFG_OP::LT || + op == SAPFOR::CFG_OP::EQ || op == SAPFOR::CFG_OP::NEQV || + op == SAPFOR::CFG_OP::EQV || op == SAPFOR::CFG_OP::EMPTY || + op == SAPFOR::CFG_OP::OR || op == SAPFOR::CFG_OP::AND; + }; + + auto isUnaryOp = [](SAPFOR::CFG_OP op) { + return op == SAPFOR::CFG_OP::UN_ADD || op == SAPFOR::CFG_OP::UN_MINUS || + op == SAPFOR::CFG_OP::NOT || op == SAPFOR::CFG_OP::ASSIGN; + }; + + while (!workStack.empty()) { + auto variable = workStack.top(); + workStack.pop(); + if (!variable || visited.count(variable)) + continue; + + visited.insert(variable); + + for (auto block : blocks) { + for (auto instrWrapper : block->getInstructions()) { + auto instr = instrWrapper->getInstruction(); + if (!instr || instr->getResult() != variable) + continue; + + auto op = instr->getOperation(); + auto arg1 = instr->getArg1(); + auto arg2 = instr->getArg2(); + + if (isBinaryOp(op) && arg1 && arg2) { + if (arg1->getType() == SAPFOR::CFG_ARG_TYPE::VAR) + result.insert(arg1); + else if (arg1->getType() == SAPFOR::CFG_ARG_TYPE::REG) + workStack.push(arg1); + + if (arg2->getType() == SAPFOR::CFG_ARG_TYPE::VAR) + result.insert(arg2); + else if (arg2->getType() == SAPFOR::CFG_ARG_TYPE::REG) + workStack.push(arg2); + } + else if (isUnaryOp(op) && arg1) { + if (arg1->getType() == SAPFOR::CFG_ARG_TYPE::VAR) + result.insert(arg1); + else if (arg1->getType() == SAPFOR::CFG_ARG_TYPE::REG) + workStack.push(arg1); + } + } + } + } + + return result; +} + +std::vector getPhiArguments(SAPFOR::BasicBlock* block, SAPFOR::Instruction* phiInstr) { + std::vector result; + + auto& instructions = block->getInstructions(); + bool collecting = false; + for (int i = instructions.size() - 1; i >= 0; --i) { + auto instr = instructions[i]->getInstruction(); + + if (collecting) { + if (instr->getOperation() == SAPFOR::CFG_OP::PARAM) { + auto arg = instr->getArg1(); + if (arg) { + result.push_back(instr); + } + } + else { + break; + } + } + + if (!instr) continue; + + if (instr == phiInstr) { + collecting = true; + continue; + } + } + + std::reverse(result.begin(), result.end()); + return result; +} + +SAPFOR::BasicBlock* findInstructionBlock(SAPFOR::Instruction* targetInstr, const std::vector& blocks) { + for (auto block : blocks) { + for (auto instrWrapper : block->getInstructions()) { + auto instr = instrWrapper->getInstruction(); + if (instr == targetInstr) { + return block; + } + } + } + return nullptr; +} + +SAPFOR::BasicBlock* findInstructionBlockByNumber(int number, const std::vector& blocks) { + for (auto block : blocks) { + for (auto instrWrapper : block->getInstructions()) { + auto instr = instrWrapper->getInstruction(); + if (instr->getNumber() == number) { + return block; + } + } + } + return nullptr; +} + + +void findInductiveVars(const std::vector& blocks, const std::vector& Loopblocks, SAPFOR::BasicBlock* loopHeader, const set& loopExits) { + set inductiveVars; + set relevantBlocks = { loopHeader }; + + for (auto block : relevantBlocks) { + + for (auto instrWrapper : block->getInstructions()) { + auto instr = instrWrapper->getInstruction(); + if (!instr) continue; + + auto op = instr->getOperation(); + auto res = instr->getResult(); + auto arg1 = instr->getArg1(); + auto arg2 = instr->getArg2(); + + if (op == SAPFOR::CFG_OP::JUMP_IF) { + if (arg1 && arg1->getType() == SAPFOR::CFG_ARG_TYPE::VAR) { + inductiveVars.insert(arg1->getValue()); + } + if (arg1 && arg1->getType() == SAPFOR::CFG_ARG_TYPE::REG) { + auto foundVariables = findRegisterSourceVariables(blocks, arg1); + for (auto var : foundVariables) { + inductiveVars.insert(var->getValue()); + } + } + } + } + } + + set finalInductiveVars; + + for (auto instrWrapper : loopHeader->getInstructions()) { + auto instr = instrWrapper->getInstruction(); + if (!instr || instr->getOperation() != SAPFOR::CFG_OP::F_CALL || !instr->getArg1() || instr->getArg1()->getValue() != "FI_FUNCTION") continue; + + auto phiRes = instr->getResult(); + if (!phiRes || !inductiveVars.count(phiRes->getValue())) continue; + + auto currentBlock = findInstructionBlock(instr, blocks); + if (!currentBlock) continue; + + auto phiArgs = getPhiArguments(currentBlock, instr); + + bool hasInLoopDefinition = false; + + for (const auto& argInstr : phiArgs) { + if (!argInstr) continue; + + int definitionInstrNumber = stoi(argInstr->getArg1()->getValue()); + if (definitionInstrNumber == -1) continue; + + auto phiBlock = findInstructionBlockByNumber(definitionInstrNumber, blocks); + if (!phiBlock) continue; + + if (std::find(Loopblocks.begin(), Loopblocks.end(), phiBlock) != Loopblocks.end()) { + hasInLoopDefinition = true; + } + } + + if (hasInLoopDefinition) { + finalInductiveVars.insert(phiRes->getValue()); + } + } + + for (auto i : finalInductiveVars) { + std::cout << "Confirmed inductive variable: " << i << std::endl; + } + + if (finalInductiveVars.empty()) { + std::cout << "No confirmed inductive variables found." << std::endl; + } +} + +SAPFOR::Instruction* findInstructionAfterLoop(const std::vector& loopBody) { + set loopSet(loopBody.begin(), loopBody.end()); + + for (auto block : loopBody) { + for (auto succ : block->getNext()) { + if (!loopSet.count(succ)) { + // + auto instructions = succ->getInstructions(); + for (auto wrapper : instructions) { + if (auto instr = wrapper->getInstruction()) { + return instr; + } + } + } + } + } + + return nullptr; // +} + +bool isEqual(const char* cstr, const std::string& str) { + return str == cstr; +} + +void findImplicitLoops(const map>& fullIR_SSA, const char* fileName) +{ + for (auto& i : fullIR_SSA) + { + //for (auto j : i.second) + // printblock(j); + + if (!isEqual(fileName, i.first->fileName)) + continue; + + map visited; + for (auto i : i.second) + visited[i->getNumber()] = UNVISITED; + + //vector visited(i.second.size(), UNVISITED); + vector> startAndEnd; + dfs(i.second[0], visited, startAndEnd, NULL); + + vector loops; + + for (auto& [tail, header] : startAndEnd) { + set loopExits; + + for (auto succ : tail->getNext()) { + if (succ != header) { + loopExits.insert(succ); + } + } + + vector loopBody; + getLoopBody(header, loopExits, loopBody); + + cout << "LOOP DETECTED:" << endl; + cout << " Header: " << header->getNumber() << endl; + cout << " Tail: " << tail->getNumber() << endl; + cout << " Body blocks: "; + for (auto block : loopBody) { + cout << block->getNumber() << " "; + } + cout << endl; + + findInductiveVars(i.second, loopBody, header, loopExits); + + + SAPFOR::Instruction* instructionAfterLoop = findInstructionAfterLoop(loopBody); + + if (instructionAfterLoop == NULL) { + cout << "Warning: instruction after loop not found!" << endl; + continue; + } + + auto firstInstruction = header->getInstructions()[0]->getInstruction(); + auto lastInstruction = tail->getInstructions().back()->getInstruction(); + + cout << "first - " << firstInstruction->getNumber() << " last - " << lastInstruction->getNumber() << " after - " << instructionAfterLoop->getNumber() << endl; + auto x = firstInstruction->getOperator(); + + auto tmpLoop = new LoopGraph(); + tmpLoop->isFor = true; + tmpLoop->lineNum = firstInstruction->getOperator()->lineNumber(); + tmpLoop->lineNumAfterLoop = instructionAfterLoop->getOperator()->lineNumber(); + + if (firstInstruction->getOperator()->variant() == FOR_NODE) { + SgForStmt* stmt = isSgForStmt(firstInstruction->getOperator()); + + cout << "for loop" << endl;// << stmt->sunparse() << endl; + } + else if (firstInstruction->getOperator()->variant() == WHILE_NODE) { + SgWhileStmt* stmt = isSgWhileStmt(firstInstruction->getOperator()); + + cout << (stmt->conditional() == NULL ? "infinit" : "") << "while loop" << endl;//<< stmt->sunparse() << endl; + } + else if (firstInstruction->getOperator()->variant() == DO_WHILE_NODE) { + SgWhileStmt* stmt = isSgDoWhileStmt(firstInstruction->getOperator()); + + cout << "do while loop" << endl;// << stmt->sunparse() << endl; + } + else if (firstInstruction->getOperator()->variant() == LOOP_NODE) { + cout << "not known loop" << endl;// << firstInstruction->getOperator()->sunparse() << endl; + } + else { + + cout << "goto loop" << endl;// firstInstruction->getOperator()->sunparse() << endl; + } + + cout << "loop start line " << tmpLoop->lineNum << endl; + cout << "after loop line " << tmpLoop->lineNumAfterLoop << endl << endl; + + loops.push_back(tmpLoop); + } + } +} diff --git a/src/LoopAnalyzer/implicit_loops_analyzer.h b/src/LoopAnalyzer/implicit_loops_analyzer.h new file mode 100644 index 0000000..3ed59e2 --- /dev/null +++ b/src/LoopAnalyzer/implicit_loops_analyzer.h @@ -0,0 +1,7 @@ +#pragma once + +#include +#include "../CFGraph/CFGraph.h" +#include "../GraphCall/graph_calls.h" + +void findImplicitLoops(const std::map>& fullIR_SSA, const char* fileName); \ No newline at end of file diff --git a/src/PrivateAnalyzer/private_arrays_search.cpp b/src/PrivateAnalyzer/private_arrays_search.cpp index 985baf6..767ebfb 100644 --- a/src/PrivateAnalyzer/private_arrays_search.cpp +++ b/src/PrivateAnalyzer/private_arrays_search.cpp @@ -121,7 +121,7 @@ static void SolveDataFlow(Region* DFG) Collapse(DFG); } -map FindPrivateArrays(map> &loopGraph, map>& FullIR) +map findPrivateArrays(map> &loopGraph, map>& FullIR) { map result; for (const auto& [loopName, loops] : loopGraph) diff --git a/src/PrivateAnalyzer/private_arrays_search.h b/src/PrivateAnalyzer/private_arrays_search.h index 2faaa27..220ac79 100644 --- a/src/PrivateAnalyzer/private_arrays_search.h +++ b/src/PrivateAnalyzer/private_arrays_search.h @@ -10,5 +10,5 @@ #include "../CFGraph/CFGraph.h" void Collapse(Region* region); -std::map FindPrivateArrays(std::map>& loopGraph, std::map>& FullIR); +std::map findPrivateArrays(std::map>& loopGraph, std::map>& FullIR); std::pair> GetBasicBlocksForLoop(const LoopGraph* loop, const std::vector blocks); diff --git a/src/Sapfor.cpp b/src/Sapfor.cpp index 86d66ee..61d190b 100644 --- a/src/Sapfor.cpp +++ b/src/Sapfor.cpp @@ -42,6 +42,7 @@ #include "ProjectManipulation/ConvertFiles.h" #include "LoopAnalyzer/loop_analyzer.h" +#include "LoopAnalyzer/implicit_loops_analyzer.h" #include "GraphCall/graph_calls_func.h" #include "GraphLoop/graph_loops_func.h" @@ -95,7 +96,7 @@ #include "CFGraph/IR.h" #include "CFGraph/RD_subst.h" #include "CFGraph/CFGraph.h" -#include "CFGraph/IRSSAForm.h" +#include "CFGraph/IR_SSAForm.h" #include "CFGraph/live_variable_analysis.h" #include "CFGraph/private_variables_analysis.h" @@ -1032,13 +1033,13 @@ static bool runAnalysis(SgProject &project, const int curr_regime, const bool ne } else if (curr_regime == BUILD_IR_SSA_FORM) { - if (ssaFormIR.size() == 0) - buildIRSSAForm(fullIR, &ssaFormIR); + if (fullIR_SSA.size() == 0) + buildIRSSAForm(fullIR, &fullIR_SSA); } - else if (curr_regime == EXPLORE_IR_LOOPS) - exploreLoops(&ssaFormIR, file_name); + else if (curr_regime == FIND_IMPLICIT_LOOPS) + findImplicitLoops(fullIR_SSA, file_name); else if (curr_regime == FIND_PRIVATE_ARRAYS) - FindPrivateArrays(loopGraph, fullIR); + findPrivateArrays(loopGraph, fullIR); else if (curr_regime == TEST_PASS) { //test pass diff --git a/src/Sapfor.h b/src/Sapfor.h index 188921a..c5dc4ca 100644 --- a/src/Sapfor.h +++ b/src/Sapfor.h @@ -182,7 +182,7 @@ enum passes { SET_IMPLICIT_NONE, RENAME_INLCUDES, - EXPLORE_IR_LOOPS, + FIND_IMPLICIT_LOOPS, BUILD_IR_SSA_FORM, FIND_PRIVATE_ARRAYS, @@ -371,7 +371,7 @@ static void setPassValues() passNames[SET_IMPLICIT_NONE] = "SET_IMPLICIT_NONE"; passNames[RENAME_INLCUDES] = "RENAME_INLCUDES"; passNames[INSERT_NO_DISTR_FLAGS_FROM_GUI] = "INSERT_NO_DISTR_FLAGS_FROM_GUI"; - passNames[EXPLORE_IR_LOOPS] = "EXPLORE_IR_LOOPS"; + passNames[FIND_IMPLICIT_LOOPS] = "FIND_IMPLICIT_LOOPS"; passNames[BUILD_IR_SSA_FORM] = "BUILD_IR_SSA_FORM"; passNames[FIND_PRIVATE_ARRAYS] = "FIND_PRIVATE_ARRAYS"; diff --git a/src/SapforData.h b/src/SapforData.h index 484e85a..94944ce 100644 --- a/src/SapforData.h +++ b/src/SapforData.h @@ -181,8 +181,6 @@ bool passNamesWasInit = false; std::map> sgStats; std::map> sgExprs; -//for EXPLORE_IR_LOOPS and BUILD_IR_SSA_FORM -map> ssaFormIR; +//for FIND_IMPLICIT_LOOPS and BUILD_IR_SSA_FORM +map> fullIR_SSA; // - -int test = 0; \ No newline at end of file diff --git a/src/Utils/PassManager.h b/src/Utils/PassManager.h index b0fe453..9d1c5fc 100644 --- a/src/Utils/PassManager.h +++ b/src/Utils/PassManager.h @@ -316,9 +316,9 @@ void InitPassesDependencies(map> &passDepsIn, set list({ VERIFY_INCLUDES, CORRECT_VAR_DECL }) <= Pass(SET_IMPLICIT_NONE); - list({ CALL_GRAPH, LOOP_GRAPH, CALL_GRAPH2 }) <= Pass(BUILD_IR_SSA_FORM) <= Pass(EXPLORE_IR_LOOPS); + list({ CALL_GRAPH, LOOP_GRAPH, CALL_GRAPH2, BUILD_IR }) <= Pass(BUILD_IR_SSA_FORM) <= Pass(FIND_IMPLICIT_LOOPS); - list({ CALL_GRAPH2, CALL_GRAPH, BUILD_IR, LOOP_GRAPH, LOOP_ANALYZER_DATA_DIST_S2 }) <= Pass(FIND_PRIVATE_ARRAYS); + list({ CALL_GRAPH, LOOP_GRAPH, CALL_GRAPH2, BUILD_IR, LOOP_ANALYZER_DATA_DIST_S2 }) <= Pass(FIND_PRIVATE_ARRAYS); passesIgnoreStateDone.insert({ CREATE_PARALLEL_DIRS, INSERT_PARALLEL_DIRS, INSERT_SHADOW_DIRS, EXTRACT_PARALLEL_DIRS, EXTRACT_SHADOW_DIRS, CREATE_REMOTES, UNPARSE_FILE, REMOVE_AND_CALC_SHADOW,